create table: add clone syntax (#542)

Signed-off-by: Maciej Obuchowski <obuchowski.maciej@gmail.com>
This commit is contained in:
Maciej Obuchowski 2022-07-16 13:17:02 +02:00 committed by GitHub
parent c2ccc80c28
commit 5363d4e399
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 1 deletions

View file

@ -863,6 +863,7 @@ pub enum Statement {
query: Option<Box<Query>>, query: Option<Box<Query>>,
without_rowid: bool, without_rowid: bool,
like: Option<ObjectName>, like: Option<ObjectName>,
clone: Option<ObjectName>,
engine: Option<String>, engine: Option<String>,
default_charset: Option<String>, default_charset: Option<String>,
collation: Option<String>, collation: Option<String>,
@ -1484,6 +1485,7 @@ impl fmt::Display for Statement {
query, query,
without_rowid, without_rowid,
like, like,
clone,
default_charset, default_charset,
engine, engine,
collation, collation,
@ -1520,7 +1522,7 @@ impl fmt::Display for Statement {
write!(f, ", ")?; write!(f, ", ")?;
} }
write!(f, "{})", display_comma_separated(constraints))?; 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 // PostgreSQL allows `CREATE TABLE t ();`, but requires empty parens
write!(f, " ()")?; write!(f, " ()")?;
} }
@ -1533,6 +1535,11 @@ impl fmt::Display for Statement {
if let Some(l) = like { if let Some(l) = like {
write!(f, " LIKE {}", l)?; write!(f, " LIKE {}", l)?;
} }
if let Some(c) = clone {
write!(f, " CLONE {}", c)?;
}
match hive_distribution { match hive_distribution {
HiveDistributionStyle::PARTITIONED { columns } => { HiveDistributionStyle::PARTITIONED { columns } => {
write!(f, " PARTITIONED BY ({})", display_comma_separated(columns))?; write!(f, " PARTITIONED BY ({})", display_comma_separated(columns))?;

View file

@ -126,6 +126,7 @@ define_keywords!(
CHAR_LENGTH, CHAR_LENGTH,
CHECK, CHECK,
CLOB, CLOB,
CLONE,
CLOSE, CLOSE,
CLUSTER, CLUSTER,
COALESCE, COALESCE,

View file

@ -1774,6 +1774,7 @@ impl<'a> Parser<'a> {
query: None, query: None,
without_rowid: false, without_rowid: false,
like: None, like: None,
clone: None,
default_charset: None, default_charset: None,
engine: None, engine: None,
collation: None, collation: None,
@ -2064,6 +2065,13 @@ impl<'a> Parser<'a> {
} else { } else {
None None
}; };
let clone = if self.parse_keyword(Keyword::CLONE) {
self.parse_object_name().ok()
} else {
None
};
// parse optional column list (schema) // parse optional column list (schema)
let (columns, constraints) = self.parse_columns()?; let (columns, constraints) = self.parse_columns()?;
@ -2147,6 +2155,7 @@ impl<'a> Parser<'a> {
query, query,
without_rowid, without_rowid,
like, like,
clone,
engine, engine,
default_charset, default_charset,
collation, collation,

View file

@ -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] #[test]
fn parse_create_table_trailing_comma() { fn parse_create_table_trailing_comma() {
let sql = "CREATE TABLE foo (bar int,)"; let sql = "CREATE TABLE foo (bar int,)";