diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index a9af626d3..0f12abb91 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -196,6 +196,10 @@ pub enum DataType { /// /// [clickhouse]: https://clickhouse.com/docs/en/sql-reference/data-types/int-uint Int256, + /// Byte with optional display width e.g. BYTE or BYTE(6) + Byte(Option), + /// Short with optional display width e.g. SHORT or SHORT(9) + Short(Option), /// Integer with optional display width e.g. INTEGER or INTEGER(11) Integer(Option), /// Long with optional display width e.g. LONG or LONG(20) @@ -204,6 +208,10 @@ pub enum DataType { UnsignedInt(Option), /// Unsigned int4 with optional display width e.g. INT4 UNSIGNED or INT4(11) UNSIGNED UnsignedInt4(Option), + /// Unsigned byte with optional display width e.g. BYTE UNSIGNED or BYTE(6) UNSIGNED + UnsignedByte(Option), + /// Unsigned short with optional display width e.g. SHORT UNSIGNED or SHORT(9) UNSIGNED + UnsignedShort(Option), /// Unsigned integer with optional display width e.g. INTEGER UNSIGNED or INTEGER(11) UNSIGNED UnsignedInteger(Option), /// Unsigned long with optional display width e.g. LONG UNSIGNED or LONG(20) UNSIGNED @@ -483,6 +491,18 @@ impl fmt::Display for DataType { DataType::UnsignedInt4(zerofill) => { format_type_with_optional_length(f, "INT4", zerofill, true) } + DataType::Byte(zerofill) => { + format_type_with_optional_length(f, "BYTE", zerofill, false) + } + DataType::UnsignedByte(zerofill) => { + format_type_with_optional_length(f, "BYTE", zerofill, true) + } + DataType::Short(zerofill) => { + format_type_with_optional_length(f, "SHORT", zerofill, false) + } + DataType::UnsignedShort(zerofill) => { + format_type_with_optional_length(f, "SHORT", zerofill, true) + } DataType::Integer(zerofill) => { format_type_with_optional_length(f, "INTEGER", zerofill, false) } diff --git a/src/keywords.rs b/src/keywords.rs index 3284b9f5d..d0e77abfd 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -140,6 +140,7 @@ define_keywords!( BUCKETS, BY, BYPASSRLS, + BYTE, BYTEA, BYTES, CACHE, @@ -717,6 +718,7 @@ define_keywords!( SETS, SETTINGS, SHARE, + SHORT, SHOW, SIMILAR, SKIP, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 815b19f78..a4997a27d 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -8272,6 +8272,22 @@ impl<'a> Parser<'a> { Keyword::INT64 => Ok(DataType::Int64), Keyword::INT128 => Ok(DataType::Int128), Keyword::INT256 => Ok(DataType::Int256), + Keyword::BYTE => { + let optional_precision = self.parse_optional_precision(); + if self.parse_keyword(Keyword::UNSIGNED) { + Ok(DataType::UnsignedByte(optional_precision?)) + } else { + Ok(DataType::Byte(optional_precision?)) + } + } + Keyword::SHORT => { + let optional_precision = self.parse_optional_precision(); + if self.parse_keyword(Keyword::UNSIGNED) { + Ok(DataType::UnsignedShort(optional_precision?)) + } else { + Ok(DataType::Short(optional_precision?)) + } + } Keyword::INTEGER => { let optional_precision = self.parse_optional_precision(); if self.parse_keyword(Keyword::UNSIGNED) { diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 6b7765a2a..6772201df 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -2405,6 +2405,54 @@ fn parse_cast() { expr_from_projection(only(&select.projection)) ); + let sql = "SELECT CAST(id AS BYTE) FROM customer"; + let select = verified_only_select(sql); + assert_eq!( + &Expr::Cast { + kind: CastKind::Cast, + expr: Box::new(Expr::Identifier(Ident::new("id"))), + data_type: DataType::Byte(None), + format: None, + }, + expr_from_projection(only(&select.projection)) + ); + + let sql = "SELECT CAST(id AS BYTE(6)) FROM customer"; + let select = verified_only_select(sql); + assert_eq!( + &Expr::Cast { + kind: CastKind::Cast, + expr: Box::new(Expr::Identifier(Ident::new("id"))), + data_type: DataType::Byte(Some(6)), + format: None, + }, + expr_from_projection(only(&select.projection)) + ); + + let sql = "SELECT CAST(id AS SHORT) FROM customer"; + let select = verified_only_select(sql); + assert_eq!( + &Expr::Cast { + kind: CastKind::Cast, + expr: Box::new(Expr::Identifier(Ident::new("id"))), + data_type: DataType::Short(None), + format: None, + }, + expr_from_projection(only(&select.projection)) + ); + + let sql = "SELECT CAST(id AS SHORT(9)) FROM customer"; + let select = verified_only_select(sql); + assert_eq!( + &Expr::Cast { + kind: CastKind::Cast, + expr: Box::new(Expr::Identifier(Ident::new("id"))), + data_type: DataType::Short(Some(9)), + format: None, + }, + expr_from_projection(only(&select.projection)) + ); + let sql = "SELECT CAST(id AS LONG) FROM customer"; let select = verified_only_select(sql); assert_eq!( @@ -2439,6 +2487,16 @@ fn parse_cast() { "SELECT CAST(id AS BIGINT) FROM customer", ); + one_statement_parses_to( + "SELECT CAST(id AS BYTE(6) UNSIGNED) FROM customer", + "SELECT CAST(id AS BYTE(6) UNSIGNED) FROM customer", + ); + + one_statement_parses_to( + "SELECT CAST(id AS SHORT(9) UNSIGNED) FROM customer", + "SELECT CAST(id AS SHORT(9) UNSIGNED) FROM customer", + ); + one_statement_parses_to( "SELECT CAST(id AS LONG(20) UNSIGNED) FROM customer", "SELECT CAST(id AS LONG(20) UNSIGNED) FROM customer",