Skip to content

Commit 608f091

Browse files
committed
Add DECLARE ... CURSOR FOR support for SQL Server (apache#1821)
1 parent fb41bfc commit 608f091

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
@@ -6489,7 +6489,7 @@ impl<'a> Parser<'a> {
64896489
/// DECLARE
64906490
// {
64916491
// { @local_variable [AS] data_type [ = value ] }
6492-
// | { @cursor_variable_name CURSOR }
6492+
// | { @cursor_variable_name CURSOR [ FOR ] }
64936493
// } [ ,...n ]
64946494
/// ```
64956495
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-ver16
@@ -6505,14 +6505,19 @@ impl<'a> Parser<'a> {
65056505
/// ```text
65066506
// {
65076507
// { @local_variable [AS] data_type [ = value ] }
6508-
// | { @cursor_variable_name CURSOR }
6508+
// | { @cursor_variable_name CURSOR [ FOR ]}
65096509
// } [ ,...n ]
65106510
/// ```
65116511
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-ver16
65126512
pub fn parse_mssql_declare_stmt(&mut self) -> Result<Declare, ParserError> {
65136513
let name = {
65146514
let ident = self.parse_identifier()?;
6515-
if !ident.value.starts_with('@') {
6515+
if !ident.value.starts_with('@')
6516+
&& !matches!(
6517+
self.peek_token().token,
6518+
Token::Word(w) if w.keyword == Keyword::CURSOR
6519+
)
6520+
{
65166521
Err(ParserError::TokenizerError(
65176522
"Invalid MsSql variable declaration.".to_string(),
65186523
))
@@ -6536,7 +6541,14 @@ impl<'a> Parser<'a> {
65366541
_ => (None, Some(self.parse_data_type()?)),
65376542
};
65386543

6539-
let assignment = self.parse_mssql_variable_declaration_expression()?;
6544+
let (for_query, assignment) = if self.peek_keyword(Keyword::FOR) {
6545+
self.next_token();
6546+
let query = Some(self.parse_query()?);
6547+
(query, None)
6548+
} else {
6549+
let assignment = self.parse_mssql_variable_declaration_expression()?;
6550+
(None, assignment)
6551+
};
65406552

65416553
Ok(Declare {
65426554
names: vec![name],
@@ -6547,7 +6559,7 @@ impl<'a> Parser<'a> {
65476559
sensitive: None,
65486560
scroll: None,
65496561
hold: None,
6550-
for_query: None,
6562+
for_query,
65516563
})
65526564
}
65536565

tests/sqlparser_mssql.rs

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

13931397
#[test]

0 commit comments

Comments
 (0)