From dabfe2b87b971443320d8bb88f30a9532ea946b0 Mon Sep 17 00:00:00 2001 From: LucaCappelletti94 Date: Thu, 11 Jun 2026 16:02:48 +0200 Subject: [PATCH] Do not consume statement terminator in unparenthesized option lists --- src/parser/mod.rs | 6 +++++- tests/sqlparser_common.rs | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index a7e641f98..57e8e8ebd 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -20707,7 +20707,11 @@ impl<'a> Parser<'a> { return self.expected_ref(" another option or EOF", self.peek_token_ref()); } } - Token::EOF | Token::SemiColon => break, + Token::EOF => break, + Token::SemiColon => { + self.prev_token(); + break; + } Token::Comma => { delimiter = KeyValueOptionsDelimiter::Comma; continue; diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index b561f8935..e031028b1 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -17942,6 +17942,22 @@ fn parse_create_user() { } } +#[test] +fn key_value_option_statements_do_not_swallow_following_statement() { + // An unparenthesized key-value option list must not swallow the statement + // terminator, otherwise any following statement fails to parse. This covers + // every unparenthesized caller of `parse_key_value_options`: `CREATE USER` + // and both `ALTER USER ... SET` forms. + for sql in [ + "CREATE USER user1; SELECT 1", + "ALTER USER user1 SET x = 'y'; SELECT 1", + "ALTER USER user1 SET TAG t = 'v'; SELECT 1", + ] { + let statements = Parser::parse_sql(&GenericDialect {}, sql).unwrap(); + assert_eq!(statements.len(), 2, "{sql}"); + } +} + #[test] fn parse_drop_stream() { let sql = "DROP STREAM s1";