@@ -22,10 +22,11 @@ use sqlparser_derive::{Visit, VisitMut};
22
22
pub use super :: ddl:: { ColumnDef , TableConstraint } ;
23
23
24
24
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 ,
29
30
} ;
30
31
31
32
/// CREATE INDEX statement.
@@ -57,6 +58,7 @@ pub struct CreateTable {
57
58
pub global : Option < bool > ,
58
59
pub if_not_exists : bool ,
59
60
pub transient : bool ,
61
+ pub volatile : bool ,
60
62
/// Table name
61
63
#[ cfg_attr( feature = "visitor" , visit( with = "visit_relation" ) ) ]
62
64
pub name : ObjectName ,
@@ -74,7 +76,7 @@ pub struct CreateTable {
74
76
pub like : Option < ObjectName > ,
75
77
pub clone : Option < ObjectName > ,
76
78
pub engine : Option < TableEngine > ,
77
- pub comment : Option < String > ,
79
+ pub comment : Option < CommentDef > ,
78
80
pub auto_increment_offset : Option < u32 > ,
79
81
pub default_charset : Option < String > ,
80
82
pub collation : Option < String > ,
@@ -94,14 +96,41 @@ pub struct CreateTable {
94
96
pub partition_by : Option < Box < Expr > > ,
95
97
/// BigQuery: Table clustering column list.
96
98
/// <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 > > > ,
98
100
/// BigQuery: Table options list.
99
101
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
100
102
pub options : Option < Vec < SqlOption > > ,
101
103
/// SQLite "STRICT" clause.
102
104
/// if the "STRICT" table-option keyword is added to the end, after the closing ")",
103
105
/// then strict typing rules apply to that table.
104
106
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 > > ,
105
134
}
106
135
107
136
impl Display for CreateTable {
@@ -115,7 +144,7 @@ impl Display for CreateTable {
115
144
// `CREATE TABLE t (a INT) AS SELECT a from t2`
116
145
write ! (
117
146
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}" ,
119
148
or_replace = if self . or_replace { "OR REPLACE " } else { "" } ,
120
149
external = if self . external { "EXTERNAL " } else { "" } ,
121
150
global = self . global
@@ -130,6 +159,7 @@ impl Display for CreateTable {
130
159
if_not_exists = if self . if_not_exists { "IF NOT EXISTS " } else { "" } ,
131
160
temporary = if self . temporary { "TEMPORARY " } else { "" } ,
132
161
transient = if self . transient { "TRANSIENT " } else { "" } ,
162
+ volatile = if self . volatile { "VOLATILE " } else { "" } ,
133
163
name = self . name,
134
164
) ?;
135
165
if let Some ( on_cluster) = & self . on_cluster {
@@ -260,9 +290,17 @@ impl Display for CreateTable {
260
290
if let Some ( engine) = & self . engine {
261
291
write ! ( f, " ENGINE={engine}" ) ?;
262
292
}
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
+ }
265
302
}
303
+
266
304
if let Some ( auto_increment_offset) = self . auto_increment_offset {
267
305
write ! ( f, " AUTO_INCREMENT {auto_increment_offset}" ) ?;
268
306
}
@@ -276,19 +314,67 @@ impl Display for CreateTable {
276
314
write ! ( f, " PARTITION BY {partition_by}" ) ?;
277
315
}
278
316
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}" ) ?;
284
318
}
319
+
285
320
if let Some ( options) = self . options . as_ref ( ) {
286
321
write ! (
287
322
f,
288
323
" OPTIONS({})" ,
289
324
display_comma_separated( options. as_slice( ) )
290
325
) ?;
291
326
}
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
+
292
378
if let Some ( query) = & self . query {
293
379
write ! ( f, " AS {query}" ) ?;
294
380
}
0 commit comments