@@ -3951,7 +3951,7 @@ impl<'a> Parser<'a> {
39513951 self.parse_comma_separated_with_trailing_commas(
39523952 |p| p.parse_select_item(),
39533953 trailing_commas,
3954- None ,
3954+ Self::is_reserved_for_column_alias ,
39553955 )
39563956 }
39573957
@@ -3985,30 +3985,42 @@ impl<'a> Parser<'a> {
39853985 self.parse_comma_separated_with_trailing_commas(
39863986 Parser::parse_table_and_joins,
39873987 trailing_commas,
3988- Some(self.dialect.get_reserved_keywords_for_table_factor()),
3988+ |kw, _parser| {
3989+ self.dialect
3990+ .get_reserved_keywords_for_table_factor()
3991+ .contains(kw)
3992+ },
39893993 )
39903994 }
39913995
39923996 /// Parse the comma of a comma-separated syntax element.
3997+ /// `R` is a predicate that should return true if the next
3998+ /// keyword is a reserved keyword.
39933999 /// Allows for control over trailing commas
4000+ ///
39944001 /// Returns true if there is a next element
3995- fn is_parse_comma_separated_end_with_trailing_commas(
4002+ fn is_parse_comma_separated_end_with_trailing_commas<R> (
39964003 &mut self,
39974004 trailing_commas: bool,
3998- reserved_keywords: Option<&[Keyword]>,
3999- ) -> bool {
4000- let reserved_keywords = reserved_keywords.unwrap_or(keywords::RESERVED_FOR_COLUMN_ALIAS);
4005+ is_reserved_keyword: &R,
4006+ ) -> bool
4007+ where
4008+ R: Fn(&Keyword, &mut Parser) -> bool,
4009+ {
40014010 if !self.consume_token(&Token::Comma) {
40024011 true
40034012 } else if trailing_commas {
4004- let token = self.peek_token ().token;
4005- match token {
4006- Token::Word(ref kw) if reserved_keywords.contains (&kw.keyword) => true,
4013+ let token = self.next_token ().token;
4014+ let is_end = match token {
4015+ Token::Word(ref kw) if is_reserved_keyword (&kw.keyword, self ) => true,
40074016 Token::RParen | Token::SemiColon | Token::EOF | Token::RBracket | Token::RBrace => {
40084017 true
40094018 }
40104019 _ => false,
4011- }
4020+ };
4021+ self.prev_token();
4022+
4023+ is_end
40124024 } else {
40134025 false
40144026 }
@@ -4017,34 +4029,44 @@ impl<'a> Parser<'a> {
40174029 /// Parse the comma of a comma-separated syntax element.
40184030 /// Returns true if there is a next element
40194031 fn is_parse_comma_separated_end(&mut self) -> bool {
4020- self.is_parse_comma_separated_end_with_trailing_commas(self.options.trailing_commas, None)
4032+ self.is_parse_comma_separated_end_with_trailing_commas(
4033+ self.options.trailing_commas,
4034+ &Self::is_reserved_for_column_alias,
4035+ )
40214036 }
40224037
40234038 /// Parse a comma-separated list of 1+ items accepted by `F`
40244039 pub fn parse_comma_separated<T, F>(&mut self, f: F) -> Result<Vec<T>, ParserError>
40254040 where
40264041 F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
40274042 {
4028- self.parse_comma_separated_with_trailing_commas(f, self.options.trailing_commas, None)
4043+ self.parse_comma_separated_with_trailing_commas(
4044+ f,
4045+ self.options.trailing_commas,
4046+ Self::is_reserved_for_column_alias,
4047+ )
40294048 }
40304049
4031- /// Parse a comma-separated list of 1+ items accepted by `F`
4032- /// Allows for control over trailing commas
4033- fn parse_comma_separated_with_trailing_commas<T, F>(
4050+ /// Parse a comma-separated list of 1+ items accepted by `F`.
4051+ /// `R` is a predicate that should return true if the next
4052+ /// keyword is a reserved keyword.
4053+ /// Allows for control over trailing commas.
4054+ fn parse_comma_separated_with_trailing_commas<T, F, R>(
40344055 &mut self,
40354056 mut f: F,
40364057 trailing_commas: bool,
4037- reserved_keywords: Option<&[Keyword]> ,
4058+ is_reserved_keyword: R ,
40384059 ) -> Result<Vec<T>, ParserError>
40394060 where
40404061 F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
4062+ R: Fn(&Keyword, &mut Parser) -> bool,
40414063 {
40424064 let mut values = vec![];
40434065 loop {
40444066 values.push(f(self)?);
40454067 if self.is_parse_comma_separated_end_with_trailing_commas(
40464068 trailing_commas,
4047- reserved_keywords ,
4069+ &is_reserved_keyword ,
40484070 ) {
40494071 break;
40504072 }
@@ -4118,6 +4140,13 @@ impl<'a> Parser<'a> {
41184140 self.parse_comma_separated(f)
41194141 }
41204142
4143+ /// Default implementation of a predicate that returns true if
4144+ /// the specified keyword is reserved for column alias.
4145+ /// See [Dialect::is_column_alias]
4146+ fn is_reserved_for_column_alias(kw: &Keyword, parser: &mut Parser) -> bool {
4147+ !parser.dialect.is_column_alias(kw, parser)
4148+ }
4149+
41214150 /// Run a parser method `f`, reverting back to the current position if unsuccessful.
41224151 /// Returns `None` if `f` returns an error
41234152 pub fn maybe_parse<T, F>(&mut self, f: F) -> Result<Option<T>, ParserError>
@@ -9394,7 +9423,7 @@ impl<'a> Parser<'a> {
93949423 let cols = self.parse_comma_separated_with_trailing_commas(
93959424 Parser::parse_view_column,
93969425 self.dialect.supports_column_definition_trailing_commas(),
9397- None ,
9426+ Self::is_reserved_for_column_alias ,
93989427 )?;
93999428 self.expect_token(&Token::RParen)?;
94009429 Ok(cols)
0 commit comments