snowflake: add support for TRANSIENT keyword (#807)

* snowflake: add support for TRANSIENT keyword

Signed-off-by: Maciej Obuchowski <obuchowski.maciej@gmail.com>

* fix clippy

---------

Signed-off-by: Maciej Obuchowski <obuchowski.maciej@gmail.com>
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
Maciej Obuchowski 2023-02-17 19:55:56 +01:00 committed by GitHub
parent 79009f5448
commit a2fea10f89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 2 deletions

View file

@ -50,6 +50,7 @@ pub struct CreateTableBuilder {
pub external: bool, pub external: bool,
pub global: Option<bool>, pub global: Option<bool>,
pub if_not_exists: bool, pub if_not_exists: bool,
pub transient: bool,
pub name: ObjectName, pub name: ObjectName,
pub columns: Vec<ColumnDef>, pub columns: Vec<ColumnDef>,
pub constraints: Vec<TableConstraint>, pub constraints: Vec<TableConstraint>,
@ -78,6 +79,7 @@ impl CreateTableBuilder {
external: false, external: false,
global: None, global: None,
if_not_exists: false, if_not_exists: false,
transient: false,
name, name,
columns: vec![], columns: vec![],
constraints: vec![], constraints: vec![],
@ -123,6 +125,11 @@ impl CreateTableBuilder {
self self
} }
pub fn transient(mut self, transient: bool) -> Self {
self.transient = transient;
self
}
pub fn columns(mut self, columns: Vec<ColumnDef>) -> Self { pub fn columns(mut self, columns: Vec<ColumnDef>) -> Self {
self.columns = columns; self.columns = columns;
self self
@ -213,6 +220,7 @@ impl CreateTableBuilder {
external: self.external, external: self.external,
global: self.global, global: self.global,
if_not_exists: self.if_not_exists, if_not_exists: self.if_not_exists,
transient: self.transient,
name: self.name, name: self.name,
columns: self.columns, columns: self.columns,
constraints: self.constraints, constraints: self.constraints,
@ -248,6 +256,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
external, external,
global, global,
if_not_exists, if_not_exists,
transient,
name, name,
columns, columns,
constraints, constraints,
@ -272,6 +281,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
external, external,
global, global,
if_not_exists, if_not_exists,
transient,
name, name,
columns, columns,
constraints, constraints,

View file

@ -1232,6 +1232,7 @@ pub enum Statement {
external: bool, external: bool,
global: Option<bool>, global: Option<bool>,
if_not_exists: bool, if_not_exists: bool,
transient: bool,
/// Table name /// Table name
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
name: ObjectName, name: ObjectName,
@ -2034,6 +2035,7 @@ impl fmt::Display for Statement {
with_options, with_options,
or_replace, or_replace,
if_not_exists, if_not_exists,
transient,
hive_distribution, hive_distribution,
hive_formats, hive_formats,
external, external,
@ -2060,7 +2062,7 @@ impl fmt::Display for Statement {
// `CREATE TABLE t (a INT) AS SELECT a from t2` // `CREATE TABLE t (a INT) AS SELECT a from t2`
write!( write!(
f, f,
"CREATE {or_replace}{external}{global}{temporary}TABLE {if_not_exists}{name}", "CREATE {or_replace}{external}{global}{temporary}{transient}TABLE {if_not_exists}{name}",
or_replace = if *or_replace { "OR REPLACE " } else { "" }, or_replace = if *or_replace { "OR REPLACE " } else { "" },
external = if *external { "EXTERNAL " } else { "" }, external = if *external { "EXTERNAL " } else { "" },
global = global global = global
@ -2074,6 +2076,7 @@ impl fmt::Display for Statement {
.unwrap_or(""), .unwrap_or(""),
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" }, if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
temporary = if *temporary { "TEMPORARY " } else { "" }, temporary = if *temporary { "TEMPORARY " } else { "" },
transient = if *transient { "TRANSIENT " } else { "" },
name = name, name = name,
)?; )?;
if let Some(on_cluster) = on_cluster { if let Some(on_cluster) = on_cluster {

View file

@ -570,6 +570,7 @@ define_keywords!(
TOP, TOP,
TRAILING, TRAILING,
TRANSACTION, TRANSACTION,
TRANSIENT,
TRANSLATE, TRANSLATE,
TRANSLATE_REGEX, TRANSLATE_REGEX,
TRANSLATION, TRANSLATION,

View file

@ -2266,6 +2266,7 @@ impl<'a> Parser<'a> {
let or_replace = self.parse_keywords(&[Keyword::OR, Keyword::REPLACE]); let or_replace = self.parse_keywords(&[Keyword::OR, Keyword::REPLACE]);
let local = self.parse_one_of_keywords(&[Keyword::LOCAL]).is_some(); let local = self.parse_one_of_keywords(&[Keyword::LOCAL]).is_some();
let global = self.parse_one_of_keywords(&[Keyword::GLOBAL]).is_some(); let global = self.parse_one_of_keywords(&[Keyword::GLOBAL]).is_some();
let transient = self.parse_one_of_keywords(&[Keyword::TRANSIENT]).is_some();
let global: Option<bool> = if global { let global: Option<bool> = if global {
Some(true) Some(true)
} else if local { } else if local {
@ -2277,7 +2278,7 @@ impl<'a> Parser<'a> {
.parse_one_of_keywords(&[Keyword::TEMP, Keyword::TEMPORARY]) .parse_one_of_keywords(&[Keyword::TEMP, Keyword::TEMPORARY])
.is_some(); .is_some();
if self.parse_keyword(Keyword::TABLE) { if self.parse_keyword(Keyword::TABLE) {
self.parse_create_table(or_replace, temporary, global) self.parse_create_table(or_replace, temporary, global, transient)
} else if self.parse_keyword(Keyword::MATERIALIZED) || self.parse_keyword(Keyword::VIEW) { } else if self.parse_keyword(Keyword::MATERIALIZED) || self.parse_keyword(Keyword::VIEW) {
self.prev_token(); self.prev_token();
self.parse_create_view(or_replace) self.parse_create_view(or_replace)
@ -3248,6 +3249,7 @@ impl<'a> Parser<'a> {
or_replace: bool, or_replace: bool,
temporary: bool, temporary: bool,
global: Option<bool>, global: Option<bool>,
transient: bool,
) -> Result<Statement, ParserError> { ) -> Result<Statement, ParserError> {
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]); let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let table_name = self.parse_object_name()?; let table_name = self.parse_object_name()?;
@ -3352,6 +3354,7 @@ impl<'a> Parser<'a> {
.table_properties(table_properties) .table_properties(table_properties)
.or_replace(or_replace) .or_replace(or_replace)
.if_not_exists(if_not_exists) .if_not_exists(if_not_exists)
.transient(transient)
.hive_distribution(hive_distribution) .hive_distribution(hive_distribution)
.hive_formats(Some(hive_formats)) .hive_formats(Some(hive_formats))
.global(global) .global(global)

View file

@ -34,6 +34,20 @@ fn test_snowflake_create_table() {
} }
} }
#[test]
fn test_snowflake_create_transient_table() {
let sql = "CREATE TRANSIENT TABLE CUSTOMER (id INT, name VARCHAR(255))";
match snowflake_and_generic().verified_stmt(sql) {
Statement::CreateTable {
name, transient, ..
} => {
assert_eq!("CUSTOMER", name.to_string());
assert!(transient)
}
_ => unreachable!(),
}
}
#[test] #[test]
fn test_snowflake_single_line_tokenize() { fn test_snowflake_single_line_tokenize() {
let sql = "CREATE TABLE# this is a comment \ntable_1"; let sql = "CREATE TABLE# this is a comment \ntable_1";