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 10cf7c16 Snowflake: Support dollar quoted comments (#1755)
10cf7c16 is described below

commit 10cf7c164ee0bae8a71e1d8f0af5851b96465692
Author: Aleksei Piianin <[email protected]>
AuthorDate: Sat Mar 15 07:07:07 2025 +0100

    Snowflake: Support dollar quoted comments (#1755)
---
 src/dialect/snowflake.rs     |  5 +----
 src/parser/mod.rs            | 37 ++++++++++++++++++-------------------
 tests/sqlparser_snowflake.rs | 15 +++++++++++++++
 3 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs
index 72252b27..09a0e57c 100644
--- a/src/dialect/snowflake.rs
+++ b/src/dialect/snowflake.rs
@@ -644,10 +644,7 @@ pub fn parse_create_stage(
     // [ comment ]
     if parser.parse_keyword(Keyword::COMMENT) {
         parser.expect_token(&Token::Eq)?;
-        comment = Some(match parser.next_token().token {
-            Token::SingleQuotedString(word) => Ok(word),
-            _ => parser.expected("a comment statement", parser.peek_token()),
-        }?)
+        comment = Some(parser.parse_comment_value()?);
     }
 
     Ok(Statement::CreateStage {
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 864fd579..e4c170ed 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -5451,11 +5451,7 @@ impl<'a> Parser<'a> {
             && self.parse_keyword(Keyword::COMMENT)
         {
             self.expect_token(&Token::Eq)?;
-            let next_token = self.next_token();
-            match next_token.token {
-                Token::SingleQuotedString(str) => Some(str),
-                _ => self.expected("string literal", next_token)?,
-            }
+            Some(self.parse_comment_value()?)
         } else {
             None
         };
@@ -7059,21 +7055,28 @@ impl<'a> Parser<'a> {
     pub fn parse_optional_inline_comment(&mut self) -> 
Result<Option<CommentDef>, ParserError> {
         let comment = if self.parse_keyword(Keyword::COMMENT) {
             let has_eq = self.consume_token(&Token::Eq);
-            let next_token = self.next_token();
-            match next_token.token {
-                Token::SingleQuotedString(str) => Some(if has_eq {
-                    CommentDef::WithEq(str)
-                } else {
-                    CommentDef::WithoutEq(str)
-                }),
-                _ => self.expected("comment", next_token)?,
-            }
+            let comment = self.parse_comment_value()?;
+            Some(if has_eq {
+                CommentDef::WithEq(comment)
+            } else {
+                CommentDef::WithoutEq(comment)
+            })
         } else {
             None
         };
         Ok(comment)
     }
 
+    pub fn parse_comment_value(&mut self) -> Result<String, ParserError> {
+        let next_token = self.next_token();
+        let value = match next_token.token {
+            Token::SingleQuotedString(str) => str,
+            Token::DollarQuotedString(str) => str.value,
+            _ => self.expected("string literal", next_token)?,
+        };
+        Ok(value)
+    }
+
     pub fn parse_optional_procedure_parameters(
         &mut self,
     ) -> Result<Option<Vec<ProcedureParam>>, ParserError> {
@@ -7209,11 +7212,7 @@ impl<'a> Parser<'a> {
         } else if self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) {
             Ok(Some(ColumnOption::NotNull))
         } else if self.parse_keywords(&[Keyword::COMMENT]) {
-            let next_token = self.next_token();
-            match next_token.token {
-                Token::SingleQuotedString(value, ..) => 
Ok(Some(ColumnOption::Comment(value))),
-                _ => self.expected("string", next_token),
-            }
+            Ok(Some(ColumnOption::Comment(self.parse_comment_value()?)))
         } else if self.parse_keyword(Keyword::NULL) {
             Ok(Some(ColumnOption::Null))
         } else if self.parse_keyword(Keyword::DEFAULT) {
diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs
index b1d31e6d..f37b657e 100644
--- a/tests/sqlparser_snowflake.rs
+++ b/tests/sqlparser_snowflake.rs
@@ -976,6 +976,21 @@ fn parse_sf_create_or_replace_with_comment_for_snowflake() 
{
     }
 }
 
+#[test]
+fn parse_sf_create_table_or_view_with_dollar_quoted_comment() {
+    // Snowflake transforms dollar quoted comments into a common comment in 
DDL representation of creation
+    snowflake()
+        .one_statement_parses_to(
+            r#"CREATE OR REPLACE TEMPORARY VIEW foo.bar.baz ("COL_1" COMMENT 
$$comment 1$$) COMMENT = $$view comment$$ AS (SELECT 1)"#,
+            r#"CREATE OR REPLACE TEMPORARY VIEW foo.bar.baz ("COL_1" COMMENT 
'comment 1') COMMENT = 'view comment' AS (SELECT 1)"#
+        );
+
+    snowflake().one_statement_parses_to(
+        r#"CREATE TABLE my_table (a STRING COMMENT $$comment 1$$) COMMENT = 
$$table comment$$"#,
+        r#"CREATE TABLE my_table (a STRING COMMENT 'comment 1') COMMENT = 
'table comment'"#,
+    );
+}
+
 #[test]
 fn test_sf_derived_table_in_parenthesis() {
     // Nesting a subquery in an extra set of parentheses is non-standard,


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to