From db73cacc8ff00a0bf408f8211942089373689dd6 Mon Sep 17 00:00:00 2001 From: Maciej Obuchowski Date: Thu, 14 Jul 2022 17:48:48 +0200 Subject: [PATCH] create table: add clone syntax Signed-off-by: Maciej Obuchowski --- src/ast/mod.rs | 9 ++++++++- src/keywords.rs | 1 + src/parser.rs | 9 +++++++++ tests/sqlparser_common.rs | 12 ++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index c316aa6b3..7666846c8 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -863,6 +863,7 @@ pub enum Statement { query: Option>, without_rowid: bool, like: Option, + clone: Option, engine: Option, default_charset: Option, collation: Option, @@ -1484,6 +1485,7 @@ impl fmt::Display for Statement { query, without_rowid, like, + clone, default_charset, engine, collation, @@ -1520,7 +1522,7 @@ impl fmt::Display for Statement { write!(f, ", ")?; } write!(f, "{})", display_comma_separated(constraints))?; - } else if query.is_none() && like.is_none() { + } else if query.is_none() && like.is_none() && clone.is_none() { // PostgreSQL allows `CREATE TABLE t ();`, but requires empty parens write!(f, " ()")?; } @@ -1533,6 +1535,11 @@ impl fmt::Display for Statement { if let Some(l) = like { write!(f, " LIKE {}", l)?; } + + if let Some(c) = clone { + write!(f, " CLONE {}", c)?; + } + match hive_distribution { HiveDistributionStyle::PARTITIONED { columns } => { write!(f, " PARTITIONED BY ({})", display_comma_separated(columns))?; diff --git a/src/keywords.rs b/src/keywords.rs index 99cb83155..dbcb67e71 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -126,6 +126,7 @@ define_keywords!( CHAR_LENGTH, CHECK, CLOB, + CLONE, CLOSE, CLUSTER, COALESCE, diff --git a/src/parser.rs b/src/parser.rs index 325d90c47..f2fd1f074 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1774,6 +1774,7 @@ impl<'a> Parser<'a> { query: None, without_rowid: false, like: None, + clone: None, default_charset: None, engine: None, collation: None, @@ -2064,6 +2065,13 @@ impl<'a> Parser<'a> { } else { None }; + + let clone = if self.parse_keyword(Keyword::CLONE) { + self.parse_object_name().ok() + } else { + None + }; + // parse optional column list (schema) let (columns, constraints) = self.parse_columns()?; @@ -2147,6 +2155,7 @@ impl<'a> Parser<'a> { query, without_rowid, like, + clone, engine, default_charset, collation, diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index bb2c4d018..c65d4d10e 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -1992,6 +1992,18 @@ fn parse_create_table_with_options() { } } +#[test] +fn parse_create_table_clone() { + let sql = "CREATE OR REPLACE TABLE a CLONE a_tmp"; + match verified_stmt(sql) { + Statement::CreateTable { name, clone, .. } => { + assert_eq!(ObjectName(vec![Ident::new("a")]), name); + assert_eq!(Some(ObjectName(vec![(Ident::new("a_tmp"))])), clone) + } + _ => unreachable!(), + } +} + #[test] fn parse_create_table_trailing_comma() { let sql = "CREATE TABLE foo (bar int,)";