mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-08 01:15:00 +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 global: Option<bool>,
|
||||
pub if_not_exists: bool,
|
||||
pub transient: bool,
|
||||
pub name: ObjectName,
|
||||
pub columns: Vec<ColumnDef>,
|
||||
pub constraints: Vec<TableConstraint>,
|
||||
|
@ -78,6 +79,7 @@ impl CreateTableBuilder {
|
|||
external: false,
|
||||
global: None,
|
||||
if_not_exists: false,
|
||||
transient: false,
|
||||
name,
|
||||
columns: vec![],
|
||||
constraints: vec![],
|
||||
|
@ -123,6 +125,11 @@ impl CreateTableBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn transient(mut self, transient: bool) -> Self {
|
||||
self.transient = transient;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn columns(mut self, columns: Vec<ColumnDef>) -> Self {
|
||||
self.columns = columns;
|
||||
self
|
||||
|
@ -213,6 +220,7 @@ impl CreateTableBuilder {
|
|||
external: self.external,
|
||||
global: self.global,
|
||||
if_not_exists: self.if_not_exists,
|
||||
transient: self.transient,
|
||||
name: self.name,
|
||||
columns: self.columns,
|
||||
constraints: self.constraints,
|
||||
|
@ -248,6 +256,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
|
|||
external,
|
||||
global,
|
||||
if_not_exists,
|
||||
transient,
|
||||
name,
|
||||
columns,
|
||||
constraints,
|
||||
|
@ -272,6 +281,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
|
|||
external,
|
||||
global,
|
||||
if_not_exists,
|
||||
transient,
|
||||
name,
|
||||
columns,
|
||||
constraints,
|
||||
|
|
|
@ -1232,6 +1232,7 @@ pub enum Statement {
|
|||
external: bool,
|
||||
global: Option<bool>,
|
||||
if_not_exists: bool,
|
||||
transient: bool,
|
||||
/// Table name
|
||||
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||
name: ObjectName,
|
||||
|
@ -2034,6 +2035,7 @@ impl fmt::Display for Statement {
|
|||
with_options,
|
||||
or_replace,
|
||||
if_not_exists,
|
||||
transient,
|
||||
hive_distribution,
|
||||
hive_formats,
|
||||
external,
|
||||
|
@ -2060,7 +2062,7 @@ impl fmt::Display for Statement {
|
|||
// `CREATE TABLE t (a INT) AS SELECT a from t2`
|
||||
write!(
|
||||
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 { "" },
|
||||
external = if *external { "EXTERNAL " } else { "" },
|
||||
global = global
|
||||
|
@ -2074,6 +2076,7 @@ impl fmt::Display for Statement {
|
|||
.unwrap_or(""),
|
||||
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
|
||||
temporary = if *temporary { "TEMPORARY " } else { "" },
|
||||
transient = if *transient { "TRANSIENT " } else { "" },
|
||||
name = name,
|
||||
)?;
|
||||
if let Some(on_cluster) = on_cluster {
|
||||
|
|
|
@ -570,6 +570,7 @@ define_keywords!(
|
|||
TOP,
|
||||
TRAILING,
|
||||
TRANSACTION,
|
||||
TRANSIENT,
|
||||
TRANSLATE,
|
||||
TRANSLATE_REGEX,
|
||||
TRANSLATION,
|
||||
|
|
|
@ -2266,6 +2266,7 @@ impl<'a> Parser<'a> {
|
|||
let or_replace = self.parse_keywords(&[Keyword::OR, Keyword::REPLACE]);
|
||||
let local = self.parse_one_of_keywords(&[Keyword::LOCAL]).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 {
|
||||
Some(true)
|
||||
} else if local {
|
||||
|
@ -2277,7 +2278,7 @@ impl<'a> Parser<'a> {
|
|||
.parse_one_of_keywords(&[Keyword::TEMP, Keyword::TEMPORARY])
|
||||
.is_some();
|
||||
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) {
|
||||
self.prev_token();
|
||||
self.parse_create_view(or_replace)
|
||||
|
@ -3248,6 +3249,7 @@ impl<'a> Parser<'a> {
|
|||
or_replace: bool,
|
||||
temporary: bool,
|
||||
global: Option<bool>,
|
||||
transient: bool,
|
||||
) -> Result<Statement, ParserError> {
|
||||
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
|
||||
let table_name = self.parse_object_name()?;
|
||||
|
@ -3352,6 +3354,7 @@ impl<'a> Parser<'a> {
|
|||
.table_properties(table_properties)
|
||||
.or_replace(or_replace)
|
||||
.if_not_exists(if_not_exists)
|
||||
.transient(transient)
|
||||
.hive_distribution(hive_distribution)
|
||||
.hive_formats(Some(hive_formats))
|
||||
.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]
|
||||
fn test_snowflake_single_line_tokenize() {
|
||||
let sql = "CREATE TABLE# this is a comment \ntable_1";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue