@@ -22,10 +22,11 @@ use sqlparser_derive::{Visit, VisitMut};
2222pub use super :: ddl:: { ColumnDef , TableConstraint } ;
2323
2424use 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
107136impl 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