Skip to content

Commit fb5a974

Browse files
authored
Support optional precision for CLOB and BLOB (#639)
* 638 Adjusting CLOB and BLOB with optional precision * 638 Adding integration tests to increase coverage * 638 Adjusting BLOB test
1 parent 300e28b commit fb5a974

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

src/ast/data_type.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ pub enum DataType {
3333
Nvarchar(Option<u64>),
3434
/// Uuid type
3535
Uuid,
36-
/// Large character object e.g. CLOB(1000)
37-
Clob(u64),
36+
/// Large character object with optional length e.g. CLOB, CLOB(1000), [standard], [Oracle]
37+
///
38+
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type
39+
/// [Oracle]: https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html
40+
Clob(Option<u64>),
3841
/// Fixed-length binary type with optional length e.g. [standard], [MS SQL Server]
3942
///
4043
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
@@ -45,8 +48,11 @@ pub enum DataType {
4548
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
4649
/// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16
4750
Varbinary(Option<u64>),
48-
/// Large binary object e.g. BLOB(1000)
49-
Blob(u64),
51+
/// Large binary object with optional length e.g. BLOB, BLOB(1000), [standard], [Oracle]
52+
///
53+
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-large-object-string-type
54+
/// [Oracle]: https://docs.oracle.com/javadb/10.8.3.0/ref/rrefblob.html
55+
Blob(Option<u64>),
5056
/// Decimal type with optional precision and scale e.g. DECIMAL(10,2)
5157
Decimal(Option<u64>, Option<u64>),
5258
/// Floating point with optional precision e.g. FLOAT(8)
@@ -131,12 +137,12 @@ impl fmt::Display for DataType {
131137
format_type_with_optional_length(f, "NVARCHAR", size, false)
132138
}
133139
DataType::Uuid => write!(f, "UUID"),
134-
DataType::Clob(size) => write!(f, "CLOB({})", size),
140+
DataType::Clob(size) => format_type_with_optional_length(f, "CLOB", size, false),
135141
DataType::Binary(size) => format_type_with_optional_length(f, "BINARY", size, false),
136142
DataType::Varbinary(size) => {
137143
format_type_with_optional_length(f, "VARBINARY", size, false)
138144
}
139-
DataType::Blob(size) => write!(f, "BLOB({})", size),
145+
DataType::Blob(size) => format_type_with_optional_length(f, "BLOB", size, false),
140146
DataType::Decimal(precision, scale) => {
141147
if let Some(scale) = scale {
142148
write!(f, "NUMERIC({},{})", precision.unwrap(), scale)

src/parser.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -3403,10 +3403,10 @@ impl<'a> Parser<'a> {
34033403
Ok(DataType::Char(self.parse_optional_precision()?))
34043404
}
34053405
}
3406-
Keyword::CLOB => Ok(DataType::Clob(self.parse_precision()?)),
3406+
Keyword::CLOB => Ok(DataType::Clob(self.parse_optional_precision()?)),
34073407
Keyword::BINARY => Ok(DataType::Binary(self.parse_optional_precision()?)),
34083408
Keyword::VARBINARY => Ok(DataType::Varbinary(self.parse_optional_precision()?)),
3409-
Keyword::BLOB => Ok(DataType::Blob(self.parse_precision()?)),
3409+
Keyword::BLOB => Ok(DataType::Blob(self.parse_optional_precision()?)),
34103410
Keyword::UUID => Ok(DataType::Uuid),
34113411
Keyword::DATE => Ok(DataType::Date),
34123412
Keyword::DATETIME => Ok(DataType::Datetime),
@@ -5258,6 +5258,10 @@ mod tests {
52585258
// TODO add tests for all data types? https://github.com/sqlparser-rs/sqlparser-rs/issues/2
52595259
#[test]
52605260
fn test_parse_data_type() {
5261+
test_parse_data_type("BLOB", "BLOB");
5262+
test_parse_data_type("BLOB(50)", "BLOB(50)");
5263+
test_parse_data_type("CLOB", "CLOB");
5264+
test_parse_data_type("CLOB(50)", "CLOB(50)");
52615265
test_parse_data_type("DOUBLE PRECISION", "DOUBLE PRECISION");
52625266
test_parse_data_type("DOUBLE", "DOUBLE");
52635267
test_parse_data_type("VARBINARY", "VARBINARY");

tests/sqlparser_common.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -1655,12 +1655,22 @@ fn parse_cast() {
16551655
expr_from_projection(only(&select.projection))
16561656
);
16571657

1658+
let sql = "SELECT CAST(id AS CLOB) FROM customer";
1659+
let select = verified_only_select(sql);
1660+
assert_eq!(
1661+
&Expr::Cast {
1662+
expr: Box::new(Expr::Identifier(Ident::new("id"))),
1663+
data_type: DataType::Clob(None)
1664+
},
1665+
expr_from_projection(only(&select.projection))
1666+
);
1667+
16581668
let sql = "SELECT CAST(id AS CLOB(50)) FROM customer";
16591669
let select = verified_only_select(sql);
16601670
assert_eq!(
16611671
&Expr::Cast {
16621672
expr: Box::new(Expr::Identifier(Ident::new("id"))),
1663-
data_type: DataType::Clob(50)
1673+
data_type: DataType::Clob(Some(50))
16641674
},
16651675
expr_from_projection(only(&select.projection))
16661676
);
@@ -1685,12 +1695,22 @@ fn parse_cast() {
16851695
expr_from_projection(only(&select.projection))
16861696
);
16871697

1698+
let sql = "SELECT CAST(id AS BLOB) FROM customer";
1699+
let select = verified_only_select(sql);
1700+
assert_eq!(
1701+
&Expr::Cast {
1702+
expr: Box::new(Expr::Identifier(Ident::new("id"))),
1703+
data_type: DataType::Blob(None)
1704+
},
1705+
expr_from_projection(only(&select.projection))
1706+
);
1707+
16881708
let sql = "SELECT CAST(id AS BLOB(50)) FROM customer";
16891709
let select = verified_only_select(sql);
16901710
assert_eq!(
16911711
&Expr::Cast {
16921712
expr: Box::new(Expr::Identifier(Ident::new("id"))),
1693-
data_type: DataType::Blob(50)
1713+
data_type: DataType::Blob(Some(50))
16941714
},
16951715
expr_from_projection(only(&select.projection))
16961716
);

0 commit comments

Comments
 (0)