Skip to content

Commit f77192d

Browse files
Re-enable trailing commas in DCL (#1318)
1 parent 0884dd9 commit f77192d

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

src/parser/mod.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ pub enum ParserError {
4646
RecursionLimitExceeded,
4747
}
4848

49+
// avoid clippy type_complexity warnings
50+
type ParsedAction = (Keyword, Option<Vec<Ident>>);
51+
4952
// Use `Parser::expected` instead, if possible
5053
macro_rules! parser_err {
5154
($MSG:expr, $loc:expr) => {
@@ -3334,6 +3337,29 @@ impl<'a> Parser<'a> {
33343337
ret
33353338
}
33363339

3340+
pub fn parse_actions_list(&mut self) -> Result<Vec<ParsedAction>, ParserError> {
3341+
let mut values = vec![];
3342+
loop {
3343+
values.push(self.parse_grant_permission()?);
3344+
if !self.consume_token(&Token::Comma) {
3345+
break;
3346+
} else if self.options.trailing_commas {
3347+
match self.peek_token().token {
3348+
Token::Word(kw) if kw.keyword == Keyword::ON => {
3349+
break;
3350+
}
3351+
Token::RParen
3352+
| Token::SemiColon
3353+
| Token::EOF
3354+
| Token::RBracket
3355+
| Token::RBrace => break,
3356+
_ => continue,
3357+
}
3358+
}
3359+
}
3360+
Ok(values)
3361+
}
3362+
33373363
/// Parse a comma-separated list of 1+ items accepted by `F`
33383364
pub fn parse_comma_separated<T, F>(&mut self, mut f: F) -> Result<Vec<T>, ParserError>
33393365
where
@@ -3347,9 +3373,7 @@ impl<'a> Parser<'a> {
33473373
} else if self.options.trailing_commas {
33483374
match self.peek_token().token {
33493375
Token::Word(kw)
3350-
if keywords::RESERVED_FOR_COLUMN_ALIAS
3351-
.iter()
3352-
.any(|d| kw.keyword == *d) =>
3376+
if keywords::RESERVED_FOR_COLUMN_ALIAS.contains(&kw.keyword) =>
33533377
{
33543378
break;
33553379
}
@@ -9680,11 +9704,8 @@ impl<'a> Parser<'a> {
96809704
with_privileges_keyword: self.parse_keyword(Keyword::PRIVILEGES),
96819705
}
96829706
} else {
9683-
let old_value = self.options.trailing_commas;
9684-
self.options.trailing_commas = false;
9685-
96869707
let (actions, err): (Vec<_>, Vec<_>) = self
9687-
.parse_comma_separated(Parser::parse_grant_permission)?
9708+
.parse_actions_list()?
96889709
.into_iter()
96899710
.map(|(kw, columns)| match kw {
96909711
Keyword::DELETE => Ok(Action::Delete),
@@ -9706,8 +9727,6 @@ impl<'a> Parser<'a> {
97069727
})
97079728
.partition(Result::is_ok);
97089729

9709-
self.options.trailing_commas = old_value;
9710-
97119730
if !err.is_empty() {
97129731
let errors: Vec<Keyword> = err.into_iter().filter_map(|x| x.err()).collect();
97139732
return Err(ParserError::ParserError(format!(
@@ -9753,7 +9772,7 @@ impl<'a> Parser<'a> {
97539772
Ok((privileges, objects))
97549773
}
97559774

9756-
pub fn parse_grant_permission(&mut self) -> Result<(Keyword, Option<Vec<Ident>>), ParserError> {
9775+
pub fn parse_grant_permission(&mut self) -> Result<ParsedAction, ParserError> {
97579776
if let Some(kw) = self.parse_one_of_keywords(&[
97589777
Keyword::CONNECT,
97599778
Keyword::CREATE,

tests/sqlparser_common.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8942,6 +8942,11 @@ fn parse_trailing_comma() {
89428942
"CREATE TABLE employees (name TEXT, age INT)",
89438943
);
89448944

8945+
trailing_commas.one_statement_parses_to(
8946+
"GRANT USAGE, SELECT, INSERT, ON p TO u",
8947+
"GRANT USAGE, SELECT, INSERT ON p TO u",
8948+
);
8949+
89458950
trailing_commas.verified_stmt("SELECT album_id, name FROM track");
89468951

89478952
trailing_commas.verified_stmt("SELECT * FROM track ORDER BY milliseconds");
@@ -8961,6 +8966,13 @@ fn parse_trailing_comma() {
89618966
ParserError::ParserError("Expected an expression, found: from".to_string())
89628967
);
89638968

8969+
assert_eq!(
8970+
trailing_commas
8971+
.parse_sql_statements("REVOKE USAGE, SELECT, ON p TO u")
8972+
.unwrap_err(),
8973+
ParserError::ParserError("Expected a privilege keyword, found: ON".to_string())
8974+
);
8975+
89648976
assert_eq!(
89658977
trailing_commas
89668978
.parse_sql_statements("CREATE TABLE employees (name text, age int,)")

0 commit comments

Comments
 (0)