From bcc9e29a44aa755d62c915596f8f30110597957a Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Tue, 29 Nov 2022 13:55:13 +0200 Subject: [PATCH] inital commit --- src/ast/mod.rs | 5 +++++ src/parser.rs | 9 +++++++++ tests/sqlparser_common.rs | 41 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 16210f863..2cb2fc0db 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1114,6 +1114,7 @@ pub enum Statement { columns: Vec, query: Box, with_options: Vec, + cluster_by: Vec, }, /// CREATE TABLE CreateTable { @@ -1851,6 +1852,7 @@ impl fmt::Display for Statement { query, materialized, with_options, + cluster_by, } => { write!( f, @@ -1865,6 +1867,9 @@ impl fmt::Display for Statement { if !columns.is_empty() { write!(f, " ({})", display_comma_separated(columns))?; } + if !cluster_by.is_empty() { + write!(f, " CLUSTER BY ({})", display_comma_separated(cluster_by))?; + } write!(f, " AS {}", query) } Statement::CreateTable { diff --git a/src/parser.rs b/src/parser.rs index 237371472..ac72a4013 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2285,6 +2285,14 @@ impl<'a> Parser<'a> { let name = self.parse_object_name()?; let columns = self.parse_parenthesized_column_list(Optional)?; let with_options = self.parse_options(Keyword::WITH)?; + + let cluster_by = if self.parse_keyword(Keyword::CLUSTER) { + self.expect_keyword(Keyword::BY)?; + self.parse_parenthesized_column_list(Optional)? + } else { + vec![] + }; + self.expect_keyword(Keyword::AS)?; let query = Box::new(self.parse_query()?); // Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here. @@ -2295,6 +2303,7 @@ impl<'a> Parser<'a> { materialized, or_replace, with_options, + cluster_by, }) } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 2af06d15e..7b755197d 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -4397,6 +4397,7 @@ fn parse_create_view() { or_replace, materialized, with_options, + cluster_by, } => { assert_eq!("myschema.myview", name.to_string()); assert_eq!(Vec::::new(), columns); @@ -4404,6 +4405,7 @@ fn parse_create_view() { assert!(!materialized); assert!(!or_replace); assert_eq!(with_options, vec![]); + assert_eq!(cluster_by, vec![]); } _ => unreachable!(), } @@ -4443,13 +4445,15 @@ fn parse_create_view_with_columns() { with_options, query, materialized, + cluster_by, } => { assert_eq!("v", name.to_string()); assert_eq!(columns, vec![Ident::new("has"), Ident::new("cols")]); assert_eq!(with_options, vec![]); assert_eq!("SELECT 1, 2", query.to_string()); assert!(!materialized); - assert!(!or_replace) + assert!(!or_replace); + assert_eq!(cluster_by, vec![]); } _ => unreachable!(), } @@ -4466,13 +4470,15 @@ fn parse_create_or_replace_view() { with_options, query, materialized, + cluster_by, } => { assert_eq!("v", name.to_string()); assert_eq!(columns, vec![]); assert_eq!(with_options, vec![]); assert_eq!("SELECT 1", query.to_string()); assert!(!materialized); - assert!(or_replace) + assert!(or_replace); + assert_eq!(cluster_by, vec![]); } _ => unreachable!(), } @@ -4493,13 +4499,15 @@ fn parse_create_or_replace_materialized_view() { with_options, query, materialized, + cluster_by, } => { assert_eq!("v", name.to_string()); assert_eq!(columns, vec![]); assert_eq!(with_options, vec![]); assert_eq!("SELECT 1", query.to_string()); assert!(materialized); - assert!(or_replace) + assert!(or_replace); + assert_eq!(cluster_by, vec![]); } _ => unreachable!(), } @@ -4516,6 +4524,32 @@ fn parse_create_materialized_view() { query, materialized, with_options, + cluster_by, + } => { + assert_eq!("myschema.myview", name.to_string()); + assert_eq!(Vec::::new(), columns); + assert_eq!("SELECT foo FROM bar", query.to_string()); + assert!(materialized); + assert_eq!(with_options, vec![]); + assert!(!or_replace); + assert_eq!(cluster_by, vec![]); + } + _ => unreachable!(), + } +} + +#[test] +fn parse_create_materialized_view_with_cluster_by() { + let sql = "CREATE MATERIALIZED VIEW myschema.myview CLUSTER BY (foo) AS SELECT foo FROM bar"; + match verified_stmt(sql) { + Statement::CreateView { + name, + or_replace, + columns, + query, + materialized, + with_options, + cluster_by, } => { assert_eq!("myschema.myview", name.to_string()); assert_eq!(Vec::::new(), columns); @@ -4523,6 +4557,7 @@ fn parse_create_materialized_view() { assert!(materialized); assert_eq!(with_options, vec![]); assert!(!or_replace); + assert_eq!(cluster_by, vec![Ident::new("foo")]); } _ => unreachable!(), }