Skip to content

Commit

Permalink
Support optional precision for CLOB and BLOB (#639)
Browse files Browse the repository at this point in the history
* 638 Adjusting CLOB and BLOB with optional precision

* 638 Adding integration tests to increase coverage

* 638 Adjusting BLOB test
  • Loading branch information
AugustoFKL committed Oct 1, 2022
1 parent 300e28b commit fb5a974
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 10 deletions.
18 changes: 12 additions & 6 deletions src/ast/data_type.rs
Expand Up @@ -33,8 +33,11 @@ pub enum DataType {
Nvarchar(Option<u64>),
/// Uuid type
Uuid,
/// Large character object e.g. CLOB(1000)
Clob(u64),
/// Large character object with optional length e.g. CLOB, CLOB(1000), [standard], [Oracle]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type
/// [Oracle]: https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html
Clob(Option<u64>),
/// Fixed-length binary type with optional length e.g. [standard], [MS SQL Server]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
Expand All @@ -45,8 +48,11 @@ pub enum DataType {
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
/// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16
Varbinary(Option<u64>),
/// Large binary object e.g. BLOB(1000)
Blob(u64),
/// Large binary object with optional length e.g. BLOB, BLOB(1000), [standard], [Oracle]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-large-object-string-type
/// [Oracle]: https://docs.oracle.com/javadb/10.8.3.0/ref/rrefblob.html
Blob(Option<u64>),
/// Decimal type with optional precision and scale e.g. DECIMAL(10,2)
Decimal(Option<u64>, Option<u64>),
/// Floating point with optional precision e.g. FLOAT(8)
Expand Down Expand Up @@ -131,12 +137,12 @@ impl fmt::Display for DataType {
format_type_with_optional_length(f, "NVARCHAR", size, false)
}
DataType::Uuid => write!(f, "UUID"),
DataType::Clob(size) => write!(f, "CLOB({})", size),
DataType::Clob(size) => format_type_with_optional_length(f, "CLOB", size, false),
DataType::Binary(size) => format_type_with_optional_length(f, "BINARY", size, false),
DataType::Varbinary(size) => {
format_type_with_optional_length(f, "VARBINARY", size, false)
}
DataType::Blob(size) => write!(f, "BLOB({})", size),
DataType::Blob(size) => format_type_with_optional_length(f, "BLOB", size, false),
DataType::Decimal(precision, scale) => {
if let Some(scale) = scale {
write!(f, "NUMERIC({},{})", precision.unwrap(), scale)
Expand Down
8 changes: 6 additions & 2 deletions src/parser.rs
Expand Up @@ -3403,10 +3403,10 @@ impl<'a> Parser<'a> {
Ok(DataType::Char(self.parse_optional_precision()?))
}
}
Keyword::CLOB => Ok(DataType::Clob(self.parse_precision()?)),
Keyword::CLOB => Ok(DataType::Clob(self.parse_optional_precision()?)),
Keyword::BINARY => Ok(DataType::Binary(self.parse_optional_precision()?)),
Keyword::VARBINARY => Ok(DataType::Varbinary(self.parse_optional_precision()?)),
Keyword::BLOB => Ok(DataType::Blob(self.parse_precision()?)),
Keyword::BLOB => Ok(DataType::Blob(self.parse_optional_precision()?)),
Keyword::UUID => Ok(DataType::Uuid),
Keyword::DATE => Ok(DataType::Date),
Keyword::DATETIME => Ok(DataType::Datetime),
Expand Down Expand Up @@ -5258,6 +5258,10 @@ mod tests {
// TODO add tests for all data types? https://github.com/sqlparser-rs/sqlparser-rs/issues/2
#[test]
fn test_parse_data_type() {
test_parse_data_type("BLOB", "BLOB");
test_parse_data_type("BLOB(50)", "BLOB(50)");
test_parse_data_type("CLOB", "CLOB");
test_parse_data_type("CLOB(50)", "CLOB(50)");
test_parse_data_type("DOUBLE PRECISION", "DOUBLE PRECISION");
test_parse_data_type("DOUBLE", "DOUBLE");
test_parse_data_type("VARBINARY", "VARBINARY");
Expand Down
24 changes: 22 additions & 2 deletions tests/sqlparser_common.rs
Expand Up @@ -1655,12 +1655,22 @@ fn parse_cast() {
expr_from_projection(only(&select.projection))
);

let sql = "SELECT CAST(id AS CLOB) FROM customer";
let select = verified_only_select(sql);
assert_eq!(
&Expr::Cast {
expr: Box::new(Expr::Identifier(Ident::new("id"))),
data_type: DataType::Clob(None)
},
expr_from_projection(only(&select.projection))
);

let sql = "SELECT CAST(id AS CLOB(50)) FROM customer";
let select = verified_only_select(sql);
assert_eq!(
&Expr::Cast {
expr: Box::new(Expr::Identifier(Ident::new("id"))),
data_type: DataType::Clob(50)
data_type: DataType::Clob(Some(50))
},
expr_from_projection(only(&select.projection))
);
Expand All @@ -1685,12 +1695,22 @@ fn parse_cast() {
expr_from_projection(only(&select.projection))
);

let sql = "SELECT CAST(id AS BLOB) FROM customer";
let select = verified_only_select(sql);
assert_eq!(
&Expr::Cast {
expr: Box::new(Expr::Identifier(Ident::new("id"))),
data_type: DataType::Blob(None)
},
expr_from_projection(only(&select.projection))
);

let sql = "SELECT CAST(id AS BLOB(50)) FROM customer";
let select = verified_only_select(sql);
assert_eq!(
&Expr::Cast {
expr: Box::new(Expr::Identifier(Ident::new("id"))),
data_type: DataType::Blob(50)
data_type: DataType::Blob(Some(50))
},
expr_from_projection(only(&select.projection))
);
Expand Down

0 comments on commit fb5a974

Please sign in to comment.