From 334264f6730a1ff578e324f4223f9469a023eb68 Mon Sep 17 00:00:00 2001 From: Yoav Cohen Date: Thu, 25 Dec 2025 14:58:49 +0100 Subject: [PATCH 1/3] Key Value Options: add support for trailing semicolon --- src/parser/mod.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 08ce9f1cc..a9754b574 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,7 @@ 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()), }; } @@ -19677,4 +19677,11 @@ mod tests { assert!(Parser::parse_sql(&GenericDialect, &sql).is_err()); } } + + #[test] + fn test_key_value_options_trailing_semicolon() { + let sql = "CREATE USER u1 option1 = 'value1' option2 = 'value2';"; + let ast = Parser::parse_sql(&GenericDialect, sql); + assert!(ast.is_ok()); + } } From 5c96e5638cba26f2f99a93f0abf6cf5e1d75689a Mon Sep 17 00:00:00 2001 From: Yoav Cohen Date: Thu, 25 Dec 2025 15:05:53 +0100 Subject: [PATCH 2/3] Key Value Options: add support for trailing semicolon --- src/parser/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index a9754b574..0eb5388a8 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -18792,7 +18792,12 @@ impl<'a> Parser<'a> { self.prev_token(); break; } - _ => return self.expected("another option, EOF, SemiColon, Comma or ')'", self.peek_token()), + _ => { + return self.expected( + "another option, EOF, SemiColon, Comma or ')'", + self.peek_token(), + ) + } }; } From 0814850053fe3981ee8fb8a5c3f582d9612ea81a Mon Sep 17 00:00:00 2001 From: Yoav Cohen Date: Fri, 9 Jan 2026 12:37:09 +0100 Subject: [PATCH 3/3] Code review comments --- src/parser/mod.rs | 7 ------- tests/sqlparser_common.rs | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 0eb5388a8..d0a774b59 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -19682,11 +19682,4 @@ mod tests { assert!(Parser::parse_sql(&GenericDialect, &sql).is_err()); } } - - #[test] - fn test_key_value_options_trailing_semicolon() { - let sql = "CREATE USER u1 option1 = 'value1' option2 = 'value2';"; - let ast = Parser::parse_sql(&GenericDialect, sql); - assert!(ast.is_ok()); - } } 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'", + ); +}