This is an automated email from the ASF dual-hosted git repository. github-bot pushed a commit to branch gh-readonly-queue/main/pr-2212-6a48f44f99d015a4f7a86275e2521ea2cc45fdae in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
commit 798fbe4b934bd6409839f75e88efb5ca98e5abb9 Author: Guan-Ming (Wesley) Chiu <[email protected]> AuthorDate: Sat Feb 14 15:00:24 2026 +0800 MSSQL: Add support for TRAN shorthand (#2212) Signed-off-by: Guan-Ming (Wesley) Chiu <[email protected]> --- src/ast/mod.rs | 6 +++++- src/dialect/mssql.rs | 8 ++++++-- src/keywords.rs | 1 + src/parser/mod.rs | 15 +++++++++------ tests/sqlparser_mssql.rs | 28 ++++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 4d8c536a..eda28226 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -6390,7 +6390,7 @@ impl Display for CascadeOption { } } -/// Transaction started with [ TRANSACTION | WORK ] +/// Transaction started with [ TRANSACTION | WORK | TRAN ] #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] @@ -6399,6 +6399,9 @@ pub enum BeginTransactionKind { Transaction, /// Alternate `WORK` keyword. Work, + /// MSSQL shorthand `TRAN` keyword. + /// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/begin-transaction-transact-sql> + Tran, } impl Display for BeginTransactionKind { @@ -6406,6 +6409,7 @@ impl Display for BeginTransactionKind { match self { BeginTransactionKind::Transaction => write!(f, "TRANSACTION"), BeginTransactionKind::Work => write!(f, "WORK"), + BeginTransactionKind::Tran => write!(f, "TRAN"), } } } diff --git a/src/dialect/mssql.rs b/src/dialect/mssql.rs index e763165d..a2127f0d 100644 --- a/src/dialect/mssql.rs +++ b/src/dialect/mssql.rs @@ -151,8 +151,12 @@ impl Dialect for MsSqlDialect { let is_block = parser .maybe_parse(|p| { if p.parse_transaction_modifier().is_some() - || p.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]) - .is_some() + || p.parse_one_of_keywords(&[ + Keyword::TRANSACTION, + Keyword::WORK, + Keyword::TRAN, + ]) + .is_some() || matches!(p.peek_token_ref().token, Token::SemiColon | Token::EOF) { p.expected("statement", p.peek_token()) diff --git a/src/keywords.rs b/src/keywords.rs index 7950b191..f1dbcd93 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -1051,6 +1051,7 @@ define_keywords!( TOTP, TRACE, TRAILING, + TRAN, TRANSACTION, TRANSIENT, TRANSLATE, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 7dc75815..1c20014d 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -18142,11 +18142,14 @@ impl<'a> Parser<'a> { /// Parse a 'BEGIN' statement pub fn parse_begin(&mut self) -> Result<Statement, ParserError> { let modifier = self.parse_transaction_modifier(); - let transaction = match self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]) { - Some(Keyword::TRANSACTION) => Some(BeginTransactionKind::Transaction), - Some(Keyword::WORK) => Some(BeginTransactionKind::Work), - _ => None, - }; + let transaction = + match self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK, Keyword::TRAN]) + { + Some(Keyword::TRANSACTION) => Some(BeginTransactionKind::Transaction), + Some(Keyword::WORK) => Some(BeginTransactionKind::Work), + Some(Keyword::TRAN) => Some(BeginTransactionKind::Tran), + _ => None, + }; Ok(Statement::StartTransaction { modes: self.parse_transaction_modes()?, begin: true, @@ -18280,7 +18283,7 @@ impl<'a> Parser<'a> { /// Parse an optional `AND [NO] CHAIN` clause for `COMMIT` and `ROLLBACK` statements pub fn parse_commit_rollback_chain(&mut self) -> Result<bool, ParserError> { - let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]); + let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK, Keyword::TRAN]); if self.parse_keyword(Keyword::AND) { let chain = !self.parse_keyword(Keyword::NO); self.expect_keyword_is(Keyword::CHAIN)?; diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs index 82e6f462..cf9ae898 100644 --- a/tests/sqlparser_mssql.rs +++ b/tests/sqlparser_mssql.rs @@ -2665,3 +2665,31 @@ fn parse_mssql_begin_end_block() { _ => panic!("Expected StartTransaction, got: {stmt:?}"), } } + +/// MSSQL supports `TRAN` as shorthand for `TRANSACTION`. +/// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/begin-transaction-transact-sql> +#[test] +fn parse_mssql_tran_shorthand() { + // BEGIN TRAN + let sql = "BEGIN TRAN"; + let stmt = ms().verified_stmt(sql); + match &stmt { + Statement::StartTransaction { + begin, + transaction, + has_end_keyword, + .. + } => { + assert!(begin); + assert_eq!(*transaction, Some(BeginTransactionKind::Tran)); + assert!(!has_end_keyword); + } + _ => panic!("Expected StartTransaction, got: {stmt:?}"), + } + + // COMMIT TRAN normalizes to COMMIT (same as COMMIT TRANSACTION) + ms().one_statement_parses_to("COMMIT TRAN", "COMMIT"); + + // ROLLBACK TRAN normalizes to ROLLBACK (same as ROLLBACK TRANSACTION) + ms().one_statement_parses_to("ROLLBACK TRAN", "ROLLBACK"); +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
