@@ -11145,17 +11145,16 @@ impl<'a> Parser<'a> {
1114511145 }
1114611146
1114711147 /// Parse a `SET ROLE` statement. Expects SET to be consumed already.
11148- fn parse_set_role(&mut self, modifier: Option<Keyword> ) -> Result<Statement, ParserError> {
11148+ fn parse_set_role(&mut self, modifier: ContextModifier ) -> Result<Statement, ParserError> {
1114911149 self.expect_keyword_is(Keyword::ROLE)?;
11150- let context_modifier = Self::keyword_to_modifier(modifier);
1115111150
1115211151 let role_name = if self.parse_keyword(Keyword::NONE) {
1115311152 None
1115411153 } else {
1115511154 Some(self.parse_identifier()?)
1115611155 };
1115711156 Ok(Statement::Set(Set::SetRole {
11158- context_modifier,
11157+ context_modifier: modifier ,
1115911158 role_name,
1116011159 }))
1116111160 }
@@ -11191,46 +11190,52 @@ impl<'a> Parser<'a> {
1119111190 }
1119211191 }
1119311192
11194- fn parse_set_assignment(
11195- &mut self,
11196- ) -> Result<(OneOrManyWithParens<ObjectName>, Expr), ParserError> {
11197- let variables = if self.dialect.supports_parenthesized_set_variables()
11193+ fn parse_context_modifier(&mut self) -> ContextModifier {
11194+ let modifier =
11195+ self.parse_one_of_keywords(&[Keyword::SESSION, Keyword::LOCAL, Keyword::GLOBAL]);
11196+
11197+ Self::keyword_to_modifier(modifier)
11198+ }
11199+
11200+ /// Parse a single SET statement assignment `var = expr`.
11201+ fn parse_set_assignment(&mut self) -> Result<SetAssignment, ParserError> {
11202+ let scope = self.parse_context_modifier();
11203+
11204+ let name = if self.dialect.supports_parenthesized_set_variables()
1119811205 && self.consume_token(&Token::LParen)
1119911206 {
11200- let vars = OneOrManyWithParens::Many(
11201- self.parse_comma_separated(|parser: &mut Parser<'a>| parser.parse_identifier())?
11202- .into_iter()
11203- .map(|ident| ObjectName::from(vec![ident]))
11204- .collect(),
11205- );
11206- self.expect_token(&Token::RParen)?;
11207- vars
11207+ // Parenthesized assignments are handled in the `parse_set` function after
11208+ // trying to parse list of assignments using this function.
11209+ // If a dialect supports both, and we find a LParen, we early exit from this function.
11210+ self.expected("Unparenthesized assignment", self.peek_token())?
1120811211 } else {
11209- OneOrManyWithParens::One( self.parse_object_name(false)?)
11212+ self.parse_object_name(false)?
1121011213 };
1121111214
1121211215 if !(self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO)) {
1121311216 return self.expected("assignment operator", self.peek_token());
1121411217 }
1121511218
11216- let values = self.parse_expr()?;
11219+ let value = self.parse_expr()?;
1121711220
11218- Ok((variables, values) )
11221+ Ok(SetAssignment { scope, name, value } )
1121911222 }
1122011223
1122111224 fn parse_set(&mut self) -> Result<Statement, ParserError> {
11222- let modifier = self.parse_one_of_keywords(&[
11223- Keyword::SESSION,
11224- Keyword::LOCAL,
11225- Keyword::HIVEVAR,
11226- Keyword::GLOBAL,
11227- ]);
11228-
11229- if let Some(Keyword::HIVEVAR) = modifier {
11225+ let hivevar = self.parse_keyword(Keyword::HIVEVAR);
11226+
11227+ // Modifier is either HIVEVAR: or a ContextModifier (LOCAL, SESSION, etc), not both
11228+ let scope = if !hivevar {
11229+ self.parse_context_modifier()
11230+ } else {
11231+ ContextModifier::None
11232+ };
11233+
11234+ if hivevar {
1123011235 self.expect_token(&Token::Colon)?;
1123111236 }
1123211237
11233- if let Some(set_role_stmt) = self.maybe_parse(|parser| parser.parse_set_role(modifier ))? {
11238+ if let Some(set_role_stmt) = self.maybe_parse(|parser| parser.parse_set_role(scope ))? {
1123411239 return Ok(set_role_stmt);
1123511240 }
1123611241
@@ -11240,8 +11245,8 @@ impl<'a> Parser<'a> {
1124011245 {
1124111246 if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
1124211247 return Ok(Set::SingleAssignment {
11243- scope: Self::keyword_to_modifier(modifier) ,
11244- hivevar: modifier == Some(Keyword::HIVEVAR) ,
11248+ scope,
11249+ hivevar,
1124511250 variable: ObjectName::from(vec!["TIMEZONE".into()]),
1124611251 values: self.parse_set_values(false)?,
1124711252 }
@@ -11251,7 +11256,7 @@ impl<'a> Parser<'a> {
1125111256 // the assignment operator. It's originally PostgreSQL specific,
1125211257 // but we allow it for all the dialects
1125311258 return Ok(Set::SetTimeZone {
11254- local: modifier == Some(Keyword::LOCAL) ,
11259+ local: scope == ContextModifier::Local ,
1125511260 value: self.parse_expr()?,
1125611261 }
1125711262 .into());
@@ -11299,41 +11304,26 @@ impl<'a> Parser<'a> {
1129911304 }
1130011305
1130111306 if self.dialect.supports_comma_separated_set_assignments() {
11307+ if scope != ContextModifier::None {
11308+ self.prev_token();
11309+ }
11310+
1130211311 if let Some(assignments) = self
1130311312 .maybe_parse(|parser| parser.parse_comma_separated(Parser::parse_set_assignment))?
1130411313 {
1130511314 return if assignments.len() > 1 {
11306- let assignments = assignments
11307- .into_iter()
11308- .map(|(var, val)| match var {
11309- OneOrManyWithParens::One(v) => Ok(SetAssignment {
11310- name: v,
11311- value: val,
11312- }),
11313- OneOrManyWithParens::Many(_) => {
11314- self.expected("List of single identifiers", self.peek_token())
11315- }
11316- })
11317- .collect::<Result<_, _>>()?;
11318-
1131911315 Ok(Set::MultipleAssignments { assignments }.into())
1132011316 } else {
11321- let (vars, values): (Vec<_>, Vec<_>) = assignments.into_iter().unzip();
11322-
11323- let variable = match vars.into_iter().next() {
11324- Some(OneOrManyWithParens::One(v)) => Ok(v),
11325- Some(OneOrManyWithParens::Many(_)) => self.expected(
11326- "Single assignment or list of assignments",
11327- self.peek_token(),
11328- ),
11329- None => self.expected("At least one identifier", self.peek_token()),
11330- }?;
11317+ let SetAssignment { scope, name, value } =
11318+ assignments.into_iter().next().ok_or_else(|| {
11319+ ParserError::ParserError("Expected at least one assignment".to_string())
11320+ })?;
1133111321
1133211322 Ok(Set::SingleAssignment {
11333- scope: Self::keyword_to_modifier(modifier) ,
11334- hivevar: modifier == Some(Keyword::HIVEVAR) ,
11335- variable,
11336- values,
11323+ scope,
11324+ hivevar,
11325+ variable: name ,
11326+ values: vec![value] ,
1133711327 }
1133811328 .into())
1133911329 };
@@ -11358,8 +11348,8 @@ impl<'a> Parser<'a> {
1135811348 if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
1135911349 let stmt = match variables {
1136011350 OneOrManyWithParens::One(var) => Set::SingleAssignment {
11361- scope: Self::keyword_to_modifier(modifier) ,
11362- hivevar: modifier == Some(Keyword::HIVEVAR) ,
11351+ scope,
11352+ hivevar,
1136311353 variable: var,
1136411354 values: self.parse_set_values(false)?,
1136511355 },
0 commit comments