Skip to content

Commit 7703fd0

Browse files
authored
Add DECLARE ... CURSOR FOR support for SQL Server (#1821)
1 parent 87d1907 commit 7703fd0

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

src/ast/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2472,10 +2472,11 @@ impl fmt::Display for DeclareAssignment {
24722472
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24732473
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
24742474
pub enum DeclareType {
2475-
/// Cursor variable type. e.g. [Snowflake] [PostgreSQL]
2475+
/// Cursor variable type. e.g. [Snowflake] [PostgreSQL] [MsSql]
24762476
///
24772477
/// [Snowflake]: https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors#declaring-a-cursor
24782478
/// [PostgreSQL]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
2479+
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql
24792480
Cursor,
24802481

24812482
/// Result set variable type. [Snowflake]

src/parser/mod.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -6446,7 +6446,7 @@ impl<'a> Parser<'a> {
64466446
/// DECLARE
64476447
// {
64486448
// { @local_variable [AS] data_type [ = value ] }
6449-
// | { @cursor_variable_name CURSOR }
6449+
// | { @cursor_variable_name CURSOR [ FOR ] }
64506450
// } [ ,...n ]
64516451
/// ```
64526452
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-ver16
@@ -6462,14 +6462,19 @@ impl<'a> Parser<'a> {
64626462
/// ```text
64636463
// {
64646464
// { @local_variable [AS] data_type [ = value ] }
6465-
// | { @cursor_variable_name CURSOR }
6465+
// | { @cursor_variable_name CURSOR [ FOR ]}
64666466
// } [ ,...n ]
64676467
/// ```
64686468
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-ver16
64696469
pub fn parse_mssql_declare_stmt(&mut self) -> Result<Declare, ParserError> {
64706470
let name = {
64716471
let ident = self.parse_identifier()?;
6472-
if !ident.value.starts_with('@') {
6472+
if !ident.value.starts_with('@')
6473+
&& !matches!(
6474+
self.peek_token().token,
6475+
Token::Word(w) if w.keyword == Keyword::CURSOR
6476+
)
6477+
{
64736478
Err(ParserError::TokenizerError(
64746479
"Invalid MsSql variable declaration.".to_string(),
64756480
))
@@ -6493,7 +6498,14 @@ impl<'a> Parser<'a> {
64936498
_ => (None, Some(self.parse_data_type()?)),
64946499
};
64956500

6496-
let assignment = self.parse_mssql_variable_declaration_expression()?;
6501+
let (for_query, assignment) = if self.peek_keyword(Keyword::FOR) {
6502+
self.next_token();
6503+
let query = Some(self.parse_query()?);
6504+
(query, None)
6505+
} else {
6506+
let assignment = self.parse_mssql_variable_declaration_expression()?;
6507+
(None, assignment)
6508+
};
64976509

64986510
Ok(Declare {
64996511
names: vec![name],
@@ -6504,7 +6516,7 @@ impl<'a> Parser<'a> {
65046516
sensitive: None,
65056517
scroll: None,
65066518
hold: None,
6507-
for_query: None,
6519+
for_query,
65086520
})
65096521
}
65106522

tests/sqlparser_mssql.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,10 @@ fn parse_mssql_declare() {
13871387
],
13881388
ast
13891389
);
1390+
1391+
let declare_cursor_for_select =
1392+
"DECLARE vend_cursor CURSOR FOR SELECT * FROM Purchasing.Vendor";
1393+
let _ = ms().verified_stmt(declare_cursor_for_select);
13901394
}
13911395

13921396
#[test]

0 commit comments

Comments
 (0)