Skip to content

Commit 798fbe4

Browse files
authored
MSSQL: Add support for TRAN shorthand (#2212)
Signed-off-by: Guan-Ming (Wesley) Chiu <105915352+guan404ming@users.noreply.github.com>
1 parent 6a48f44 commit 798fbe4

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
@@ -6390,7 +6390,7 @@ impl Display for CascadeOption {
63906390
}
63916391
}
63926392

6393-
/// Transaction started with [ TRANSACTION | WORK ]
6393+
/// Transaction started with [ TRANSACTION | WORK | TRAN ]
63946394
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
63956395
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
63966396
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
@@ -6399,13 +6399,17 @@ pub enum BeginTransactionKind {
63996399
Transaction,
64006400
/// Alternate `WORK` keyword.
64016401
Work,
6402+
/// MSSQL shorthand `TRAN` keyword.
6403+
/// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/begin-transaction-transact-sql>
6404+
Tran,
64026405
}
64036406

64046407
impl Display for BeginTransactionKind {
64056408
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64066409
match self {
64076410
BeginTransactionKind::Transaction => write!(f, "TRANSACTION"),
64086411
BeginTransactionKind::Work => write!(f, "WORK"),
6412+
BeginTransactionKind::Tran => write!(f, "TRAN"),
64096413
}
64106414
}
64116415
}

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
@@ -1051,6 +1051,7 @@ define_keywords!(
10511051
TOTP,
10521052
TRACE,
10531053
TRAILING,
1054+
TRAN,
10541055
TRANSACTION,
10551056
TRANSIENT,
10561057
TRANSLATE,

src/parser/mod.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18142,11 +18142,14 @@ impl<'a> Parser<'a> {
1814218142
/// Parse a 'BEGIN' statement
1814318143
pub fn parse_begin(&mut self) -> Result<Statement, ParserError> {
1814418144
let modifier = self.parse_transaction_modifier();
18145-
let transaction = match self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]) {
18146-
Some(Keyword::TRANSACTION) => Some(BeginTransactionKind::Transaction),
18147-
Some(Keyword::WORK) => Some(BeginTransactionKind::Work),
18148-
_ => None,
18149-
};
18145+
let transaction =
18146+
match self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK, Keyword::TRAN])
18147+
{
18148+
Some(Keyword::TRANSACTION) => Some(BeginTransactionKind::Transaction),
18149+
Some(Keyword::WORK) => Some(BeginTransactionKind::Work),
18150+
Some(Keyword::TRAN) => Some(BeginTransactionKind::Tran),
18151+
_ => None,
18152+
};
1815018153
Ok(Statement::StartTransaction {
1815118154
modes: self.parse_transaction_modes()?,
1815218155
begin: true,
@@ -18280,7 +18283,7 @@ impl<'a> Parser<'a> {
1828018283

1828118284
/// Parse an optional `AND [NO] CHAIN` clause for `COMMIT` and `ROLLBACK` statements
1828218285
pub fn parse_commit_rollback_chain(&mut self) -> Result<bool, ParserError> {
18283-
let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]);
18286+
let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK, Keyword::TRAN]);
1828418287
if self.parse_keyword(Keyword::AND) {
1828518288
let chain = !self.parse_keyword(Keyword::NO);
1828618289
self.expect_keyword_is(Keyword::CHAIN)?;

tests/sqlparser_mssql.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2665,3 +2665,31 @@ fn parse_mssql_begin_end_block() {
26652665
_ => panic!("Expected StartTransaction, got: {stmt:?}"),
26662666
}
26672667
}
2668+
2669+
/// MSSQL supports `TRAN` as shorthand for `TRANSACTION`.
2670+
/// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/begin-transaction-transact-sql>
2671+
#[test]
2672+
fn parse_mssql_tran_shorthand() {
2673+
// BEGIN TRAN
2674+
let sql = "BEGIN TRAN";
2675+
let stmt = ms().verified_stmt(sql);
2676+
match &stmt {
2677+
Statement::StartTransaction {
2678+
begin,
2679+
transaction,
2680+
has_end_keyword,
2681+
..
2682+
} => {
2683+
assert!(begin);
2684+
assert_eq!(*transaction, Some(BeginTransactionKind::Tran));
2685+
assert!(!has_end_keyword);
2686+
}
2687+
_ => panic!("Expected StartTransaction, got: {stmt:?}"),
2688+
}
2689+
2690+
// COMMIT TRAN normalizes to COMMIT (same as COMMIT TRANSACTION)
2691+
ms().one_statement_parses_to("COMMIT TRAN", "COMMIT");
2692+
2693+
// ROLLBACK TRAN normalizes to ROLLBACK (same as ROLLBACK TRANSACTION)
2694+
ms().one_statement_parses_to("ROLLBACK TRAN", "ROLLBACK");
2695+
}

0 commit comments

Comments
 (0)