@@ -3516,16 +3516,11 @@ impl<'a> Parser<'a> {
35163516 // e.g. `SELECT 1, 2, FROM t`
35173517 // https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#trailing_commas
35183518 // https://docs.snowflake.com/en/release-notes/2024/8_11#select-supports-trailing-commas
3519- //
3520- // This pattern could be captured better with RAII type semantics, but it's quite a bit of
3521- // code to add for just one case, so we'll just do it manually here.
3522- let old_value = self.options.trailing_commas;
3523- self.options.trailing_commas |= self.dialect.supports_projection_trailing_commas();
35243519
3525- let ret = self.parse_comma_separated(|p| p.parse_select_item());
3526- self.options.trailing_commas = old_value ;
3520+ let trailing_commas =
3521+ self.options.trailing_commas | self.dialect.supports_projection_trailing_commas() ;
35273522
3528- ret
3523+ self.parse_comma_separated_with_trailing_commas(|p| p.parse_select_item(), trailing_commas)
35293524 }
35303525
35313526 pub fn parse_actions_list(&mut self) -> Result<Vec<ParsedAction>, ParserError> {
@@ -3552,11 +3547,12 @@ impl<'a> Parser<'a> {
35523547 }
35533548
35543549 /// Parse the comma of a comma-separated syntax element.
3550+ /// Allows for control over trailing commas
35553551 /// Returns true if there is a next element
3556- fn is_parse_comma_separated_end (&mut self) -> bool {
3552+ fn is_parse_comma_separated_end_with_trailing_commas (&mut self, trailing_commas: bool ) -> bool {
35573553 if !self.consume_token(&Token::Comma) {
35583554 true
3559- } else if self.options. trailing_commas {
3555+ } else if trailing_commas {
35603556 let token = self.peek_token().token;
35613557 match token {
35623558 Token::Word(ref kw)
@@ -3574,15 +3570,34 @@ impl<'a> Parser<'a> {
35743570 }
35753571 }
35763572
3573+ /// Parse the comma of a comma-separated syntax element.
3574+ /// Returns true if there is a next element
3575+ fn is_parse_comma_separated_end(&mut self) -> bool {
3576+ self.is_parse_comma_separated_end_with_trailing_commas(self.options.trailing_commas)
3577+ }
3578+
35773579 /// Parse a comma-separated list of 1+ items accepted by `F`
3578- pub fn parse_comma_separated<T, F>(&mut self, mut f: F) -> Result<Vec<T>, ParserError>
3580+ pub fn parse_comma_separated<T, F>(&mut self, f: F) -> Result<Vec<T>, ParserError>
3581+ where
3582+ F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
3583+ {
3584+ self.parse_comma_separated_with_trailing_commas(f, self.options.trailing_commas)
3585+ }
3586+
3587+ /// Parse a comma-separated list of 1+ items accepted by `F`
3588+ /// Allows for control over trailing commas
3589+ fn parse_comma_separated_with_trailing_commas<T, F>(
3590+ &mut self,
3591+ mut f: F,
3592+ trailing_commas: bool,
3593+ ) -> Result<Vec<T>, ParserError>
35793594 where
35803595 F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
35813596 {
35823597 let mut values = vec![];
35833598 loop {
35843599 values.push(f(self)?);
3585- if self.is_parse_comma_separated_end( ) {
3600+ if self.is_parse_comma_separated_end_with_trailing_commas(trailing_commas ) {
35863601 break;
35873602 }
35883603 }
0 commit comments