MSSQL: Add support for EXEC output and default keywords (#1940)

This commit is contained in:
Yoav Cohen 2025-07-14 10:19:28 +02:00 committed by GitHub
parent 750a7aa054
commit 9b9ffe450c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 4 deletions

View file

@ -4059,6 +4059,12 @@ pub enum Statement {
immediate: bool,
into: Vec<Ident>,
using: Vec<ExprWithAlias>,
/// Whether the last parameter is the return value of the procedure
/// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#output>
output: bool,
/// Whether to invoke the procedure with the default parameter values
/// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#default>
default: bool,
},
/// ```sql
/// PREPARE name [ ( data_type [, ...] ) ] AS statement
@ -5815,6 +5821,8 @@ impl fmt::Display for Statement {
immediate,
into,
using,
output,
default,
} => {
let (open, close) = if *has_parentheses {
("(", ")")
@ -5835,6 +5843,12 @@ impl fmt::Display for Statement {
if !using.is_empty() {
write!(f, " USING {}", display_comma_separated(using))?;
};
if *output {
write!(f, " OUTPUT")?;
}
if *default {
write!(f, " DEFAULT")?;
}
Ok(())
}
Statement::Prepare {

View file

@ -15734,10 +15734,11 @@ impl<'a> Parser<'a> {
let has_parentheses = self.consume_token(&Token::LParen);
let end_kws = &[Keyword::USING, Keyword::OUTPUT, Keyword::DEFAULT];
let end_token = match (has_parentheses, self.peek_token().token) {
(true, _) => Token::RParen,
(false, Token::EOF) => Token::EOF,
(false, Token::Word(w)) if w.keyword == Keyword::USING => Token::Word(w),
(false, Token::Word(w)) if end_kws.contains(&w.keyword) => Token::Word(w),
(false, _) => Token::SemiColon,
};
@ -15759,6 +15760,10 @@ impl<'a> Parser<'a> {
vec![]
};
let output = self.parse_keyword(Keyword::OUTPUT);
let default = self.parse_keyword(Keyword::DEFAULT);
Ok(Statement::Execute {
immediate: name.is_none(),
name,
@ -15766,6 +15771,8 @@ impl<'a> Parser<'a> {
has_parentheses,
into,
using,
output,
default,
})
}

View file

@ -11393,6 +11393,8 @@ fn parse_execute_stored_procedure() {
immediate: false,
using: vec![],
into: vec![],
output: false,
default: false,
};
assert_eq!(
// Microsoft SQL Server does not use parentheses around arguments for EXECUTE
@ -11407,6 +11409,18 @@ fn parse_execute_stored_procedure() {
),
expected
);
match ms_and_generic().verified_stmt("EXECUTE dbo.proc1 @ReturnVal = @X OUTPUT") {
Statement::Execute { output, .. } => {
assert!(output);
}
_ => unreachable!(),
}
match ms_and_generic().verified_stmt("EXECUTE dbo.proc1 DEFAULT") {
Statement::Execute { default, .. } => {
assert!(default);
}
_ => unreachable!(),
}
}
#[test]
@ -11425,6 +11439,8 @@ fn parse_execute_immediate() {
into: vec![Ident::new("a")],
name: None,
has_parentheses: false,
output: false,
default: false,
};
let stmt = dialects.verified_stmt("EXECUTE IMMEDIATE 'SELECT 1' INTO a USING 1 AS b");

View file

@ -1666,7 +1666,9 @@ fn parse_execute() {
has_parentheses: false,
using: vec![],
immediate: false,
into: vec![]
into: vec![],
output: false,
default: false,
}
);
@ -1682,7 +1684,9 @@ fn parse_execute() {
has_parentheses: true,
using: vec![],
immediate: false,
into: vec![]
into: vec![],
output: false,
default: false,
}
);
@ -1719,7 +1723,9 @@ fn parse_execute() {
},
],
immediate: false,
into: vec![]
into: vec![],
output: false,
default: false,
}
);
}