mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-16 13:04:58 +00:00
MSSQL: Add support for EXEC output and default keywords (#1940)
This commit is contained in:
parent
750a7aa054
commit
9b9ffe450c
4 changed files with 47 additions and 4 deletions
|
@ -4059,6 +4059,12 @@ pub enum Statement {
|
||||||
immediate: bool,
|
immediate: bool,
|
||||||
into: Vec<Ident>,
|
into: Vec<Ident>,
|
||||||
using: Vec<ExprWithAlias>,
|
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
|
/// ```sql
|
||||||
/// PREPARE name [ ( data_type [, ...] ) ] AS statement
|
/// PREPARE name [ ( data_type [, ...] ) ] AS statement
|
||||||
|
@ -5815,6 +5821,8 @@ impl fmt::Display for Statement {
|
||||||
immediate,
|
immediate,
|
||||||
into,
|
into,
|
||||||
using,
|
using,
|
||||||
|
output,
|
||||||
|
default,
|
||||||
} => {
|
} => {
|
||||||
let (open, close) = if *has_parentheses {
|
let (open, close) = if *has_parentheses {
|
||||||
("(", ")")
|
("(", ")")
|
||||||
|
@ -5835,6 +5843,12 @@ impl fmt::Display for Statement {
|
||||||
if !using.is_empty() {
|
if !using.is_empty() {
|
||||||
write!(f, " USING {}", display_comma_separated(using))?;
|
write!(f, " USING {}", display_comma_separated(using))?;
|
||||||
};
|
};
|
||||||
|
if *output {
|
||||||
|
write!(f, " OUTPUT")?;
|
||||||
|
}
|
||||||
|
if *default {
|
||||||
|
write!(f, " DEFAULT")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Statement::Prepare {
|
Statement::Prepare {
|
||||||
|
|
|
@ -15734,10 +15734,11 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
let has_parentheses = self.consume_token(&Token::LParen);
|
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) {
|
let end_token = match (has_parentheses, self.peek_token().token) {
|
||||||
(true, _) => Token::RParen,
|
(true, _) => Token::RParen,
|
||||||
(false, Token::EOF) => Token::EOF,
|
(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,
|
(false, _) => Token::SemiColon,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15759,6 +15760,10 @@ impl<'a> Parser<'a> {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let output = self.parse_keyword(Keyword::OUTPUT);
|
||||||
|
|
||||||
|
let default = self.parse_keyword(Keyword::DEFAULT);
|
||||||
|
|
||||||
Ok(Statement::Execute {
|
Ok(Statement::Execute {
|
||||||
immediate: name.is_none(),
|
immediate: name.is_none(),
|
||||||
name,
|
name,
|
||||||
|
@ -15766,6 +15771,8 @@ impl<'a> Parser<'a> {
|
||||||
has_parentheses,
|
has_parentheses,
|
||||||
into,
|
into,
|
||||||
using,
|
using,
|
||||||
|
output,
|
||||||
|
default,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11393,6 +11393,8 @@ fn parse_execute_stored_procedure() {
|
||||||
immediate: false,
|
immediate: false,
|
||||||
using: vec![],
|
using: vec![],
|
||||||
into: vec![],
|
into: vec![],
|
||||||
|
output: false,
|
||||||
|
default: false,
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
// Microsoft SQL Server does not use parentheses around arguments for EXECUTE
|
// Microsoft SQL Server does not use parentheses around arguments for EXECUTE
|
||||||
|
@ -11407,6 +11409,18 @@ fn parse_execute_stored_procedure() {
|
||||||
),
|
),
|
||||||
expected
|
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]
|
#[test]
|
||||||
|
@ -11425,6 +11439,8 @@ fn parse_execute_immediate() {
|
||||||
into: vec![Ident::new("a")],
|
into: vec![Ident::new("a")],
|
||||||
name: None,
|
name: None,
|
||||||
has_parentheses: false,
|
has_parentheses: false,
|
||||||
|
output: false,
|
||||||
|
default: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let stmt = dialects.verified_stmt("EXECUTE IMMEDIATE 'SELECT 1' INTO a USING 1 AS b");
|
let stmt = dialects.verified_stmt("EXECUTE IMMEDIATE 'SELECT 1' INTO a USING 1 AS b");
|
||||||
|
|
|
@ -1666,7 +1666,9 @@ fn parse_execute() {
|
||||||
has_parentheses: false,
|
has_parentheses: false,
|
||||||
using: vec![],
|
using: vec![],
|
||||||
immediate: false,
|
immediate: false,
|
||||||
into: vec![]
|
into: vec![],
|
||||||
|
output: false,
|
||||||
|
default: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1682,7 +1684,9 @@ fn parse_execute() {
|
||||||
has_parentheses: true,
|
has_parentheses: true,
|
||||||
using: vec![],
|
using: vec![],
|
||||||
immediate: false,
|
immediate: false,
|
||||||
into: vec![]
|
into: vec![],
|
||||||
|
output: false,
|
||||||
|
default: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1719,7 +1723,9 @@ fn parse_execute() {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
immediate: false,
|
immediate: false,
|
||||||
into: vec![]
|
into: vec![],
|
||||||
|
output: false,
|
||||||
|
default: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue