Skip to content

Commit 6ac616d

Browse files
yoavcloudayman-sigma
authored andcommitted
MSSQL: Add support for EXEC output and default keywords (apache#1940)
1 parent 45e4846 commit 6ac616d

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

src/ast/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4088,6 +4088,12 @@ pub enum Statement {
40884088
immediate: bool,
40894089
into: Vec<Ident>,
40904090
using: Vec<ExprWithAlias>,
4091+
/// Whether the last parameter is the return value of the procedure
4092+
/// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#output>
4093+
output: bool,
4094+
/// Whether to invoke the procedure with the default parameter values
4095+
/// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#default>
4096+
default: bool,
40914097
},
40924098
/// ```sql
40934099
/// PREPARE name [ ( data_type [, ...] ) ] AS statement
@@ -5844,6 +5850,8 @@ impl fmt::Display for Statement {
58445850
immediate,
58455851
into,
58465852
using,
5853+
output,
5854+
default,
58475855
} => {
58485856
let (open, close) = if *has_parentheses {
58495857
("(", ")")
@@ -5864,6 +5872,12 @@ impl fmt::Display for Statement {
58645872
if !using.is_empty() {
58655873
write!(f, " USING {}", display_comma_separated(using))?;
58665874
};
5875+
if *output {
5876+
write!(f, " OUTPUT")?;
5877+
}
5878+
if *default {
5879+
write!(f, " DEFAULT")?;
5880+
}
58675881
Ok(())
58685882
}
58695883
Statement::Prepare {

src/parser/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15766,10 +15766,11 @@ impl<'a> Parser<'a> {
1576615766

1576715767
let has_parentheses = self.consume_token(&Token::LParen);
1576815768

15769+
let end_kws = &[Keyword::USING, Keyword::OUTPUT, Keyword::DEFAULT];
1576915770
let end_token = match (has_parentheses, self.peek_token().token) {
1577015771
(true, _) => Token::RParen,
1577115772
(false, Token::EOF) => Token::EOF,
15772-
(false, Token::Word(w)) if w.keyword == Keyword::USING => Token::Word(w),
15773+
(false, Token::Word(w)) if end_kws.contains(&w.keyword) => Token::Word(w),
1577315774
(false, _) => Token::SemiColon,
1577415775
};
1577515776

@@ -15791,13 +15792,19 @@ impl<'a> Parser<'a> {
1579115792
vec![]
1579215793
};
1579315794

15795+
let output = self.parse_keyword(Keyword::OUTPUT);
15796+
15797+
let default = self.parse_keyword(Keyword::DEFAULT);
15798+
1579415799
Ok(Statement::Execute {
1579515800
immediate: name.is_none(),
1579615801
name,
1579715802
parameters,
1579815803
has_parentheses,
1579915804
into,
1580015805
using,
15806+
output,
15807+
default,
1580115808
})
1580215809
}
1580315810

tests/sqlparser_common.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11396,6 +11396,8 @@ fn parse_execute_stored_procedure() {
1139611396
immediate: false,
1139711397
using: vec![],
1139811398
into: vec![],
11399+
output: false,
11400+
default: false,
1139911401
};
1140011402
assert_eq!(
1140111403
// Microsoft SQL Server does not use parentheses around arguments for EXECUTE
@@ -11410,6 +11412,18 @@ fn parse_execute_stored_procedure() {
1141011412
),
1141111413
expected
1141211414
);
11415+
match ms_and_generic().verified_stmt("EXECUTE dbo.proc1 @ReturnVal = @X OUTPUT") {
11416+
Statement::Execute { output, .. } => {
11417+
assert!(output);
11418+
}
11419+
_ => unreachable!(),
11420+
}
11421+
match ms_and_generic().verified_stmt("EXECUTE dbo.proc1 DEFAULT") {
11422+
Statement::Execute { default, .. } => {
11423+
assert!(default);
11424+
}
11425+
_ => unreachable!(),
11426+
}
1141311427
}
1141411428

1141511429
#[test]
@@ -11428,6 +11442,8 @@ fn parse_execute_immediate() {
1142811442
into: vec![Ident::new("a")],
1142911443
name: None,
1143011444
has_parentheses: false,
11445+
output: false,
11446+
default: false,
1143111447
};
1143211448

1143311449
let stmt = dialects.verified_stmt("EXECUTE IMMEDIATE 'SELECT 1' INTO a USING 1 AS b");

tests/sqlparser_postgres.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,9 @@ fn parse_execute() {
16661666
has_parentheses: false,
16671667
using: vec![],
16681668
immediate: false,
1669-
into: vec![]
1669+
into: vec![],
1670+
output: false,
1671+
default: false,
16701672
}
16711673
);
16721674

@@ -1682,7 +1684,9 @@ fn parse_execute() {
16821684
has_parentheses: true,
16831685
using: vec![],
16841686
immediate: false,
1685-
into: vec![]
1687+
into: vec![],
1688+
output: false,
1689+
default: false,
16861690
}
16871691
);
16881692

@@ -1719,7 +1723,9 @@ fn parse_execute() {
17191723
},
17201724
],
17211725
immediate: false,
1722-
into: vec![]
1726+
into: vec![],
1727+
output: false,
1728+
default: false,
17231729
}
17241730
);
17251731
}

0 commit comments

Comments
 (0)