mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-24 07:54:06 +00:00
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:
parent
79009f5448
commit
a2fea10f89
5 changed files with 33 additions and 2 deletions
|
@ -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,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -570,6 +570,7 @@ define_keywords!(
|
||||||
TOP,
|
TOP,
|
||||||
TRAILING,
|
TRAILING,
|
||||||
TRANSACTION,
|
TRANSACTION,
|
||||||
|
TRANSIENT,
|
||||||
TRANSLATE,
|
TRANSLATE,
|
||||||
TRANSLATE_REGEX,
|
TRANSLATE_REGEX,
|
||||||
TRANSLATION,
|
TRANSLATION,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue