mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-12-23 11:12:51 +00:00
BigQuery: Fix column identifier reserved keywords list (#1678)
This commit is contained in:
parent
269967a6ac
commit
7980c866a3
5 changed files with 120 additions and 34 deletions
|
|
@ -3951,7 +3951,7 @@ impl<'a> Parser<'a> {
|
|||
self.parse_comma_separated_with_trailing_commas(
|
||||
|p| p.parse_select_item(),
|
||||
trailing_commas,
|
||||
None,
|
||||
Self::is_reserved_for_column_alias,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -3985,30 +3985,42 @@ impl<'a> Parser<'a> {
|
|||
self.parse_comma_separated_with_trailing_commas(
|
||||
Parser::parse_table_and_joins,
|
||||
trailing_commas,
|
||||
Some(self.dialect.get_reserved_keywords_for_table_factor()),
|
||||
|kw, _parser| {
|
||||
self.dialect
|
||||
.get_reserved_keywords_for_table_factor()
|
||||
.contains(kw)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Parse the comma of a comma-separated syntax element.
|
||||
/// `R` is a predicate that should return true if the next
|
||||
/// keyword is a reserved keyword.
|
||||
/// Allows for control over trailing commas
|
||||
///
|
||||
/// Returns true if there is a next element
|
||||
fn is_parse_comma_separated_end_with_trailing_commas(
|
||||
fn is_parse_comma_separated_end_with_trailing_commas<R>(
|
||||
&mut self,
|
||||
trailing_commas: bool,
|
||||
reserved_keywords: Option<&[Keyword]>,
|
||||
) -> bool {
|
||||
let reserved_keywords = reserved_keywords.unwrap_or(keywords::RESERVED_FOR_COLUMN_ALIAS);
|
||||
is_reserved_keyword: &R,
|
||||
) -> bool
|
||||
where
|
||||
R: Fn(&Keyword, &mut Parser) -> bool,
|
||||
{
|
||||
if !self.consume_token(&Token::Comma) {
|
||||
true
|
||||
} else if trailing_commas {
|
||||
let token = self.peek_token().token;
|
||||
match token {
|
||||
Token::Word(ref kw) if reserved_keywords.contains(&kw.keyword) => true,
|
||||
let token = self.next_token().token;
|
||||
let is_end = match token {
|
||||
Token::Word(ref kw) if is_reserved_keyword(&kw.keyword, self) => true,
|
||||
Token::RParen | Token::SemiColon | Token::EOF | Token::RBracket | Token::RBrace => {
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
};
|
||||
self.prev_token();
|
||||
|
||||
is_end
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
@ -4017,7 +4029,10 @@ impl<'a> Parser<'a> {
|
|||
/// Parse the comma of a comma-separated syntax element.
|
||||
/// Returns true if there is a next element
|
||||
fn is_parse_comma_separated_end(&mut self) -> bool {
|
||||
self.is_parse_comma_separated_end_with_trailing_commas(self.options.trailing_commas, None)
|
||||
self.is_parse_comma_separated_end_with_trailing_commas(
|
||||
self.options.trailing_commas,
|
||||
&Self::is_reserved_for_column_alias,
|
||||
)
|
||||
}
|
||||
|
||||
/// Parse a comma-separated list of 1+ items accepted by `F`
|
||||
|
|
@ -4025,26 +4040,33 @@ impl<'a> Parser<'a> {
|
|||
where
|
||||
F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
|
||||
{
|
||||
self.parse_comma_separated_with_trailing_commas(f, self.options.trailing_commas, None)
|
||||
self.parse_comma_separated_with_trailing_commas(
|
||||
f,
|
||||
self.options.trailing_commas,
|
||||
Self::is_reserved_for_column_alias,
|
||||
)
|
||||
}
|
||||
|
||||
/// Parse a comma-separated list of 1+ items accepted by `F`
|
||||
/// Allows for control over trailing commas
|
||||
fn parse_comma_separated_with_trailing_commas<T, F>(
|
||||
/// Parse a comma-separated list of 1+ items accepted by `F`.
|
||||
/// `R` is a predicate that should return true if the next
|
||||
/// keyword is a reserved keyword.
|
||||
/// Allows for control over trailing commas.
|
||||
fn parse_comma_separated_with_trailing_commas<T, F, R>(
|
||||
&mut self,
|
||||
mut f: F,
|
||||
trailing_commas: bool,
|
||||
reserved_keywords: Option<&[Keyword]>,
|
||||
is_reserved_keyword: R,
|
||||
) -> Result<Vec<T>, ParserError>
|
||||
where
|
||||
F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
|
||||
R: Fn(&Keyword, &mut Parser) -> bool,
|
||||
{
|
||||
let mut values = vec![];
|
||||
loop {
|
||||
values.push(f(self)?);
|
||||
if self.is_parse_comma_separated_end_with_trailing_commas(
|
||||
trailing_commas,
|
||||
reserved_keywords,
|
||||
&is_reserved_keyword,
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -4118,6 +4140,13 @@ impl<'a> Parser<'a> {
|
|||
self.parse_comma_separated(f)
|
||||
}
|
||||
|
||||
/// Default implementation of a predicate that returns true if
|
||||
/// the specified keyword is reserved for column alias.
|
||||
/// See [Dialect::is_column_alias]
|
||||
fn is_reserved_for_column_alias(kw: &Keyword, parser: &mut Parser) -> bool {
|
||||
!parser.dialect.is_column_alias(kw, parser)
|
||||
}
|
||||
|
||||
/// Run a parser method `f`, reverting back to the current position if unsuccessful.
|
||||
/// Returns `None` if `f` returns an error
|
||||
pub fn maybe_parse<T, F>(&mut self, f: F) -> Result<Option<T>, ParserError>
|
||||
|
|
@ -9394,7 +9423,7 @@ impl<'a> Parser<'a> {
|
|||
let cols = self.parse_comma_separated_with_trailing_commas(
|
||||
Parser::parse_view_column,
|
||||
self.dialect.supports_column_definition_trailing_commas(),
|
||||
None,
|
||||
Self::is_reserved_for_column_alias,
|
||||
)?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
Ok(cols)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue