feat: Support trailing commas (#557)

This commit is contained in:
Yoshiyuki Komazaki 2022-08-11 19:54:04 +09:00 committed by GitHub
parent 8176561100
commit aabafc9fc8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 1 deletions

View file

@ -1639,6 +1639,33 @@ impl<'a> Parser<'a> {
}
}
/// Parse a comma-separated list of 1+ SelectItem
pub fn parse_projection(&mut self) -> Result<Vec<SelectItem>, ParserError> {
let mut values = vec![];
loop {
values.push(self.parse_select_item()?);
if !self.consume_token(&Token::Comma) {
break;
} else if dialect_of!(self is BigQueryDialect) {
// BigQuery allows trailing commas.
// e.g. `SELECT 1, 2, FROM t`
// https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#trailing_commas
match self.peek_token() {
Token::Word(kw)
if keywords::RESERVED_FOR_COLUMN_ALIAS
.iter()
.any(|d| kw.keyword == *d) =>
{
break
}
Token::RParen | Token::EOF => break,
_ => continue,
}
}
}
Ok(values)
}
/// Parse a comma-separated list of 1+ items accepted by `F`
pub fn parse_comma_separated<T, F>(&mut self, mut f: F) -> Result<Vec<T>, ParserError>
where
@ -3486,7 +3513,7 @@ impl<'a> Parser<'a> {
None
};
let projection = self.parse_comma_separated(Parser::parse_select_item)?;
let projection = self.parse_projection()?;
let into = if self.parse_keyword(Keyword::INTO) {
let temporary = self

View file

@ -94,6 +94,21 @@ fn parse_table_identifiers() {
test_table_ident("abc5.GROUP", vec![Ident::new("abc5"), Ident::new("GROUP")]);
}
#[test]
fn parse_trailing_comma() {
for (sql, canonical) in [
("SELECT a,", "SELECT a"),
("SELECT a, b,", "SELECT a, b"),
("SELECT a, b AS c,", "SELECT a, b AS c"),
("SELECT a, b AS c, FROM t", "SELECT a, b AS c FROM t"),
("SELECT a, b, FROM t", "SELECT a, b FROM t"),
("SELECT a, b, LIMIT 1", "SELECT a, b LIMIT 1"),
("SELECT a, (SELECT 1, )", "SELECT a, (SELECT 1)"),
] {
bigquery().one_statement_parses_to(sql, canonical);
}
}
#[test]
fn parse_cast_type() {
let sql = r#"SELECT SAFE_CAST(1 AS INT64)"#;