@@ -10961,6 +10961,37 @@ impl<'a> Parser<'a> {
1096110961 })
1096210962 }
1096310963
10964+ fn parse_set_values(
10965+ &mut self,
10966+ parenthesized_assignment: bool,
10967+ ) -> Result<Vec<Expr>, ParserError> {
10968+ let mut values = vec![];
10969+
10970+ if parenthesized_assignment {
10971+ self.expect_token(&Token::LParen)?;
10972+ }
10973+
10974+ loop {
10975+ let value = if let Some(expr) = self.try_parse_expr_sub_query()? {
10976+ expr
10977+ } else if let Ok(expr) = self.parse_expr() {
10978+ expr
10979+ } else {
10980+ self.expected("variable value", self.peek_token())?
10981+ };
10982+
10983+ values.push(value);
10984+ if self.consume_token(&Token::Comma) {
10985+ continue;
10986+ }
10987+
10988+ if parenthesized_assignment {
10989+ self.expect_token(&Token::RParen)?;
10990+ }
10991+ return Ok(values);
10992+ }
10993+ }
10994+
1096410995 pub fn parse_set(&mut self) -> Result<Statement, ParserError> {
1096510996 let modifier =
1096610997 self.parse_one_of_keywords(&[Keyword::SESSION, Keyword::LOCAL, Keyword::HIVEVAR]);
@@ -10989,99 +11020,76 @@ impl<'a> Parser<'a> {
1098911020 OneOrManyWithParens::One(self.parse_object_name(false)?)
1099011021 };
1099111022
10992- let names = matches!(&variables, OneOrManyWithParens::One(variable) if variable.to_string().eq_ignore_ascii_case("NAMES"));
10993-
10994- if names && self.dialect.supports_set_names() {
10995- if self.parse_keyword(Keyword::DEFAULT) {
10996- return Ok(Statement::SetNamesDefault {});
10997- }
10998-
10999- let charset_name = self.parse_identifier()?;
11000- let collation_name = if self.parse_one_of_keywords(&[Keyword::COLLATE]).is_some() {
11001- Some(self.parse_literal_string()?)
11002- } else {
11003- None
11004- };
11005-
11006- return Ok(Statement::SetNames {
11007- charset_name,
11008- collation_name,
11023+ if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
11024+ let parenthesized_assignment = matches!(&variables, OneOrManyWithParens::Many(_));
11025+ let values = self.parse_set_values(parenthesized_assignment);
11026+
11027+ return Ok(Statement::SetVariable {
11028+ local: modifier == Some(Keyword::LOCAL),
11029+ hivevar: modifier == Some(Keyword::HIVEVAR),
11030+ variables,
11031+ value: values,
1100911032 });
1101011033 }
1101111034
11012- let parenthesized_assignment = matches!(&variables, OneOrManyWithParens::Many(_));
11013-
11014- if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
11015- if parenthesized_assignment {
11016- self.expect_token(&Token::LParen)?;
11017- }
11035+ let OneOrManyWithParens::One(variable) = variables else {
11036+ return self.expected("set variable", self.peek_token());
11037+ };
1101811038
11019- let mut values = vec![];
11020- loop {
11021- let value = if let Some(expr) = self.try_parse_expr_sub_query()? {
11022- expr
11023- } else if let Ok(expr) = self.parse_expr() {
11024- expr
11039+ match variable.to_string().to_ascii_uppercase().as_str() {
11040+ "NAMES" if self.dialect.supports_set_names() => {
11041+ if self.parse_keyword(Keyword::DEFAULT) {
11042+ return Ok(Statement::SetNamesDefault {});
11043+ }
11044+ let charset_name = self.parse_identifier()?;
11045+ let collation_name = if self.parse_one_of_keywords(&[Keyword::COLLATE]).is_some() {
11046+ Some(self.parse_literal_string()?)
1102511047 } else {
11026- self.expected("variable value", self.peek_token())?
11048+ None
1102711049 };
1102811050
11029- values.push(value);
11030- if self.consume_token(&Token::Comma) {
11031- continue;
11032- }
11033-
11034- if parenthesized_assignment {
11035- self.expect_token(&Token::RParen)?;
11051+ return Ok(Statement::SetNames {
11052+ charset_name,
11053+ collation_name,
11054+ });
11055+ }
11056+ "TIMEZONE" => match self.parse_expr() {
11057+ Ok(expr) => {
11058+ return Ok(Statement::SetTimeZone {
11059+ local: modifier == Some(Keyword::LOCAL),
11060+ value: expr,
11061+ })
1103611062 }
11037- return Ok(Statement::SetVariable {
11038- local: modifier == Some(Keyword::LOCAL),
11039- hivevar: Some(Keyword::HIVEVAR) == modifier,
11040- variables,
11041- value: values,
11063+ _ => return self.expected("timezone value", self.peek_token()),
11064+ },
11065+ "CHARACTERISTICS" => {
11066+ self.expect_keywords(&[Keyword::AS, Keyword::TRANSACTION])?;
11067+ return Ok(Statement::SetTransaction {
11068+ modes: self.parse_transaction_modes()?,
11069+ snapshot: None,
11070+ session: true,
1104211071 });
1104311072 }
11044- }
11045-
11046- let OneOrManyWithParens::One(variable) = variables else {
11047- return self.expected("set variable", self.peek_token());
11048- };
11049-
11050- if variable.to_string().eq_ignore_ascii_case("TIMEZONE") {
11051- // for some db (e.g. postgresql), SET TIME ZONE <value> is an alias for SET TIMEZONE [TO|=] <value>
11052- match self.parse_expr() {
11053- Ok(expr) => Ok(Statement::SetTimeZone {
11054- local: modifier == Some(Keyword::LOCAL),
11055- value: expr,
11056- }),
11057- _ => self.expected("timezone value", self.peek_token())?,
11058- }
11059- } else if variable.to_string() == "CHARACTERISTICS" {
11060- self.expect_keywords(&[Keyword::AS, Keyword::TRANSACTION])?;
11061- Ok(Statement::SetTransaction {
11062- modes: self.parse_transaction_modes()?,
11063- snapshot: None,
11064- session: true,
11065- })
11066- } else if variable.to_string() == "TRANSACTION" && modifier.is_none() {
11067- if self.parse_keyword(Keyword::SNAPSHOT) {
11068- let snapshot_id = self.parse_value()?.value;
11073+ "TRANSACTION" if modifier.is_none() => {
11074+ if self.parse_keyword(Keyword::SNAPSHOT) {
11075+ let snapshot_id = self.parse_value()?.value;
11076+ return Ok(Statement::SetTransaction {
11077+ modes: vec![],
11078+ snapshot: Some(snapshot_id),
11079+ session: false,
11080+ });
11081+ }
1106911082 return Ok(Statement::SetTransaction {
11070- modes: vec![] ,
11071- snapshot: Some(snapshot_id) ,
11083+ modes: self.parse_transaction_modes()? ,
11084+ snapshot: None ,
1107211085 session: false,
1107311086 });
1107411087 }
11075- Ok(Statement::SetTransaction {
11076- modes: self.parse_transaction_modes()?,
11077- snapshot: None,
11078- session: false,
11079- })
11080- } else if self.dialect.supports_set_stmt_without_operator() {
11081- self.prev_token();
11082- self.parse_set_session_params()
11083- } else {
11084- self.expected("equals sign or TO", self.peek_token())
11088+ _ if self.dialect.supports_set_stmt_without_operator() => {
11089+ self.prev_token();
11090+ return self.parse_set_session_params();
11091+ }
11092+ _ => return self.expected("equals sign or TO", self.peek_token()),
1108511093 }
1108611094 }
1108711095
0 commit comments