diff --git a/e2e_test/database/timezone.slt b/e2e_test/database/timezone.slt index 1af87000610a4..5ee196a8bf17d 100644 --- a/e2e_test/database/timezone.slt +++ b/e2e_test/database/timezone.slt @@ -29,4 +29,45 @@ set timezone = 'GMT' query T show timezone; ---- -GMT \ No newline at end of file +GMT + +statement ok +set time zone local; + +statement ok +set time zone default; + +statement ok +set time zone 'utc'; + +statement error Invalid value +set time zone 'utcx'; + +statement ok +set time zone utc; + +statement error Invalid value +set time zone utcx; + +statement ok +set time zone "utc"; + +statement error Invalid value +set time zone "utcx"; + +statement error Invalid value +set time zone "default"; + +statement error Invalid value +set time zone "local"; + +statement error Invalid value +set time zone null; + +# The following are valid in PostgreSQL but we do not support them for simplicity. + +statement error Invalid value +set time zone 12.3; + +statement error +set time zone interval '1' hour; diff --git a/src/sqlparser/src/parser.rs b/src/sqlparser/src/parser.rs index 538eb7302414e..932ee368f0f17 100644 --- a/src/sqlparser/src/parser.rs +++ b/src/sqlparser/src/parser.rs @@ -3581,15 +3581,17 @@ impl Parser { pub fn parse_set(&mut self) -> Result { let modifier = self.parse_one_of_keywords(&[Keyword::SESSION, Keyword::LOCAL]); if self.parse_keywords(&[Keyword::TIME, Keyword::ZONE]) { - let value = if self.parse_keyword(Keyword::DEFAULT) { - SetTimeZoneValue::Default - } else if self.parse_keyword(Keyword::LOCAL) { - SetTimeZoneValue::Local - } else if let Ok(ident) = self.parse_identifier() { - SetTimeZoneValue::Ident(ident) - } else { - let value = self.parse_value()?; - SetTimeZoneValue::Literal(value) + let token = self.peek_token(); + let value = match (self.parse_value(), token.token) { + (Ok(value), _) => SetTimeZoneValue::Literal(value), + (Err(_), Token::Word(w)) if w.keyword == Keyword::DEFAULT => { + SetTimeZoneValue::Default + } + (Err(_), Token::Word(w)) if w.keyword == Keyword::LOCAL => SetTimeZoneValue::Local, + (Err(_), Token::Word(w)) => SetTimeZoneValue::Ident(w.to_ident()?), + (Err(_), unexpected) => { + self.expected("variable value", unexpected.with_location(token.location))? + } }; return Ok(Statement::SetTimeZone { diff --git a/src/sqlparser/tests/testdata/set.yaml b/src/sqlparser/tests/testdata/set.yaml index 88aaa61949606..309ffc5213aee 100644 --- a/src/sqlparser/tests/testdata/set.yaml +++ b/src/sqlparser/tests/testdata/set.yaml @@ -6,9 +6,7 @@ - input: SET TIME ZONE "Asia/Shanghai" formatted_sql: SET TIME ZONE "Asia/Shanghai" - input: SET TIME ZONE 'Asia/Shanghai' - error_msg: |- - sql parser error: Expected a value, found: EOF at the end - Near "SET TIME ZONE 'Asia/Shanghai'" + formatted_sql: SET TIME ZONE 'Asia/Shanghai' - input: SET TIME ZONE "UTC" formatted_sql: SET TIME ZONE "UTC" - input: SET TIME ZONE UTC