Skip to content

Commit be77ce5

Browse files
balliegojrIlson Roberto Balliego Junior
andauthored
Add support for snowflake exclusive create table options (#1233)
Co-authored-by: Ilson Roberto Balliego Junior <[email protected]>
1 parent 3c33ac1 commit be77ce5

File tree

10 files changed

+1029
-31
lines changed

10 files changed

+1029
-31
lines changed

src/ast/dml.rs

Lines changed: 100 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ use sqlparser_derive::{Visit, VisitMut};
2222
pub use super::ddl::{ColumnDef, TableConstraint};
2323

2424
use super::{
25-
display_comma_separated, display_separated, Expr, FileFormat, FromTable, HiveDistributionStyle,
26-
HiveFormat, HiveIOFormat, HiveRowFormat, Ident, InsertAliases, MysqlInsertPriority, ObjectName,
27-
OnCommit, OnInsert, OneOrManyWithParens, OrderByExpr, Query, SelectItem, SqlOption,
28-
SqliteOnConflict, TableEngine, TableWithJoins,
25+
display_comma_separated, display_separated, CommentDef, Expr, FileFormat, FromTable,
26+
HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident, InsertAliases,
27+
MysqlInsertPriority, ObjectName, OnCommit, OnInsert, OneOrManyWithParens, OrderByExpr, Query,
28+
RowAccessPolicy, SelectItem, SqlOption, SqliteOnConflict, TableEngine, TableWithJoins, Tag,
29+
WrappedCollection,
2930
};
3031

3132
/// CREATE INDEX statement.
@@ -57,6 +58,7 @@ pub struct CreateTable {
5758
pub global: Option<bool>,
5859
pub if_not_exists: bool,
5960
pub transient: bool,
61+
pub volatile: bool,
6062
/// Table name
6163
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
6264
pub name: ObjectName,
@@ -74,7 +76,7 @@ pub struct CreateTable {
7476
pub like: Option<ObjectName>,
7577
pub clone: Option<ObjectName>,
7678
pub engine: Option<TableEngine>,
77-
pub comment: Option<String>,
79+
pub comment: Option<CommentDef>,
7880
pub auto_increment_offset: Option<u32>,
7981
pub default_charset: Option<String>,
8082
pub collation: Option<String>,
@@ -94,14 +96,41 @@ pub struct CreateTable {
9496
pub partition_by: Option<Box<Expr>>,
9597
/// BigQuery: Table clustering column list.
9698
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
97-
pub cluster_by: Option<Vec<Ident>>,
99+
pub cluster_by: Option<WrappedCollection<Vec<Ident>>>,
98100
/// BigQuery: Table options list.
99101
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
100102
pub options: Option<Vec<SqlOption>>,
101103
/// SQLite "STRICT" clause.
102104
/// if the "STRICT" table-option keyword is added to the end, after the closing ")",
103105
/// then strict typing rules apply to that table.
104106
pub strict: bool,
107+
/// Snowflake "COPY GRANTS" clause
108+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
109+
pub copy_grants: bool,
110+
/// Snowflake "ENABLE_SCHEMA_EVOLUTION" clause
111+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
112+
pub enable_schema_evolution: Option<bool>,
113+
/// Snowflake "CHANGE_TRACKING" clause
114+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
115+
pub change_tracking: Option<bool>,
116+
/// Snowflake "DATA_RETENTION_TIME_IN_DAYS" clause
117+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
118+
pub data_retention_time_in_days: Option<u64>,
119+
/// Snowflake "MAX_DATA_EXTENSION_TIME_IN_DAYS" clause
120+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
121+
pub max_data_extension_time_in_days: Option<u64>,
122+
/// Snowflake "DEFAULT_DDL_COLLATION" clause
123+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
124+
pub default_ddl_collation: Option<String>,
125+
/// Snowflake "WITH AGGREGATION POLICY" clause
126+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
127+
pub with_aggregation_policy: Option<ObjectName>,
128+
/// Snowflake "WITH ROW ACCESS POLICY" clause
129+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
130+
pub with_row_access_policy: Option<RowAccessPolicy>,
131+
/// Snowflake "WITH TAG" clause
132+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
133+
pub with_tags: Option<Vec<Tag>>,
105134
}
106135

107136
impl Display for CreateTable {
@@ -115,7 +144,7 @@ impl Display for CreateTable {
115144
// `CREATE TABLE t (a INT) AS SELECT a from t2`
116145
write!(
117146
f,
118-
"CREATE {or_replace}{external}{global}{temporary}{transient}TABLE {if_not_exists}{name}",
147+
"CREATE {or_replace}{external}{global}{temporary}{transient}{volatile}TABLE {if_not_exists}{name}",
119148
or_replace = if self.or_replace { "OR REPLACE " } else { "" },
120149
external = if self.external { "EXTERNAL " } else { "" },
121150
global = self.global
@@ -130,6 +159,7 @@ impl Display for CreateTable {
130159
if_not_exists = if self.if_not_exists { "IF NOT EXISTS " } else { "" },
131160
temporary = if self.temporary { "TEMPORARY " } else { "" },
132161
transient = if self.transient { "TRANSIENT " } else { "" },
162+
volatile = if self.volatile { "VOLATILE " } else { "" },
133163
name = self.name,
134164
)?;
135165
if let Some(on_cluster) = &self.on_cluster {
@@ -260,9 +290,17 @@ impl Display for CreateTable {
260290
if let Some(engine) = &self.engine {
261291
write!(f, " ENGINE={engine}")?;
262292
}
263-
if let Some(comment) = &self.comment {
264-
write!(f, " COMMENT '{comment}'")?;
293+
if let Some(comment_def) = &self.comment {
294+
match comment_def {
295+
CommentDef::WithEq(comment) => {
296+
write!(f, " COMMENT = '{comment}'")?;
297+
}
298+
CommentDef::WithoutEq(comment) => {
299+
write!(f, " COMMENT '{comment}'")?;
300+
}
301+
}
265302
}
303+
266304
if let Some(auto_increment_offset) = self.auto_increment_offset {
267305
write!(f, " AUTO_INCREMENT {auto_increment_offset}")?;
268306
}
@@ -276,19 +314,67 @@ impl Display for CreateTable {
276314
write!(f, " PARTITION BY {partition_by}")?;
277315
}
278316
if let Some(cluster_by) = self.cluster_by.as_ref() {
279-
write!(
280-
f,
281-
" CLUSTER BY {}",
282-
display_comma_separated(cluster_by.as_slice())
283-
)?;
317+
write!(f, " CLUSTER BY {cluster_by}")?;
284318
}
319+
285320
if let Some(options) = self.options.as_ref() {
286321
write!(
287322
f,
288323
" OPTIONS({})",
289324
display_comma_separated(options.as_slice())
290325
)?;
291326
}
327+
328+
if self.copy_grants {
329+
write!(f, " COPY GRANTS")?;
330+
}
331+
332+
if let Some(is_enabled) = self.enable_schema_evolution {
333+
write!(
334+
f,
335+
" ENABLE_SCHEMA_EVOLUTION={}",
336+
if is_enabled { "TRUE" } else { "FALSE" }
337+
)?;
338+
}
339+
340+
if let Some(is_enabled) = self.change_tracking {
341+
write!(
342+
f,
343+
" CHANGE_TRACKING={}",
344+
if is_enabled { "TRUE" } else { "FALSE" }
345+
)?;
346+
}
347+
348+
if let Some(data_retention_time_in_days) = self.data_retention_time_in_days {
349+
write!(
350+
f,
351+
" DATA_RETENTION_TIME_IN_DAYS={data_retention_time_in_days}",
352+
)?;
353+
}
354+
355+
if let Some(max_data_extension_time_in_days) = self.max_data_extension_time_in_days {
356+
write!(
357+
f,
358+
" MAX_DATA_EXTENSION_TIME_IN_DAYS={max_data_extension_time_in_days}",
359+
)?;
360+
}
361+
362+
if let Some(default_ddl_collation) = &self.default_ddl_collation {
363+
write!(f, " DEFAULT_DDL_COLLATION='{default_ddl_collation}'",)?;
364+
}
365+
366+
if let Some(with_aggregation_policy) = &self.with_aggregation_policy {
367+
write!(f, " WITH AGGREGATION POLICY {with_aggregation_policy}",)?;
368+
}
369+
370+
if let Some(row_access_policy) = &self.with_row_access_policy {
371+
write!(f, " {row_access_policy}",)?;
372+
}
373+
374+
if let Some(tag) = &self.with_tags {
375+
write!(f, " WITH TAG ({})", display_comma_separated(tag.as_slice()))?;
376+
}
377+
292378
if let Some(query) = &self.query {
293379
write!(f, " AS {query}")?;
294380
}

0 commit comments

Comments
 (0)