Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4b8797e

Browse files
Snowflake: Add support for CREATE DYNAMIC TABLE (#1960)
1 parent 3b52428 commit 4b8797e

File tree

11 files changed

+342
-96
lines changed

11 files changed

+342
-96
lines changed

‎src/ast/ddl.rs‎

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ use crate::ast::{
3333
display_comma_separated, display_separated, ArgMode, CommentDef, CreateFunctionBody,
3434
CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, DataType, Expr, FileFormat,
3535
FunctionBehavior, FunctionCalledOnNull, FunctionDeterminismSpecifier, FunctionParallel,
36-
HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident, MySQLColumnPosition,
37-
ObjectName, OnCommit, OneOrManyWithParens, OperateFunctionArg, OrderByExpr, ProjectionSelect,
38-
Query, RowAccessPolicy, SequenceOptions, Spanned, SqlOption, StorageSerializationPolicy, Tag,
39-
Value, ValueWithSpan, WrappedCollection,
36+
HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident, InitializeKind,
37+
MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens, OperateFunctionArg,
38+
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy, SequenceOptions,
39+
Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag, Value, ValueWithSpan,
40+
WrappedCollection,
4041
};
4142
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
4243
use crate::keywords::Keyword;
@@ -2428,6 +2429,7 @@ pub struct CreateTable {
24282429
pub or_replace: bool,
24292430
pub temporary: bool,
24302431
pub external: bool,
2432+
pub dynamic: bool,
24312433
pub global: Option<bool>,
24322434
pub if_not_exists: bool,
24332435
pub transient: bool,
@@ -2448,6 +2450,7 @@ pub struct CreateTable {
24482450
pub without_rowid: bool,
24492451
pub like: Option<CreateTableLikeKind>,
24502452
pub clone: Option<ObjectName>,
2453+
pub version: Option<TableVersion>,
24512454
// For Hive dialect, the table comment is after the column definitions without `=`,
24522455
// so the `comment` field is optional and different than the comment field in the general options list.
24532456
// [Hive](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateTable)
@@ -2525,6 +2528,21 @@ pub struct CreateTable {
25252528
/// Snowflake "STORAGE_SERIALIZATION_POLICY" clause for Iceberg tables
25262529
/// <https://docs.snowflake.com/en/sql-reference/sql/create-iceberg-table>
25272530
pub storage_serialization_policy: Option<StorageSerializationPolicy>,
2531+
/// Snowflake "TARGET_LAG" clause for dybamic tables
2532+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table>
2533+
pub target_lag: Option<String>,
2534+
/// Snowflake "WAREHOUSE" clause for dybamic tables
2535+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table>
2536+
pub warehouse: Option<Ident>,
2537+
/// Snowflake "REFRESH_MODE" clause for dybamic tables
2538+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table>
2539+
pub refresh_mode: Option<RefreshModeKind>,
2540+
/// Snowflake "INITIALIZE" clause for dybamic tables
2541+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table>
2542+
pub initialize: Option<InitializeKind>,
2543+
/// Snowflake "REQUIRE USER" clause for dybamic tables
2544+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table>
2545+
pub require_user: bool,
25282546
}
25292547

25302548
impl fmt::Display for CreateTable {
@@ -2538,7 +2556,7 @@ impl fmt::Display for CreateTable {
25382556
// `CREATE TABLE t (a INT) AS SELECT a from t2`
25392557
write!(
25402558
f,
2541-
"CREATE {or_replace}{external}{global}{temporary}{transient}{volatile}{iceberg}TABLE {if_not_exists}{name}",
2559+
"CREATE {or_replace}{external}{global}{temporary}{transient}{volatile}{dynamic}{iceberg}TABLE {if_not_exists}{name}",
25422560
or_replace = if self.or_replace { "OR REPLACE " } else { "" },
25432561
external = if self.external { "EXTERNAL " } else { "" },
25442562
global = self.global
@@ -2556,6 +2574,7 @@ impl fmt::Display for CreateTable {
25562574
volatile = if self.volatile { "VOLATILE " } else { "" },
25572575
// Only for Snowflake
25582576
iceberg = if self.iceberg { "ICEBERG " } else { "" },
2577+
dynamic = if self.dynamic { "DYNAMIC " } else { "" },
25592578
name = self.name,
25602579
)?;
25612580
if let Some(on_cluster) = &self.on_cluster {
@@ -2598,6 +2617,10 @@ impl fmt::Display for CreateTable {
25982617
write!(f, " CLONE {c}")?;
25992618
}
26002619

2620+
if let Some(version) = &self.version {
2621+
write!(f, " {version}")?;
2622+
}
2623+
26012624
match &self.hive_distribution {
26022625
HiveDistributionStyle::PARTITIONED { columns } => {
26032626
write!(f, " PARTITIONED BY ({})", display_comma_separated(columns))?;
@@ -2700,27 +2723,27 @@ impl fmt::Display for CreateTable {
27002723
write!(f, " {options}")?;
27012724
}
27022725
if let Some(external_volume) = self.external_volume.as_ref() {
2703-
write!(f, " EXTERNAL_VOLUME = '{external_volume}'")?;
2726+
write!(f, " EXTERNAL_VOLUME='{external_volume}'")?;
27042727
}
27052728

27062729
if let Some(catalog) = self.catalog.as_ref() {
2707-
write!(f, " CATALOG = '{catalog}'")?;
2730+
write!(f, " CATALOG='{catalog}'")?;
27082731
}
27092732

27102733
if self.iceberg {
27112734
if let Some(base_location) = self.base_location.as_ref() {
2712-
write!(f, " BASE_LOCATION = '{base_location}'")?;
2735+
write!(f, " BASE_LOCATION='{base_location}'")?;
27132736
}
27142737
}
27152738

27162739
if let Some(catalog_sync) = self.catalog_sync.as_ref() {
2717-
write!(f, " CATALOG_SYNC = '{catalog_sync}'")?;
2740+
write!(f, " CATALOG_SYNC='{catalog_sync}'")?;
27182741
}
27192742

27202743
if let Some(storage_serialization_policy) = self.storage_serialization_policy.as_ref() {
27212744
write!(
27222745
f,
2723-
" STORAGE_SERIALIZATION_POLICY = {storage_serialization_policy}"
2746+
" STORAGE_SERIALIZATION_POLICY={storage_serialization_policy}"
27242747
)?;
27252748
}
27262749

@@ -2774,6 +2797,26 @@ impl fmt::Display for CreateTable {
27742797
write!(f, " WITH TAG ({})", display_comma_separated(tag.as_slice()))?;
27752798
}
27762799

2800+
if let Some(target_lag) = &self.target_lag {
2801+
write!(f, " TARGET_LAG='{target_lag}'")?;
2802+
}
2803+
2804+
if let Some(warehouse) = &self.warehouse {
2805+
write!(f, " WAREHOUSE={warehouse}")?;
2806+
}
2807+
2808+
if let Some(refresh_mode) = &self.refresh_mode {
2809+
write!(f, " REFRESH_MODE={refresh_mode}")?;
2810+
}
2811+
2812+
if let Some(initialize) = &self.initialize {
2813+
write!(f, " INITIALIZE={initialize}")?;
2814+
}
2815+
2816+
if self.require_user {
2817+
write!(f, " REQUIRE USER")?;
2818+
}
2819+
27772820
if self.on_commit.is_some() {
27782821
let on_commit = match self.on_commit {
27792822
Some(OnCommit::DeleteRows) => "ON COMMIT DELETE ROWS",

‎src/ast/helpers/stmt_create_table.rs‎

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ use sqlparser_derive::{Visit, VisitMut};
2626

2727
use crate::ast::{
2828
ClusteredBy, ColumnDef, CommentDef, CreateTable, CreateTableLikeKind, CreateTableOptions, Expr,
29-
FileFormat, HiveDistributionStyle, HiveFormat, Ident, ObjectName, OnCommit,
30-
OneOrManyWithParens, Query, RowAccessPolicy,Statement,StorageSerializationPolicy,
31-
TableConstraint, Tag, WrappedCollection,
29+
FileFormat, HiveDistributionStyle, HiveFormat, Ident, InitializeKind,ObjectName, OnCommit,
30+
OneOrManyWithParens, Query, RefreshModeKind,RowAccessPolicy,Statement,
31+
StorageSerializationPolicy,TableConstraint,TableVersion, Tag, WrappedCollection,
3232
};
3333

3434
use crate::parser::ParserError;
@@ -72,6 +72,7 @@ pub struct CreateTableBuilder {
7272
pub transient: bool,
7373
pub volatile: bool,
7474
pub iceberg: bool,
75+
pub dynamic: bool,
7576
pub name: ObjectName,
7677
pub columns: Vec<ColumnDef>,
7778
pub constraints: Vec<TableConstraint>,
@@ -83,6 +84,7 @@ pub struct CreateTableBuilder {
8384
pub without_rowid: bool,
8485
pub like: Option<CreateTableLikeKind>,
8586
pub clone: Option<ObjectName>,
87+
pub version: Option<TableVersion>,
8688
pub comment: Option<CommentDef>,
8789
pub on_commit: Option<OnCommit>,
8890
pub on_cluster: Option<Ident>,
@@ -108,6 +110,11 @@ pub struct CreateTableBuilder {
108110
pub catalog_sync: Option<String>,
109111
pub storage_serialization_policy: Option<StorageSerializationPolicy>,
110112
pub table_options: CreateTableOptions,
113+
pub target_lag: Option<String>,
114+
pub warehouse: Option<Ident>,
115+
pub refresh_mode: Option<RefreshModeKind>,
116+
pub initialize: Option<InitializeKind>,
117+
pub require_user: bool,
111118
}
112119

113120
impl CreateTableBuilder {
@@ -121,6 +128,7 @@ impl CreateTableBuilder {
121128
transient: false,
122129
volatile: false,
123130
iceberg: false,
131+
dynamic: false,
124132
name,
125133
columns: vec![],
126134
constraints: vec![],
@@ -132,6 +140,7 @@ impl CreateTableBuilder {
132140
without_rowid: false,
133141
like: None,
134142
clone: None,
143+
version: None,
135144
comment: None,
136145
on_commit: None,
137146
on_cluster: None,
@@ -157,6 +166,11 @@ impl CreateTableBuilder {
157166
catalog_sync: None,
158167
storage_serialization_policy: None,
159168
table_options: CreateTableOptions::None,
169+
target_lag: None,
170+
warehouse: None,
171+
refresh_mode: None,
172+
initialize: None,
173+
require_user: false,
160174
}
161175
}
162176
pub fn or_replace(mut self, or_replace: bool) -> Self {
@@ -199,6 +213,11 @@ impl CreateTableBuilder {
199213
self
200214
}
201215

216+
pub fn dynamic(mut self, dynamic: bool) -> Self {
217+
self.dynamic = dynamic;
218+
self
219+
}
220+
202221
pub fn columns(mut self, columns: Vec<ColumnDef>) -> Self {
203222
self.columns = columns;
204223
self
@@ -248,6 +267,11 @@ impl CreateTableBuilder {
248267
self
249268
}
250269

270+
pub fn version(mut self, version: Option<TableVersion>) -> Self {
271+
self.version = version;
272+
self
273+
}
274+
251275
pub fn comment_after_column_def(mut self, comment: Option<CommentDef>) -> Self {
252276
self.comment = comment;
253277
self
@@ -382,24 +406,29 @@ impl CreateTableBuilder {
382406
self
383407
}
384408

385-
/// Returns true if the statement has exactly one source of info on the schema of the new table.
386-
/// This is Snowflake-specific, some dialects allow more than one source.
387-
pub(crate) fn validate_schema_info(&self) -> bool {
388-
let mut sources = 0;
389-
if !self.columns.is_empty() {
390-
sources += 1;
391-
}
392-
if self.query.is_some() {
393-
sources += 1;
394-
}
395-
if self.like.is_some() {
396-
sources += 1;
397-
}
398-
if self.clone.is_some() {
399-
sources += 1;
400-
}
409+
pub fn target_lag(mut self, target_lag: Option<String>) -> Self {
410+
self.target_lag = target_lag;
411+
self
412+
}
413+
414+
pub fn warehouse(mut self, warehouse: Option<Ident>) -> Self {
415+
self.warehouse = warehouse;
416+
self
417+
}
401418

402-
sources == 1
419+
pub fn refresh_mode(mut self, refresh_mode: Option<RefreshModeKind>) -> Self {
420+
self.refresh_mode = refresh_mode;
421+
self
422+
}
423+
424+
pub fn initialize(mut self, initialize: Option<InitializeKind>) -> Self {
425+
self.initialize = initialize;
426+
self
427+
}
428+
429+
pub fn require_user(mut self, require_user: bool) -> Self {
430+
self.require_user = require_user;
431+
self
403432
}
404433

405434
pub fn build(self) -> Statement {
@@ -412,6 +441,7 @@ impl CreateTableBuilder {
412441
transient: self.transient,
413442
volatile: self.volatile,
414443
iceberg: self.iceberg,
444+
dynamic: self.dynamic,
415445
name: self.name,
416446
columns: self.columns,
417447
constraints: self.constraints,
@@ -423,6 +453,7 @@ impl CreateTableBuilder {
423453
without_rowid: self.without_rowid,
424454
like: self.like,
425455
clone: self.clone,
456+
version: self.version,
426457
comment: self.comment,
427458
on_commit: self.on_commit,
428459
on_cluster: self.on_cluster,
@@ -448,6 +479,11 @@ impl CreateTableBuilder {
448479
catalog_sync: self.catalog_sync,
449480
storage_serialization_policy: self.storage_serialization_policy,
450481
table_options: self.table_options,
482+
target_lag: self.target_lag,
483+
warehouse: self.warehouse,
484+
refresh_mode: self.refresh_mode,
485+
initialize: self.initialize,
486+
require_user: self.require_user,
451487
})
452488
}
453489
}
@@ -468,6 +504,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
468504
transient,
469505
volatile,
470506
iceberg,
507+
dynamic,
471508
name,
472509
columns,
473510
constraints,
@@ -479,6 +516,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
479516
without_rowid,
480517
like,
481518
clone,
519+
version,
482520
comment,
483521
on_commit,
484522
on_cluster,
@@ -504,13 +542,19 @@ impl TryFrom<Statement> for CreateTableBuilder {
504542
catalog_sync,
505543
storage_serialization_policy,
506544
table_options,
545+
target_lag,
546+
warehouse,
547+
refresh_mode,
548+
initialize,
549+
require_user,
507550
}) => Ok(Self {
508551
or_replace,
509552
temporary,
510553
external,
511554
global,
512555
if_not_exists,
513556
transient,
557+
dynamic,
514558
name,
515559
columns,
516560
constraints,
@@ -522,6 +566,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
522566
without_rowid,
523567
like,
524568
clone,
569+
version,
525570
comment,
526571
on_commit,
527572
on_cluster,
@@ -549,6 +594,11 @@ impl TryFrom<Statement> for CreateTableBuilder {
549594
catalog_sync,
550595
storage_serialization_policy,
551596
table_options,
597+
target_lag,
598+
warehouse,
599+
refresh_mode,
600+
initialize,
601+
require_user,
552602
}),
553603
_ => Err(ParserError::ParserError(format!(
554604
"Expected create table statement, but received: {stmt}"

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /