Skip to content

Commit dd61f05

Browse files
committed
MSSQL: Add support for TRAN shorthand
Signed-off-by: Guan-Ming (Wesley) Chiu <105915352+guan404ming@users.noreply.github.com>
1 parent 329a94c commit dd61f05

File tree

5 files changed

+49
-9
lines changed

5 files changed

+49
-9
lines changed

src/ast/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6298,7 +6298,7 @@ impl Display for CascadeOption {
62986298
}
62996299
}
63006300

6301-
/// Transaction started with [ TRANSACTION | WORK ]
6301+
/// Transaction started with [ TRANSACTION | WORK | TRAN ]
63026302
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
63036303
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
63046304
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
@@ -6307,13 +6307,17 @@ pub enum BeginTransactionKind {
63076307
Transaction,
63086308
/// Alternate `WORK` keyword.
63096309
Work,
6310+
/// MSSQL shorthand `TRAN` keyword.
6311+
/// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/begin-transaction-transact-sql>
6312+
Tran,
63106313
}
63116314

63126315
impl Display for BeginTransactionKind {
63136316
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63146317
match self {
63156318
BeginTransactionKind::Transaction => write!(f, "TRANSACTION"),
63166319
BeginTransactionKind::Work => write!(f, "WORK"),
6320+
BeginTransactionKind::Tran => write!(f, "TRAN"),
63176321
}
63186322
}
63196323
}

src/dialect/mssql.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,12 @@ impl Dialect for MsSqlDialect {
151151
let is_block = parser
152152
.maybe_parse(|p| {
153153
if p.parse_transaction_modifier().is_some()
154-
|| p.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK])
155-
.is_some()
154+
|| p.parse_one_of_keywords(&[
155+
Keyword::TRANSACTION,
156+
Keyword::WORK,
157+
Keyword::TRAN,
158+
])
159+
.is_some()
156160
|| matches!(p.peek_token_ref().token, Token::SemiColon | Token::EOF)
157161
{
158162
p.expected("statement", p.peek_token())

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ define_keywords!(
10501050
TOTP,
10511051
TRACE,
10521052
TRAILING,
1053+
TRAN,
10531054
TRANSACTION,
10541055
TRANSIENT,
10551056
TRANSLATE,

src/parser/mod.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18067,11 +18067,14 @@ impl<'a> Parser<'a> {
1806718067
/// Parse a 'BEGIN' statement
1806818068
pub fn parse_begin(&mut self) -> Result<Statement, ParserError> {
1806918069
let modifier = self.parse_transaction_modifier();
18070-
let transaction = match self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]) {
18071-
Some(Keyword::TRANSACTION) => Some(BeginTransactionKind::Transaction),
18072-
Some(Keyword::WORK) => Some(BeginTransactionKind::Work),
18073-
_ => None,
18074-
};
18070+
let transaction =
18071+
match self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK, Keyword::TRAN])
18072+
{
18073+
Some(Keyword::TRANSACTION) => Some(BeginTransactionKind::Transaction),
18074+
Some(Keyword::WORK) => Some(BeginTransactionKind::Work),
18075+
Some(Keyword::TRAN) => Some(BeginTransactionKind::Tran),
18076+
_ => None,
18077+
};
1807518078
Ok(Statement::StartTransaction {
1807618079
modes: self.parse_transaction_modes()?,
1807718080
begin: true,
@@ -18205,7 +18208,7 @@ impl<'a> Parser<'a> {
1820518208

1820618209
/// Parse an optional `AND [NO] CHAIN` clause for `COMMIT` and `ROLLBACK` statements
1820718210
pub fn parse_commit_rollback_chain(&mut self) -> Result<bool, ParserError> {
18208-
let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]);
18211+
let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK, Keyword::TRAN]);
1820918212
if self.parse_keyword(Keyword::AND) {
1821018213
let chain = !self.parse_keyword(Keyword::NO);
1821118214
self.expect_keyword_is(Keyword::CHAIN)?;

tests/sqlparser_mssql.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,3 +2628,31 @@ fn parse_mssql_begin_end_block() {
26282628
_ => panic!("Expected StartTransaction, got: {stmt:?}"),
26292629
}
26302630
}
2631+
2632+
/// MSSQL supports `TRAN` as shorthand for `TRANSACTION`.
2633+
/// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/begin-transaction-transact-sql>
2634+
#[test]
2635+
fn parse_mssql_tran_shorthand() {
2636+
// BEGIN TRAN
2637+
let sql = "BEGIN TRAN";
2638+
let stmt = ms().verified_stmt(sql);
2639+
match &stmt {
2640+
Statement::StartTransaction {
2641+
begin,
2642+
transaction,
2643+
has_end_keyword,
2644+
..
2645+
} => {
2646+
assert!(begin);
2647+
assert_eq!(*transaction, Some(BeginTransactionKind::Tran));
2648+
assert!(!has_end_keyword);
2649+
}
2650+
_ => panic!("Expected StartTransaction, got: {stmt:?}"),
2651+
}
2652+
2653+
// COMMIT TRAN normalizes to COMMIT (same as COMMIT TRANSACTION)
2654+
ms().one_statement_parses_to("COMMIT TRAN", "COMMIT");
2655+
2656+
// ROLLBACK TRAN normalizes to ROLLBACK (same as ROLLBACK TRANSACTION)
2657+
ms().one_statement_parses_to("ROLLBACK TRAN", "ROLLBACK");
2658+
}

0 commit comments

Comments
 (0)