From b094aba9d5c2fba78c2d1909d1521bbeef7b4124 Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Tue, 14 Dec 2021 17:08:52 +0200 Subject: [PATCH 1/7] Inital support in current_timestamp --- src/parser.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 45b3bea0e..80c3ff0b5 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -357,6 +357,7 @@ impl<'a> Parser<'a> { self.prev_token(); Ok(Expr::Value(self.parse_value()?)) } + Keyword::CURRENT_TIMESTAMP => self.parse_current_timestamp(ObjectName(vec![w.to_ident()])), Keyword::CASE => self.parse_case_expr(), Keyword::CAST => self.parse_cast_expr(), Keyword::TRY_CAST => self.parse_try_cast_expr(), @@ -508,6 +509,20 @@ impl<'a> Parser<'a> { })) } + pub fn parse_current_timestamp(&mut self, name: ObjectName) -> Result { + let args = if self.consume_token(&Token::LParen) { + self.parse_optional_args()? + } else { + vec![] + }; + Ok(Expr::Function(Function { + name, + args, + over:None, + distinct:false, + })) + } + pub fn parse_window_frame_units(&mut self) -> Result { match self.next_token() { Token::Word(w) => match w.keyword { From d63d415dcebeb5e57e46fd247d8236ab9082af8d Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Wed, 15 Dec 2021 10:05:17 +0200 Subject: [PATCH 2/7] Support time functions --- src/parser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 80c3ff0b5..83daf881c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -357,7 +357,7 @@ impl<'a> Parser<'a> { self.prev_token(); Ok(Expr::Value(self.parse_value()?)) } - Keyword::CURRENT_TIMESTAMP => self.parse_current_timestamp(ObjectName(vec![w.to_ident()])), + Keyword::CURRENT_TIMESTAMP | Keyword::CURRENT_TIME | Keyword::CURRENT_DATE => self.parse_time_functions(ObjectName(vec![w.to_ident()])), Keyword::CASE => self.parse_case_expr(), Keyword::CAST => self.parse_cast_expr(), Keyword::TRY_CAST => self.parse_try_cast_expr(), @@ -509,7 +509,7 @@ impl<'a> Parser<'a> { })) } - pub fn parse_current_timestamp(&mut self, name: ObjectName) -> Result { + pub fn parse_time_functions(&mut self, name: ObjectName) -> Result { let args = if self.consume_token(&Token::LParen) { self.parse_optional_args()? } else { From abae1effb3d830a1bf850309d7eaa687abda4782 Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Wed, 15 Dec 2021 14:27:20 +0200 Subject: [PATCH 3/7] Add Test --- tests/sqlparser_common.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 65b7869d4..947c91761 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -3620,3 +3620,18 @@ fn verified_only_select(query: &str) -> Select { fn verified_expr(query: &str) -> Expr { all_dialects().verified_expr(query) } + +#[test] +fn parse_time_functions() { + let sql = "SELECT CURRENT_TIMESTAMP()"; + let select = verified_only_select(sql); + assert_eq!( + &Expr::Function(Function { + name: ObjectName(vec![Ident::new("CURRENT_TIMESTAMP")]), + args: vec![], + over: None, + distinct: false, + }), + expr_from_projection(&select.projection[0]) + ); +} From 47e06433760a4ab2d675af3e6de2f175018d8b51 Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Sat, 18 Dec 2021 01:11:43 +0200 Subject: [PATCH 4/7] Fix PR --- src/parser.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 83daf881c..46cdf60d6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -357,7 +357,9 @@ impl<'a> Parser<'a> { self.prev_token(); Ok(Expr::Value(self.parse_value()?)) } - Keyword::CURRENT_TIMESTAMP | Keyword::CURRENT_TIME | Keyword::CURRENT_DATE => self.parse_time_functions(ObjectName(vec![w.to_ident()])), + Keyword::CURRENT_TIMESTAMP | Keyword::CURRENT_TIME | Keyword::CURRENT_DATE => { + self.parse_time_functions(ObjectName(vec![w.to_ident()])) + } Keyword::CASE => self.parse_case_expr(), Keyword::CAST => self.parse_cast_expr(), Keyword::TRY_CAST => self.parse_try_cast_expr(), @@ -516,11 +518,11 @@ impl<'a> Parser<'a> { vec![] }; Ok(Expr::Function(Function { - name, - args, - over:None, - distinct:false, - })) + name, + args, + over: None, + distinct: false, + })) } pub fn parse_window_frame_units(&mut self) -> Result { From d9a42f73284918b307fa30aa1963e33b8129059e Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Tue, 21 Dec 2021 16:29:46 +0200 Subject: [PATCH 5/7] Fix tests --- tests/sqlparser_common.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 947c91761..a52fc6cac 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -3634,4 +3634,37 @@ fn parse_time_functions() { }), expr_from_projection(&select.projection[0]) ); + + // Validating Parenthesis + one_statement_parses_to("SELECT CURRENT_TIMESTAMP", sql); + + let sql = "SELECT CURRENT_TIME()"; + let select = verified_only_select(sql); + assert_eq!( + &Expr::Function(Function { + name: ObjectName(vec![Ident::new("CURRENT_TIME")]), + args: vec![], + over: None, + distinct: false, + }), + expr_from_projection(&select.projection[0]) + ); + + // Validating Parenthesis + one_statement_parses_to("SELECT CURRENT_TIME", sql); + + let sql = "SELECT CURRENT_DATE()"; + let select = verified_only_select(sql); + assert_eq!( + &Expr::Function(Function { + name: ObjectName(vec![Ident::new("CURRENT_DATE")]), + args: vec![], + over: None, + distinct: false, + }), + expr_from_projection(&select.projection[0]) + ); + + // Validating Parenthesis + one_statement_parses_to("SELECT CURRENT_DATE", sql); } From 62f09cbfc4484ec2e89a05a53ddcbd54db0a3c5f Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Sun, 26 Dec 2021 12:18:58 +0200 Subject: [PATCH 6/7] Add Support for distinct with parentheses --- src/parser.rs | 11 +++++++++++ tests/sqlparser_common.rs | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 2796577f6..82c0f475f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2648,8 +2648,19 @@ impl<'a> Parser<'a> { None }; + // Not Sure if Top should be cheked here as well. Trino doesn't support TOP. + let is_l_parent = if distinct { + self.consume_token(&Token::LParen) + } else { + false + }; + let projection = self.parse_comma_separated(Parser::parse_select_item)?; + if is_l_parent { + self.consume_token(&Token::RParen); + } + // Note that for keywords to be properly handled here, they need to be // added to `RESERVED_FOR_COLUMN_ALIAS` / `RESERVED_FOR_TABLE_ALIAS`, // otherwise they may be parsed as an alias as part of the `projection` diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index e5b669e2d..5790a5ddc 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -327,6 +327,25 @@ fn parse_select_distinct() { ); } +#[test] +fn parse_select_distinct_two_fields() { + let sql = "SELECT DISTINCT name, id FROM customer"; + let select = verified_only_select(sql); + assert!(select.distinct); + one_statement_parses_to( + "SELECT DISTINCT (name, id) FROM customer", + sql, + ); + assert_eq!( + &SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("name"))), + &select.projection[0] + ); + assert_eq!( + &SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("id"))), + &select.projection[1] + ); +} + #[test] fn parse_select_all() { one_statement_parses_to("SELECT ALL name FROM customer", "SELECT name FROM customer"); From fc9b3180a8b9f96a48d882413776fcfdfe10db2d Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Sun, 26 Dec 2021 12:21:15 +0200 Subject: [PATCH 7/7] Fix nightly --- tests/sqlparser_common.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 5790a5ddc..91f6ae297 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -332,10 +332,7 @@ fn parse_select_distinct_two_fields() { let sql = "SELECT DISTINCT name, id FROM customer"; let select = verified_only_select(sql); assert!(select.distinct); - one_statement_parses_to( - "SELECT DISTINCT (name, id) FROM customer", - sql, - ); + one_statement_parses_to("SELECT DISTINCT (name, id) FROM customer", sql); assert_eq!( &SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("name"))), &select.projection[0]