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]