diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 08ce9f1cc..d0a774b59 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -18780,7 +18780,7 @@ impl<'a> Parser<'a> { return self.expected(" another option or EOF", self.peek_token()); } } - Token::EOF => break, + Token::EOF | Token::SemiColon => break, Token::Comma => { delimiter = KeyValueOptionsDelimiter::Comma; continue; @@ -18792,7 +18792,12 @@ impl<'a> Parser<'a> { self.prev_token(); break; } - _ => return self.expected("another option, EOF, Comma or ')'", self.peek_token()), + _ => { + return self.expected( + "another option, EOF, SemiColon, Comma or ')'", + self.peek_token(), + ) + } }; } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 4c3babd65..208a56e23 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -18052,3 +18052,11 @@ fn parse_overlap_as_bool_and() { let dialects = all_dialects_where(|d| d.supports_double_ampersand_operator()); dialects.one_statement_parses_to("SELECT x && y", "SELECT x AND y"); } + +#[test] +fn test_parse_key_value_options_trailing_semicolon() { + one_statement_parses_to( + "CREATE USER u1 option1='value1' option2='value2';", + "CREATE USER u1 option1='value1' option2='value2'", + ); +}