From fd65e617255160d2c0705b3c0deabff83ea34962 Mon Sep 17 00:00:00 2001 From: Rasmus Jonsson Date: Fri, 3 Dec 2021 00:14:18 +0300 Subject: [PATCH 1/5] Support parsing VARBINARY, BINARY, BLOB, CLOB * add parser support for already-defined data types * add required precision parameter function --- src/parser.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 45b3bea0e1..53dc48184c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2090,6 +2090,10 @@ impl<'a> Parser<'a> { let (precision, scale) = self.parse_optional_precision_scale()?; Ok(DataType::Decimal(precision, scale)) } + Keyword::BINARY => Ok(DataType::Binary(self.parse_required_precision()?)), + Keyword::VARBINARY => Ok(DataType::Binary(self.parse_required_precision()?)), + Keyword::CLOB => Ok(DataType::Clob(self.parse_required_precision()?)), + Keyword::BLOB => Ok(DataType::Blob(self.parse_required_precision()?)), _ => { self.prev_token(); let type_name = self.parse_object_name()?; @@ -2218,6 +2222,18 @@ impl<'a> Parser<'a> { } } + pub fn parse_required_precision(&mut self) -> Result { + if self.consume_token(&Token::LParen) { + let n = self.parse_literal_uint()?; + self.expect_token(&Token::RParen)?; + Ok(n) + } else { + Err(ParserError::ParserError( + "expected precision data type {}".to_string(), + )) + } + } + pub fn parse_optional_precision_scale( &mut self, ) -> Result<(Option, Option), ParserError> { From e84ca2251ac336e0168dddbed64ab7b5f15daa8f Mon Sep 17 00:00:00 2001 From: Rasmus Jonsson Date: Fri, 3 Dec 2021 00:56:41 +0300 Subject: [PATCH 2/5] BINARY precision is optional Reference: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html ::= BINARY [ ] | (...) --- src/ast/data_type.rs | 7 +++++-- src/parser.rs | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index 96071c2280..3e5a7b62c9 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -32,7 +32,7 @@ pub enum DataType { /// Large character object e.g. CLOB(1000) Clob(u64), /// Fixed-length binary type e.g. BINARY(10) - Binary(u64), + Binary(Option), /// Variable-length binary type e.g. VARBINARY(10) Varbinary(u64), /// Large binary object e.g. BLOB(1000) @@ -86,7 +86,10 @@ impl fmt::Display for DataType { } DataType::Uuid => write!(f, "UUID"), DataType::Clob(size) => write!(f, "CLOB({})", size), - DataType::Binary(size) => write!(f, "BINARY({})", size), + DataType::Binary(size) => match size { + None => write!(f, "BINARY"), + Some(s) => write!(f, "BINARY({})", s) + }, DataType::Varbinary(size) => write!(f, "VARBINARY({})", size), DataType::Blob(size) => write!(f, "BLOB({})", size), DataType::Decimal(precision, scale) => { diff --git a/src/parser.rs b/src/parser.rs index 53dc48184c..7ce4548f70 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2090,8 +2090,8 @@ impl<'a> Parser<'a> { let (precision, scale) = self.parse_optional_precision_scale()?; Ok(DataType::Decimal(precision, scale)) } - Keyword::BINARY => Ok(DataType::Binary(self.parse_required_precision()?)), - Keyword::VARBINARY => Ok(DataType::Binary(self.parse_required_precision()?)), + Keyword::BINARY => Ok(DataType::Binary(self.parse_optional_precision()?)), + Keyword::VARBINARY => Ok(DataType::Varbinary(self.parse_required_precision()?)), Keyword::CLOB => Ok(DataType::Clob(self.parse_required_precision()?)), Keyword::BLOB => Ok(DataType::Blob(self.parse_required_precision()?)), _ => { @@ -2229,7 +2229,7 @@ impl<'a> Parser<'a> { Ok(n) } else { Err(ParserError::ParserError( - "expected precision data type {}".to_string(), + "expected precision data type".to_string(), )) } } From ce22800c19cd814243c0447b2d51fead21ef4e84 Mon Sep 17 00:00:00 2001 From: Rasmus Jonsson Date: Fri, 3 Dec 2021 15:51:11 +0300 Subject: [PATCH 3/5] Support BIT data type Reference: https://jakewheat.github.io/sql-overview/sql-1999-grammar.html ::= BIT [ ] | (...) Supported in at least MySQL version 8 https://dev.mysql.com/doc/refman/8.0/en/bit-type.html --- src/ast/data_type.rs | 6 ++++++ src/keywords.rs | 1 + src/parser.rs | 1 + 3 files changed, 8 insertions(+) diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index 3e5a7b62c9..bd5364e8c7 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -75,6 +75,8 @@ pub enum DataType { Custom(ObjectName), /// Arrays Array(Box), + /// Bitfield + Bit(Option), } impl fmt::Display for DataType { @@ -118,6 +120,10 @@ impl fmt::Display for DataType { DataType::String => write!(f, "STRING"), DataType::Bytea => write!(f, "BYTEA"), DataType::Array(ty) => write!(f, "{}[]", ty), + DataType::Bit(size) => match size { + None => write!(f, "BIT"), + Some(s) => write!(f, "BIT({})", s) + }, DataType::Custom(ty) => write!(f, "{}", ty), } } diff --git a/src/keywords.rs b/src/keywords.rs index 8f73836c41..5590bc31f0 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -98,6 +98,7 @@ define_keywords!( BETWEEN, BIGINT, BINARY, + BIT, BLOB, BOOLEAN, BOTH, diff --git a/src/parser.rs b/src/parser.rs index 7ce4548f70..665d508ef8 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2094,6 +2094,7 @@ impl<'a> Parser<'a> { Keyword::VARBINARY => Ok(DataType::Varbinary(self.parse_required_precision()?)), Keyword::CLOB => Ok(DataType::Clob(self.parse_required_precision()?)), Keyword::BLOB => Ok(DataType::Blob(self.parse_required_precision()?)), + Keyword::BIT => Ok(DataType::Bit(self.parse_optional_precision()?)), _ => { self.prev_token(); let type_name = self.parse_object_name()?; From f7b133ae76b468f2fff304a7ce98fe1f76068b93 Mon Sep 17 00:00:00 2001 From: rptr Date: Wed, 19 Jan 2022 14:30:32 +0300 Subject: [PATCH 4/5] Parse JSON type --- src/ast/data_type.rs | 2 ++ src/keywords.rs | 1 + src/parser.rs | 1 + 3 files changed, 4 insertions(+) diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index bd5364e8c7..e0f36646a7 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -77,6 +77,7 @@ pub enum DataType { Array(Box), /// Bitfield Bit(Option), + Json, } impl fmt::Display for DataType { @@ -125,6 +126,7 @@ impl fmt::Display for DataType { Some(s) => write!(f, "BIT({})", s) }, DataType::Custom(ty) => write!(f, "{}", ty), + DataType::Json => write!(f, "JSON"), } } } diff --git a/src/keywords.rs b/src/keywords.rs index 5590bc31f0..b64d429977 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -255,6 +255,7 @@ define_keywords!( IS, ISOLATION, JOIN, + JSON, JSONFILE, KEY, LAG, diff --git a/src/parser.rs b/src/parser.rs index 665d508ef8..4864f324b0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2095,6 +2095,7 @@ impl<'a> Parser<'a> { Keyword::CLOB => Ok(DataType::Clob(self.parse_required_precision()?)), Keyword::BLOB => Ok(DataType::Blob(self.parse_required_precision()?)), Keyword::BIT => Ok(DataType::Bit(self.parse_optional_precision()?)), + Keyword::JSON => Ok(DataType::Json), _ => { self.prev_token(); let type_name = self.parse_object_name()?; From a7de3c84dea4f86d05a56ed3ca03559e14e2013c Mon Sep 17 00:00:00 2001 From: rptr Date: Thu, 20 Jan 2022 09:17:29 +0300 Subject: [PATCH 5/5] JSON operators --- src/ast/operator.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ast/operator.rs b/src/ast/operator.rs index 244ea517c1..f1759b2e91 100644 --- a/src/ast/operator.rs +++ b/src/ast/operator.rs @@ -86,6 +86,8 @@ pub enum BinaryOperator { PGRegexIMatch, PGRegexNotMatch, PGRegexNotIMatch, + JsonColumnPath, + JsonInlinePath, } impl fmt::Display for BinaryOperator { @@ -121,6 +123,8 @@ impl fmt::Display for BinaryOperator { BinaryOperator::PGRegexIMatch => "~*", BinaryOperator::PGRegexNotMatch => "!~", BinaryOperator::PGRegexNotIMatch => "!~*", + BinaryOperator::JsonColumnPath => "->", + BinaryOperator::JsonInlinePath => "->>", }) } }