From a698f663720d2d6ce3628e4767a94e906f834cc6 Mon Sep 17 00:00:00 2001 From: Wei-Ting Kuo Date: Fri, 25 Nov 2022 18:19:55 +0800 Subject: [PATCH 1/4] add set time zone sometimezone as a exception while parsing keyword::set --- src/parser.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/parser.rs b/src/parser.rs index a0b141bc1..4abf275ef 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4553,7 +4553,10 @@ impl<'a> Parser<'a> { charset_name, collation_name, }) - } else if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) { + } else if (self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO)) + || (variable == ObjectName(vec!["TIMEZONE".into()])) + { + // when the object name is TIMEZONE, we support `SET TIMEZONE 'UTC'` without Eq sign or TO let mut values = vec![]; loop { let value = if let Ok(expr) = self.parse_expr() { From d0753f87b6e3440c1cd74276b351e1a3fd9667a5 Mon Sep 17 00:00:00 2001 From: Wei-Ting Kuo Date: Fri, 25 Nov 2022 18:34:46 +0800 Subject: [PATCH 2/4] remove redundant parentheses --- src/parser.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 4abf275ef..699f8fd39 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4553,8 +4553,9 @@ impl<'a> Parser<'a> { charset_name, collation_name, }) - } else if (self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO)) - || (variable == ObjectName(vec!["TIMEZONE".into()])) + } else if self.consume_token(&Token::Eq) + || self.parse_keyword(Keyword::TO) + || variable == ObjectName(vec!["TIMEZONE".into()]) { // when the object name is TIMEZONE, we support `SET TIMEZONE 'UTC'` without Eq sign or TO let mut values = vec![]; From 64ddbb2e9f5a73f4280d0b5ccf524ce8451be0f8 Mon Sep 17 00:00:00 2001 From: Wei-Ting Kuo Date: Mon, 28 Nov 2022 17:29:21 +0800 Subject: [PATCH 3/4] add Statement::SetTimeZone --- src/ast/mod.rs | 12 ++++++++++++ src/parser.rs | 15 ++++++++++----- tests/sqlparser_common.rs | 13 +++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index f568c3960..16210f863 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1271,6 +1271,11 @@ pub enum Statement { variable: ObjectName, value: Vec, }, + /// SET TIME ZONE + /// + /// Note: this is a PostgreSQL-specific statements + /// SET TIME ZONE is an alias for SET timezone TO in PostgreSQL + SetTimeZone { local: bool, value: Expr }, /// SET NAMES 'charset_name' [COLLATE 'collation_name'] /// /// Note: this is a MySQL-specific statement. @@ -2228,6 +2233,13 @@ impl fmt::Display for Statement { value = display_comma_separated(value) ) } + Statement::SetTimeZone { local, value } => { + f.write_str("SET ")?; + if *local { + f.write_str("LOCAL ")?; + } + write!(f, "TIME ZONE {value}") + } Statement::SetNames { charset_name, collation_name, diff --git a/src/parser.rs b/src/parser.rs index 699f8fd39..33978a681 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4553,11 +4553,7 @@ impl<'a> Parser<'a> { charset_name, collation_name, }) - } else if self.consume_token(&Token::Eq) - || self.parse_keyword(Keyword::TO) - || variable == ObjectName(vec!["TIMEZONE".into()]) - { - // when the object name is TIMEZONE, we support `SET TIMEZONE 'UTC'` without Eq sign or TO + } else if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) { let mut values = vec![]; loop { let value = if let Ok(expr) = self.parse_expr() { @@ -4577,6 +4573,15 @@ impl<'a> Parser<'a> { value: values, }); } + } else if variable.to_string().eq_ignore_ascii_case("TIMEZONE") { + // for some db (e.g. postgresql), SET TIME ZONE is an alias for SET TIMEZONE [TO|=] + match self.parse_expr() { + Ok(expr) => Ok(Statement::SetTimeZone { + local: modifier == Some(Keyword::LOCAL), + value: expr, + }), + _ => self.expected("timezone value", self.peek_token())?, + } } else if variable.to_string() == "CHARACTERISTICS" { self.expect_keywords(&[Keyword::AS, Keyword::TRANSACTION])?; Ok(Statement::SetTransaction { diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index ec4c2f257..e05d97611 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -4979,6 +4979,19 @@ fn parse_set_time_zone() { one_statement_parses_to("SET TIME ZONE TO 'UTC'", "SET TIMEZONE = 'UTC'"); } +#[test] +fn parse_set_time_zone_alias() { + println!("wew"); + match verified_stmt("SET TIME ZONE 'UTC'") { + Statement::SetTimeZone { local, value } => { + assert!(!local); + println!("wew"); + assert_eq!(value, Expr::Value(Value::SingleQuotedString("UTC".into()))); + } + _ => unreachable!(), + } +} + #[test] fn parse_commit() { match verified_stmt("COMMIT") { From 453fd90b89bc8158a0b57c31ea619c85c7dec723 Mon Sep 17 00:00:00 2001 From: Wei-Ting Kuo Date: Tue, 29 Nov 2022 04:47:17 +0800 Subject: [PATCH 4/4] delete useless comments --- tests/sqlparser_common.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index e05d97611..2af06d15e 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -4981,11 +4981,9 @@ fn parse_set_time_zone() { #[test] fn parse_set_time_zone_alias() { - println!("wew"); match verified_stmt("SET TIME ZONE 'UTC'") { Statement::SetTimeZone { local, value } => { assert!(!local); - println!("wew"); assert_eq!(value, Expr::Value(Value::SingleQuotedString("UTC".into()))); } _ => unreachable!(),