From 6d4188de53bd60e1d0cfae9c11c3491c214af633 Mon Sep 17 00:00:00 2001 From: Michael Victor Zink Date: Tue, 3 Dec 2024 16:47:12 -0800 Subject: [PATCH] Support BIT column types (#1577) --- src/ast/data_type.rs | 14 ++++++++++++++ src/keywords.rs | 1 + src/parser/mod.rs | 7 +++++++ tests/sqlparser_common.rs | 19 +++++++++++++++++++ 4 files changed, 41 insertions(+) diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index fbfdc2dcf..ccca7f4cb 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -307,6 +307,16 @@ pub enum DataType { FixedString(u64), /// Bytea Bytea, + /// Bit string, e.g. [Postgres], [MySQL], or [MSSQL] + /// + /// [Postgres]: https://www.postgresql.org/docs/current/datatype-bit.html + /// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/bit-type.html + /// [MSSQL]: https://learn.microsoft.com/en-us/sql/t-sql/data-types/bit-transact-sql?view=sql-server-ver16 + Bit(Option), + /// Variable-length bit string e.g. [Postgres] + /// + /// [Postgres]: https://www.postgresql.org/docs/current/datatype-bit.html + BitVarying(Option), /// Custom type such as enums Custom(ObjectName, Vec), /// Arrays @@ -518,6 +528,10 @@ impl fmt::Display for DataType { DataType::LongText => write!(f, "LONGTEXT"), DataType::String(size) => format_type_with_optional_length(f, "STRING", size, false), DataType::Bytea => write!(f, "BYTEA"), + DataType::Bit(size) => format_type_with_optional_length(f, "BIT", size, false), + DataType::BitVarying(size) => { + format_type_with_optional_length(f, "BIT VARYING", size, false) + } DataType::Array(ty) => match ty { ArrayElemTypeDef::None => write!(f, "ARRAY"), ArrayElemTypeDef::SquareBracket(t, None) => write!(f, "{t}[]"), diff --git a/src/keywords.rs b/src/keywords.rs index 4ec088941..e00e26a62 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -126,6 +126,7 @@ define_keywords!( BIGNUMERIC, BINARY, BINDING, + BIT, BLOB, BLOOMFILTER, BOOL, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 90665e9f9..efdf0d6d0 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -8134,6 +8134,13 @@ impl<'a> Parser<'a> { Keyword::MEDIUMBLOB => Ok(DataType::MediumBlob), Keyword::LONGBLOB => Ok(DataType::LongBlob), Keyword::BYTES => Ok(DataType::Bytes(self.parse_optional_precision()?)), + Keyword::BIT => { + if self.parse_keyword(Keyword::VARYING) { + Ok(DataType::BitVarying(self.parse_optional_precision()?)) + } else { + Ok(DataType::Bit(self.parse_optional_precision()?)) + } + } Keyword::UUID => Ok(DataType::Uuid), Keyword::DATE => Ok(DataType::Date), Keyword::DATE32 => Ok(DataType::Date32), diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 4e0cac45b..f146b298e 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -12440,3 +12440,22 @@ fn test_reserved_keywords_for_identifiers() { let sql = "SELECT MAX(interval) FROM tbl"; dialects.parse_sql_statements(sql).unwrap(); } + +#[test] +fn parse_create_table_with_bit_types() { + let sql = "CREATE TABLE t (a BIT, b BIT VARYING, c BIT(42), d BIT VARYING(43))"; + match verified_stmt(sql) { + Statement::CreateTable(CreateTable { columns, .. }) => { + assert_eq!(columns.len(), 4); + assert_eq!(columns[0].data_type, DataType::Bit(None)); + assert_eq!(columns[0].to_string(), "a BIT"); + assert_eq!(columns[1].data_type, DataType::BitVarying(None)); + assert_eq!(columns[1].to_string(), "b BIT VARYING"); + assert_eq!(columns[2].data_type, DataType::Bit(Some(42))); + assert_eq!(columns[2].to_string(), "c BIT(42)"); + assert_eq!(columns[3].data_type, DataType::BitVarying(Some(43))); + assert_eq!(columns[3].to_string(), "d BIT VARYING(43)"); + } + _ => unreachable!(), + } +}