Skip to content

Commit 664e44b

Browse files
committed
create an error implicitly later …
by consuming the keywords at most once
1 parent dae7829 commit 664e44b

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

src/parser.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,21 +1022,13 @@ impl Parser {
10221022
let referred_columns = self.parse_parenthesized_column_list(Optional)?;
10231023
let mut on_delete = None;
10241024
let mut on_update = None;
1025-
while self.parse_keyword("ON") {
1026-
if self.parse_keyword("DELETE") {
1027-
if on_delete == None {
1028-
on_delete = Some(self.parse_referential_action()?);
1029-
} else {
1030-
return self
1031-
.expected("ON DELETE option not more than once", self.peek_token());
1032-
}
1033-
} else if self.parse_keyword("UPDATE") {
1034-
if on_update == None {
1035-
on_update = Some(self.parse_referential_action()?);
1036-
} else {
1037-
return self
1038-
.expected("ON UPDATE option not more than once", self.peek_token());
1039-
}
1025+
loop {
1026+
if on_delete.is_none() && self.parse_keywords(vec!["ON", "DELETE"]) {
1027+
on_delete = Some(self.parse_referential_action()?);
1028+
} else if on_update.is_none() && self.parse_keywords(vec!["ON", "UPDATE"]) {
1029+
on_update = Some(self.parse_referential_action()?);
1030+
} else {
1031+
break;
10401032
}
10411033
}
10421034
ColumnOption::ForeignKey {

tests/sqlparser_common.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,32 @@ fn parse_create_table() {
10151015
.contains("Expected column option, found: GARBAGE"));
10161016
}
10171017

1018+
#[test]
1019+
fn parse_create_table_with_multiple_on_delete_fails() {
1020+
parse_sql_statements(
1021+
"\
1022+
create table X (\
1023+
y_id int references Y (id) \
1024+
on delete cascade on update cascade on delete no action\
1025+
)",
1026+
)
1027+
.expect_err("should have failed");
1028+
}
1029+
1030+
#[test]
1031+
fn parse_create_table_with_on_delete_on_update_2in_any_order() -> Result<(), ParserError> {
1032+
let sql = |options: &str| -> String {
1033+
format!("create table X (y_id int references Y (id) {})", options)
1034+
};
1035+
1036+
parse_sql_statements(&sql("on update cascade on delete no action"))?;
1037+
parse_sql_statements(&sql("on delete cascade on update cascade"))?;
1038+
parse_sql_statements(&sql("on update no action"))?;
1039+
parse_sql_statements(&sql("on delete restrict"))?;
1040+
1041+
Ok(())
1042+
}
1043+
10181044
#[test]
10191045
fn parse_create_table_with_options() {
10201046
let sql = "CREATE TABLE t (c int) WITH (foo = 'bar', a = 123)";

0 commit comments

Comments
 (0)