Skip to content

Commit 881c059

Browse files
localstack-spiral[bot]spiralsabir-akhadov-localstack
authored
LAV-2586: Support CREATE TABLE USING TEMPLATE (#2984)
* LAV-2586: support CREATE TABLE USING TEMPLATE Co-authored-by: Sabir Akhadov <sabir.akhadov@localstack.cloud> * LAV-2586: update vendored CreateTable fixtures Co-authored-by: Sabir Akhadov <sabir.akhadov@localstack.cloud> * LAV-2586: close template validation gaps Co-authored-by: Sabir Akhadov <sabir.akhadov@localstack.cloud> --------- Co-authored-by: spiral <spiral@localhost> Co-authored-by: Sabir Akhadov <sabir.akhadov@localstack.cloud>
1 parent 91a853a commit 881c059

8 files changed

Lines changed: 32 additions & 2 deletions

File tree

src/ast/ddl.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3852,6 +3852,8 @@ pub struct CreateTable {
38523852
pub location: Option<String>,
38533853
/// Query used to populate the table
38543854
pub query: Option<Box<Query>>,
3855+
/// Snowflake `USING TEMPLATE (<query>)` query.
3856+
pub template: Option<Box<Query>>,
38553857
/// If the table should be created without a rowid (SQLite)
38563858
pub without_rowid: bool,
38573859
/// `LIKE` clause
@@ -4438,7 +4440,9 @@ impl fmt::Display for CreateTable {
44384440
if let Some(sortkey) = &self.sortkey {
44394441
write!(f, " SORTKEY({})", display_comma_separated(sortkey))?;
44404442
}
4441-
if let Some(query) = &self.query {
4443+
if let Some(query) = &self.template {
4444+
write!(f, " USING TEMPLATE ({query})")?;
4445+
} else if let Some(query) = &self.query {
44424446
write!(f, " AS {query}")?;
44434447
}
44444448
Ok(())

src/ast/helpers/stmt_create_table.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ pub struct CreateTableBuilder {
106106
pub location: Option<String>,
107107
/// Optional `AS SELECT` query for the table.
108108
pub query: Option<Box<Query>>,
109+
/// Optional Snowflake `USING TEMPLATE` query.
110+
pub template: Option<Box<Query>>,
109111
/// Whether `WITHOUT ROWID` is set.
110112
pub without_rowid: bool,
111113
/// Optional `LIKE` clause kind.
@@ -246,6 +248,7 @@ impl CreateTableBuilder {
246248
file_format: None,
247249
location: None,
248250
query: None,
251+
template: None,
249252
without_rowid: false,
250253
like: None,
251254
clone: None,
@@ -400,6 +403,11 @@ impl CreateTableBuilder {
400403
self.query = query;
401404
self
402405
}
406+
/// Set a Snowflake `USING TEMPLATE` query.
407+
pub fn template(mut self, template: Option<Box<Query>>) -> Self {
408+
self.template = template;
409+
self
410+
}
403411
/// Set `WITHOUT ROWID` option.
404412
pub fn without_rowid(mut self, without_rowid: bool) -> Self {
405413
self.without_rowid = without_rowid;
@@ -709,6 +717,7 @@ impl CreateTableBuilder {
709717
file_format: self.file_format,
710718
location: self.location,
711719
query: self.query,
720+
template: self.template,
712721
without_rowid: self.without_rowid,
713722
like: self.like,
714723
clone: self.clone,
@@ -808,6 +817,7 @@ impl From<CreateTable> for CreateTableBuilder {
808817
file_format: table.file_format,
809818
location: table.location,
810819
query: table.query,
820+
template: table.template,
811821
without_rowid: table.without_rowid,
812822
like: table.like,
813823
clone: table.clone,

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,7 @@ impl Spanned for CreateTable {
716716
snapshot: _, // bool, BigQuery specific
717717
name,
718718
columns,
719+
template: _,
719720
constraints,
720721
hive_distribution: _, // hive specific
721722
hive_formats: _, // hive specific

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,7 @@ define_keywords!(
11491149
TASK_AUTO_RETRY_ATTEMPTS,
11501150
TBLPROPERTIES,
11511151
TEMP,
1152+
TEMPLATE,
11521153
TEMPORARY,
11531154
TEMPTABLE,
11541155
TERMINATED,

src/parser/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9753,8 +9753,17 @@ impl<'a> Parser<'a> {
97539753
None
97549754
};
97559755

9756+
let template = if self.parse_keywords(&[Keyword::USING, Keyword::TEMPLATE]) {
9757+
self.expect_token(&Token::LParen)?;
9758+
let query = self.parse_query()?;
9759+
self.expect_token(&Token::RParen)?;
9760+
Some(query)
9761+
} else {
9762+
None
9763+
};
9764+
97569765
// Parse optional `AS ( query )`
9757-
let query = if self.parse_keyword(Keyword::AS) {
9766+
let query = if template.is_none() && self.parse_keyword(Keyword::AS) {
97589767
Some(self.parse_query()?)
97599768
} else if self.dialect.supports_create_table_select() && self.parse_keyword(Keyword::SELECT)
97609769
{
@@ -9776,6 +9785,7 @@ impl<'a> Parser<'a> {
97769785
.hive_formats(hive_formats)
97779786
.global(global)
97789787
.query(query)
9788+
.template(template)
97799789
.without_rowid(without_rowid)
97809790
.like(like)
97819791
.clone_clause(clone)

tests/sqlparser_duckdb.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,7 @@ fn test_duckdb_union_datatype() {
755755
file_format: Default::default(),
756756
location: Default::default(),
757757
query: Default::default(),
758+
template: Default::default(),
758759
without_rowid: Default::default(),
759760
like: Default::default(),
760761
clone: Default::default(),

tests/sqlparser_mssql.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,6 +1982,7 @@ fn parse_create_table_with_valid_options() {
19821982
file_format: None,
19831983
location: None,
19841984
query: None,
1985+
template: None,
19851986
without_rowid: false,
19861987
like: None,
19871988
clone: None,
@@ -2176,6 +2177,7 @@ fn parse_create_table_with_identity_column() {
21762177
file_format: None,
21772178
location: None,
21782179
query: None,
2180+
template: None,
21792181
without_rowid: false,
21802182
like: None,
21812183
clone: None,

tests/sqlparser_postgres.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6704,6 +6704,7 @@ fn parse_trigger_related_functions() {
67046704
file_format: None,
67056705
location: None,
67066706
query: None,
6707+
template: None,
67076708
without_rowid: false,
67086709
like: None,
67096710
clone: None,

0 commit comments

Comments
 (0)