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

alamb 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 84348d48 Snowflake: support of views column comment (#1441)
84348d48 is described below

commit 84348d483eafaf4b608c9869ab03984852c7a4d2
Author: Aleksei Piianin <[email protected]>
AuthorDate: Mon Oct 7 22:20:23 2024 +0200

    Snowflake: support of views column comment (#1441)
---
 src/ast/ddl.rs               |  9 +++------
 src/ast/mod.rs               | 12 ++++++------
 src/parser/mod.rs            |  9 ++++++---
 tests/sqlparser_bigquery.rs  |  4 ++--
 tests/sqlparser_snowflake.rs | 39 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 56 insertions(+), 17 deletions(-)

diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs
index 4578ae8f..6eafc4da 100644
--- a/src/ast/ddl.rs
+++ b/src/ast/ddl.rs
@@ -1040,6 +1040,7 @@ impl fmt::Display for ColumnDef {
 /// ```sql
 /// name
 /// age OPTIONS(description = "age column", tag = "prod")
+/// amount COMMENT 'The total amount for the order line'
 /// created_at DateTime64
 /// ```
 #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
@@ -1048,7 +1049,7 @@ impl fmt::Display for ColumnDef {
 pub struct ViewColumnDef {
     pub name: Ident,
     pub data_type: Option<DataType>,
-    pub options: Option<Vec<SqlOption>>,
+    pub options: Option<Vec<ColumnOption>>,
 }
 
 impl fmt::Display for ViewColumnDef {
@@ -1058,11 +1059,7 @@ impl fmt::Display for ViewColumnDef {
             write!(f, " {}", data_type)?;
         }
         if let Some(options) = self.options.as_ref() {
-            write!(
-                f,
-                " OPTIONS({})",
-                display_comma_separated(options.as_slice())
-            )?;
+            write!(f, " {}", display_comma_separated(options.as_slice()))?;
         }
         Ok(())
     }
diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index 8c4bc25a..995370f5 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -3930,6 +3930,12 @@ impl fmt::Display for Statement {
                         .map(|to| format!(" TO {to}"))
                         .unwrap_or_default()
                 )?;
+                if !columns.is_empty() {
+                    write!(f, " ({})", display_comma_separated(columns))?;
+                }
+                if matches!(options, CreateTableOptions::With(_)) {
+                    write!(f, " {options}")?;
+                }
                 if let Some(comment) = comment {
                     write!(
                         f,
@@ -3937,12 +3943,6 @@ impl fmt::Display for Statement {
                         value::escape_single_quote_string(comment)
                     )?;
                 }
-                if matches!(options, CreateTableOptions::With(_)) {
-                    write!(f, " {options}")?;
-                }
-                if !columns.is_empty() {
-                    write!(f, " ({})", display_comma_separated(columns))?;
-                }
                 if !cluster_by.is_empty() {
                     write!(f, " CLUSTER BY ({})", 
display_comma_separated(cluster_by))?;
                 }
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 88c3bd19..4e67524a 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -8361,11 +8361,14 @@ impl<'a> Parser<'a> {
     /// Parses a column definition within a view.
     fn parse_view_column(&mut self) -> Result<ViewColumnDef, ParserError> {
         let name = self.parse_identifier(false)?;
-        let options = if dialect_of!(self is BigQueryDialect | GenericDialect)
-            && self.parse_keyword(Keyword::OPTIONS)
+        let options = if (dialect_of!(self is BigQueryDialect | GenericDialect)
+            && self.parse_keyword(Keyword::OPTIONS))
+            || (dialect_of!(self is SnowflakeDialect | GenericDialect)
+                && self.parse_keyword(Keyword::COMMENT))
         {
             self.prev_token();
-            Some(self.parse_options(Keyword::OPTIONS)?)
+            self.parse_optional_column_option()?
+                .map(|option| vec![option])
         } else {
             None
         };
diff --git a/tests/sqlparser_bigquery.rs b/tests/sqlparser_bigquery.rs
index 55afe473..63517fe5 100644
--- a/tests/sqlparser_bigquery.rs
+++ b/tests/sqlparser_bigquery.rs
@@ -272,10 +272,10 @@ fn parse_create_view_with_options() {
                     ViewColumnDef {
                         name: Ident::new("age"),
                         data_type: None,
-                        options: Some(vec![SqlOption::KeyValue {
+                        options: 
Some(vec![ColumnOption::Options(vec![SqlOption::KeyValue {
                             key: Ident::new("description"),
                             value: 
Expr::Value(Value::DoubleQuotedString("field age".to_string())),
-                        }])
+                        }])]),
                     },
                 ],
                 columns
diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs
index 50c5f740..e73b6999 100644
--- a/tests/sqlparser_snowflake.rs
+++ b/tests/sqlparser_snowflake.rs
@@ -2405,3 +2405,42 @@ fn parse_use() {
         );
     }
 }
+
+#[test]
+fn view_comment_option_should_be_after_column_list() {
+    for sql in [
+        "CREATE OR REPLACE VIEW v (a) COMMENT = 'Comment' AS SELECT a FROM t",
+        "CREATE OR REPLACE VIEW v (a COMMENT 'a comment', b, c COMMENT 'c 
comment') COMMENT = 'Comment' AS SELECT a FROM t",
+        "CREATE OR REPLACE VIEW v (a COMMENT 'a comment', b, c COMMENT 'c 
comment') WITH (foo = bar) COMMENT = 'Comment' AS SELECT a FROM t",
+    ] {
+        snowflake_and_generic()
+            .verified_stmt(sql);
+    }
+}
+
+#[test]
+fn parse_view_column_descriptions() {
+    let sql = "CREATE OR REPLACE VIEW v (a COMMENT 'Comment', b) AS SELECT a, 
b FROM table1";
+
+    match snowflake_and_generic().verified_stmt(sql) {
+        Statement::CreateView { name, columns, .. } => {
+            assert_eq!(name.to_string(), "v");
+            assert_eq!(
+                columns,
+                vec![
+                    ViewColumnDef {
+                        name: Ident::new("a"),
+                        data_type: None,
+                        options: 
Some(vec![ColumnOption::Comment("Comment".to_string())]),
+                    },
+                    ViewColumnDef {
+                        name: Ident::new("b"),
+                        data_type: None,
+                        options: None,
+                    }
+                ]
+            );
+        }
+        _ => unreachable!(),
+    };
+}


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

Reply via email to