You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by if...@apache.org on 2025/04/24 18:16:53 UTC

(datafusion-sqlparser-rs) branch main updated: Add `DECLARE ... CURSOR FOR` support for SQL Server (#1821)

This is an automated email from the ASF dual-hosted git repository.

iffyio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 7703fd0d Add `DECLARE ... CURSOR FOR` support for SQL Server (#1821)
7703fd0d is described below

commit 7703fd0d3180c2e8b347c11394084c3a2458be14
Author: Andrew Harper <an...@veracross.com>
AuthorDate: Thu Apr 24 14:16:49 2025 -0400

    Add `DECLARE ... CURSOR FOR` support for SQL Server (#1821)
---
 src/ast/mod.rs           |  3 ++-
 src/parser/mod.rs        | 22 +++++++++++++++++-----
 tests/sqlparser_mssql.rs |  4 ++++
 3 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index b60ade78..45924579 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -2472,10 +2472,11 @@ impl fmt::Display for DeclareAssignment {
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub enum DeclareType {
-    /// Cursor variable type. e.g. [Snowflake] [PostgreSQL]
+    /// Cursor variable type. e.g. [Snowflake] [PostgreSQL] [MsSql]
     ///
     /// [Snowflake]: https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors#declaring-a-cursor
     /// [PostgreSQL]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
+    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql
     Cursor,
 
     /// Result set variable type. [Snowflake]
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index fe81b599..0546548a 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -6446,7 +6446,7 @@ impl<'a> Parser<'a> {
     /// DECLARE
     // {
     //   { @local_variable [AS] data_type [ = value ] }
-    //   | { @cursor_variable_name CURSOR }
+    //   | { @cursor_variable_name CURSOR [ FOR ] }
     // } [ ,...n ]
     /// ```
     /// [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> {
     /// ```text
     // {
     //   { @local_variable [AS] data_type [ = value ] }
-    //   | { @cursor_variable_name CURSOR }
+    //   | { @cursor_variable_name CURSOR [ FOR ]}
     // } [ ,...n ]
     /// ```
     /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-ver16
     pub fn parse_mssql_declare_stmt(&mut self) -> Result<Declare, ParserError> {
         let name = {
             let ident = self.parse_identifier()?;
-            if !ident.value.starts_with('@') {
+            if !ident.value.starts_with('@')
+                && !matches!(
+                    self.peek_token().token,
+                    Token::Word(w) if w.keyword == Keyword::CURSOR
+                )
+            {
                 Err(ParserError::TokenizerError(
                     "Invalid MsSql variable declaration.".to_string(),
                 ))
@@ -6493,7 +6498,14 @@ impl<'a> Parser<'a> {
             _ => (None, Some(self.parse_data_type()?)),
         };
 
-        let assignment = self.parse_mssql_variable_declaration_expression()?;
+        let (for_query, assignment) = if self.peek_keyword(Keyword::FOR) {
+            self.next_token();
+            let query = Some(self.parse_query()?);
+            (query, None)
+        } else {
+            let assignment = self.parse_mssql_variable_declaration_expression()?;
+            (None, assignment)
+        };
 
         Ok(Declare {
             names: vec![name],
@@ -6504,7 +6516,7 @@ impl<'a> Parser<'a> {
             sensitive: None,
             scroll: None,
             hold: None,
-            for_query: None,
+            for_query,
         })
     }
 
diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs
index b86e1a7d..ef610347 100644
--- a/tests/sqlparser_mssql.rs
+++ b/tests/sqlparser_mssql.rs
@@ -1387,6 +1387,10 @@ fn parse_mssql_declare() {
         ],
         ast
     );
+
+    let declare_cursor_for_select =
+        "DECLARE vend_cursor CURSOR FOR SELECT * FROM Purchasing.Vendor";
+    let _ = ms().verified_stmt(declare_cursor_for_select);
 }
 
 #[test]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org