From 193e25373095c6757568217a934d31cbf426736e Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Wed, 4 Mar 2026 14:09:46 -0800 Subject: [PATCH 1/2] Fixed transaction handling for snowflake --- src/dialect/snowflake.rs | 12 ++++++++++++ tests/sqlparser_snowflake.rs | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs index f756c4159..08690e063 100644 --- a/src/dialect/snowflake.rs +++ b/src/dialect/snowflake.rs @@ -247,6 +247,18 @@ impl Dialect for SnowflakeDialect { fn parse_statement(&self, parser: &mut Parser) -> Option> { if parser.parse_keyword(Keyword::BEGIN) { + // Snowflake supports both `BEGIN TRANSACTION` and `BEGIN ... END` blocks. + // If the next keyword indicates a transaction statement, let the + // standard parse_begin() handle it. + if parser.peek_keyword(Keyword::TRANSACTION) + || parser.peek_keyword(Keyword::WORK) + || parser.peek_keyword(Keyword::NAME) + || parser.peek_token().token == Token::SemiColon + || parser.peek_token().token == Token::EOF + { + parser.prev_token(); + return None; + } return Some(parser.parse_begin_exception_end()); } diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index c51cf3bdf..2d34880ca 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -4610,6 +4610,24 @@ END assert_eq!(2, exception[1].statements.len()); } +#[test] +fn test_begin_transaction() { + snowflake().verified_stmt("BEGIN TRANSACTION"); + snowflake().verified_stmt("BEGIN WORK"); + + // BEGIN TRANSACTION with statements + let stmts = snowflake() + .parse_sql_statements("BEGIN TRANSACTION; DROP TABLE IF EXISTS bla; COMMIT") + .unwrap(); + assert_eq!(3, stmts.len()); + + // Bare BEGIN (no TRANSACTION keyword) with statements + let stmts = snowflake() + .parse_sql_statements("BEGIN; DROP TABLE IF EXISTS bla; COMMIT") + .unwrap(); + assert_eq!(3, stmts.len()); +} + #[test] fn test_snowflake_fetch_clause_syntax() { let canonical = "SELECT c1 FROM fetch_test FETCH FIRST 2 ROWS ONLY"; From 91df9a63a8b690129b45efe058af108c4382ec71 Mon Sep 17 00:00:00 2001 From: Andriy Romanov Date: Thu, 5 Mar 2026 12:33:13 -0800 Subject: [PATCH 2/2] Fixes based on comments --- src/dialect/snowflake.rs | 9 ++++----- tests/sqlparser_snowflake.rs | 3 +++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs index 08690e063..6c160a9dd 100644 --- a/src/dialect/snowflake.rs +++ b/src/dialect/snowflake.rs @@ -250,11 +250,10 @@ impl Dialect for SnowflakeDialect { // Snowflake supports both `BEGIN TRANSACTION` and `BEGIN ... END` blocks. // If the next keyword indicates a transaction statement, let the // standard parse_begin() handle it. - if parser.peek_keyword(Keyword::TRANSACTION) - || parser.peek_keyword(Keyword::WORK) - || parser.peek_keyword(Keyword::NAME) - || parser.peek_token().token == Token::SemiColon - || parser.peek_token().token == Token::EOF + if parser + .peek_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK, Keyword::NAME]) + .is_some() + || matches!(parser.peek_token_ref().token, Token::SemiColon | Token::EOF) { parser.prev_token(); return None; diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index 2d34880ca..022c644a4 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -4626,6 +4626,9 @@ fn test_begin_transaction() { .parse_sql_statements("BEGIN; DROP TABLE IF EXISTS bla; COMMIT") .unwrap(); assert_eq!(3, stmts.len()); + + // Bare BEGIN at EOF (no semicolon, no TRANSACTION keyword) + snowflake().verified_stmt("BEGIN"); } #[test]