Skip to content

Commit f1cacd2

Browse files
committed
create table parsing - unify the different parameter options into the CreateTableOptions enum
1 parent 66f5260 commit f1cacd2

14 files changed

+182
-154
lines changed

src/ast/dml.rs

+12-32
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ pub use super::ddl::{ColumnDef, TableConstraint};
3333

3434
use super::{
3535
display_comma_separated, display_separated, query::InputFormatClause, Assignment, ClusteredBy,
36-
CommentDef, Expr, FileFormat, FromTable, HiveDistributionStyle, HiveFormat, HiveIOFormat,
37-
HiveRowFormat, Ident, IndexType, InsertAliases, MysqlInsertPriority, ObjectName, OnCommit,
38-
OnInsert, OneOrManyWithParens, OrderByExpr, Query, RowAccessPolicy, SelectItem, Setting,
39-
SqlOption, SqliteOnConflict, StorageSerializationPolicy, TableObject, TableWithJoins, Tag,
36+
CommentDef, CreateTableOptions, Expr, FileFormat, FromTable, HiveDistributionStyle, HiveFormat,
37+
HiveIOFormat, HiveRowFormat, Ident, IndexType, InsertAliases, MysqlInsertPriority, ObjectName,
38+
OnCommit, OnInsert, OneOrManyWithParens, OrderByExpr, Query, RowAccessPolicy, SelectItem,
39+
Setting, SqliteOnConflict, StorageSerializationPolicy, TableObject, TableWithJoins, Tag,
4040
WrappedCollection,
4141
};
4242

@@ -146,14 +146,7 @@ pub struct CreateTable {
146146
pub constraints: Vec<TableConstraint>,
147147
pub hive_distribution: HiveDistributionStyle,
148148
pub hive_formats: Option<HiveFormat>,
149-
pub table_properties: Vec<SqlOption>,
150-
pub with_options: Vec<SqlOption>,
151-
/// BigQuery: Table options list.
152-
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
153-
pub options: Option<Vec<SqlOption>>,
154-
/// Plain options, options which are not part on any declerative statement e.g. WITH/OPTIONS/...
155-
/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
156-
pub plain_options: Vec<SqlOption>,
149+
pub table_options: CreateTableOptions,
157150
pub file_format: Option<FileFormat>,
158151
pub location: Option<String>,
159152
pub query: Option<Box<Query>>,
@@ -372,19 +365,12 @@ impl Display for CreateTable {
372365
}
373366
write!(f, " LOCATION '{}'", self.location.as_ref().unwrap())?;
374367
}
375-
if !self.table_properties.is_empty() {
376-
write!(
377-
f,
378-
" TBLPROPERTIES ({})",
379-
display_comma_separated(&self.table_properties)
380-
)?;
381-
}
382-
if !self.with_options.is_empty() {
383-
write!(f, " WITH ({})", display_comma_separated(&self.with_options))?;
384-
}
385368

386-
if !self.plain_options.is_empty() {
387-
write!(f, " {}", display_separated(&self.plain_options, " "))?;
369+
match &self.table_options {
370+
options @ CreateTableOptions::With(_)
371+
| options @ CreateTableOptions::Plain(_)
372+
| options @ CreateTableOptions::TableProperties(_) => write!(f, " {}", options)?,
373+
_ => (),
388374
}
389375

390376
if let Some(primary_key) = &self.primary_key {
@@ -399,15 +385,9 @@ impl Display for CreateTable {
399385
if let Some(cluster_by) = self.cluster_by.as_ref() {
400386
write!(f, " CLUSTER BY {cluster_by}")?;
401387
}
402-
403-
if let Some(options) = self.options.as_ref() {
404-
write!(
405-
f,
406-
" OPTIONS({})",
407-
display_comma_separated(options.as_slice())
408-
)?;
388+
if let options @ CreateTableOptions::Options(_) = &self.table_options {
389+
write!(f, " {}", options)?;
409390
}
410-
411391
if let Some(external_volume) = self.external_volume.as_ref() {
412392
write!(f, " EXTERNAL_VOLUME = '{external_volume}'")?;
413393
}

src/ast/helpers/stmt_create_table.rs

+15-44
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ use sqlparser_derive::{Visit, VisitMut};
2626

2727
use super::super::dml::CreateTable;
2828
use crate::ast::{
29-
ClusteredBy, ColumnDef, CommentDef, Expr, FileFormat, HiveDistributionStyle, HiveFormat, Ident,
30-
ObjectName, OnCommit, OneOrManyWithParens, Query, RowAccessPolicy, SqlOption, Statement,
31-
StorageSerializationPolicy, TableConstraint, Tag, WrappedCollection,
29+
ClusteredBy, ColumnDef, CommentDef, CreateTableOptions, Expr, FileFormat,
30+
HiveDistributionStyle, HiveFormat, Ident, ObjectName, OnCommit, OneOrManyWithParens, Query,
31+
RowAccessPolicy, Statement, StorageSerializationPolicy, TableConstraint, Tag,
32+
WrappedCollection,
3233
};
3334

3435
use crate::parser::ParserError;
@@ -77,10 +78,6 @@ pub struct CreateTableBuilder {
7778
pub constraints: Vec<TableConstraint>,
7879
pub hive_distribution: HiveDistributionStyle,
7980
pub hive_formats: Option<HiveFormat>,
80-
pub table_properties: Vec<SqlOption>,
81-
pub with_options: Vec<SqlOption>,
82-
pub options: Option<Vec<SqlOption>>,
83-
pub plain_options: Vec<SqlOption>,
8481
pub file_format: Option<FileFormat>,
8582
pub location: Option<String>,
8683
pub query: Option<Box<Query>>,
@@ -110,6 +107,7 @@ pub struct CreateTableBuilder {
110107
pub catalog: Option<String>,
111108
pub catalog_sync: Option<String>,
112109
pub storage_serialization_policy: Option<StorageSerializationPolicy>,
110+
pub table_options: CreateTableOptions,
113111
}
114112

115113
impl CreateTableBuilder {
@@ -128,9 +126,6 @@ impl CreateTableBuilder {
128126
constraints: vec![],
129127
hive_distribution: HiveDistributionStyle::NONE,
130128
hive_formats: None,
131-
table_properties: vec![],
132-
plain_options: vec![],
133-
with_options: vec![],
134129
file_format: None,
135130
location: None,
136131
query: None,
@@ -145,7 +140,6 @@ impl CreateTableBuilder {
145140
partition_by: None,
146141
cluster_by: None,
147142
clustered_by: None,
148-
options: None,
149143
strict: false,
150144
copy_grants: false,
151145
enable_schema_evolution: None,
@@ -161,6 +155,7 @@ impl CreateTableBuilder {
161155
catalog: None,
162156
catalog_sync: None,
163157
storage_serialization_policy: None,
158+
table_options: CreateTableOptions::None,
164159
}
165160
}
166161
pub fn or_replace(mut self, or_replace: bool) -> Self {
@@ -223,15 +218,6 @@ impl CreateTableBuilder {
223218
self
224219
}
225220

226-
pub fn table_properties(mut self, table_properties: Vec<SqlOption>) -> Self {
227-
self.table_properties = table_properties;
228-
self
229-
}
230-
231-
pub fn with_options(mut self, with_options: Vec<SqlOption>) -> Self {
232-
self.with_options = with_options;
233-
self
234-
}
235221
pub fn file_format(mut self, file_format: Option<FileFormat>) -> Self {
236222
self.file_format = file_format;
237223
self
@@ -301,16 +287,6 @@ impl CreateTableBuilder {
301287
self
302288
}
303289

304-
pub fn options(mut self, options: Option<Vec<SqlOption>>) -> Self {
305-
self.options = options;
306-
self
307-
}
308-
309-
pub fn plain_options(mut self, options: Vec<SqlOption>) -> Self {
310-
self.plain_options = options;
311-
self
312-
}
313-
314290
pub fn strict(mut self, strict: bool) -> Self {
315291
self.strict = strict;
316292
self
@@ -395,6 +371,11 @@ impl CreateTableBuilder {
395371
self
396372
}
397373

374+
pub fn table_options(mut self, table_options: CreateTableOptions) -> Self {
375+
self.table_options = table_options;
376+
self
377+
}
378+
398379
pub fn build(self) -> Statement {
399380
Statement::CreateTable(CreateTable {
400381
or_replace: self.or_replace,
@@ -410,8 +391,6 @@ impl CreateTableBuilder {
410391
constraints: self.constraints,
411392
hive_distribution: self.hive_distribution,
412393
hive_formats: self.hive_formats,
413-
table_properties: self.table_properties,
414-
with_options: self.with_options,
415394
file_format: self.file_format,
416395
location: self.location,
417396
query: self.query,
@@ -426,7 +405,6 @@ impl CreateTableBuilder {
426405
partition_by: self.partition_by,
427406
cluster_by: self.cluster_by,
428407
clustered_by: self.clustered_by,
429-
options: self.options,
430408
strict: self.strict,
431409
copy_grants: self.copy_grants,
432410
enable_schema_evolution: self.enable_schema_evolution,
@@ -442,7 +420,7 @@ impl CreateTableBuilder {
442420
catalog: self.catalog,
443421
catalog_sync: self.catalog_sync,
444422
storage_serialization_policy: self.storage_serialization_policy,
445-
plain_options: self.plain_options,
423+
table_options: self.table_options,
446424
})
447425
}
448426
}
@@ -468,8 +446,6 @@ impl TryFrom<Statement> for CreateTableBuilder {
468446
constraints,
469447
hive_distribution,
470448
hive_formats,
471-
table_properties,
472-
with_options,
473449
file_format,
474450
location,
475451
query,
@@ -484,7 +460,6 @@ impl TryFrom<Statement> for CreateTableBuilder {
484460
partition_by,
485461
cluster_by,
486462
clustered_by,
487-
options,
488463
strict,
489464
copy_grants,
490465
enable_schema_evolution,
@@ -500,7 +475,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
500475
catalog,
501476
catalog_sync,
502477
storage_serialization_policy,
503-
plain_options,
478+
table_options,
504479
}) => Ok(Self {
505480
or_replace,
506481
temporary,
@@ -513,8 +488,6 @@ impl TryFrom<Statement> for CreateTableBuilder {
513488
constraints,
514489
hive_distribution,
515490
hive_formats,
516-
table_properties,
517-
with_options,
518491
file_format,
519492
location,
520493
query,
@@ -529,7 +502,6 @@ impl TryFrom<Statement> for CreateTableBuilder {
529502
partition_by,
530503
cluster_by,
531504
clustered_by,
532-
options,
533505
strict,
534506
iceberg,
535507
copy_grants,
@@ -547,7 +519,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
547519
catalog,
548520
catalog_sync,
549521
storage_serialization_policy,
550-
plain_options,
522+
table_options,
551523
}),
552524
_ => Err(ParserError::ParserError(format!(
553525
"Expected create table statement, but received: {stmt}"
@@ -561,8 +533,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
561533
pub(crate) struct CreateTableConfiguration {
562534
pub partition_by: Option<Box<Expr>>,
563535
pub cluster_by: Option<WrappedCollection<Vec<Ident>>>,
564-
pub options: Option<Vec<SqlOption>>,
565-
pub plain_options: Vec<SqlOption>,
536+
pub table_options: CreateTableOptions,
566537
}
567538

568539
#[cfg(test)]

src/ast/mod.rs

+18
Original file line numberDiff line numberDiff line change
@@ -2557,6 +2557,18 @@ pub enum CreateTableOptions {
25572557
///
25582558
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
25592559
Options(Vec<SqlOption>),
2560+
2561+
/// Plain options, options which are not part on any declerative statement e.g. WITH/OPTIONS/...
2562+
/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
2563+
Plain(Vec<SqlOption>),
2564+
2565+
TableProperties(Vec<SqlOption>),
2566+
}
2567+
2568+
impl Default for CreateTableOptions {
2569+
fn default() -> Self {
2570+
Self::None
2571+
}
25602572
}
25612573

25622574
impl fmt::Display for CreateTableOptions {
@@ -2568,6 +2580,12 @@ impl fmt::Display for CreateTableOptions {
25682580
CreateTableOptions::Options(options) => {
25692581
write!(f, "OPTIONS({})", display_comma_separated(options))
25702582
}
2583+
CreateTableOptions::TableProperties(options) => {
2584+
write!(f, "TBLPROPERTIES ({})", display_comma_separated(options))
2585+
}
2586+
CreateTableOptions::Plain(options) => {
2587+
write!(f, "{}", display_separated(options, " "))
2588+
}
25712589
CreateTableOptions::None => Ok(()),
25722590
}
25732591
}

src/ast/spans.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -558,10 +558,8 @@ impl Spanned for CreateTable {
558558
constraints,
559559
hive_distribution: _, // hive specific
560560
hive_formats: _, // hive specific
561-
table_properties,
562-
with_options,
563-
file_format: _, // enum
564-
location: _, // string, no span
561+
file_format: _, // enum
562+
location: _, // string, no span
565563
query,
566564
without_rowid: _, // bool
567565
like,
@@ -574,7 +572,6 @@ impl Spanned for CreateTable {
574572
partition_by: _, // todo, BigQuery specific
575573
cluster_by: _, // todo, BigQuery specific
576574
clustered_by: _, // todo, Hive specific
577-
options: _, // todo, BigQuery specific
578575
strict: _, // bool
579576
copy_grants: _, // bool
580577
enable_schema_evolution: _, // bool
@@ -590,16 +587,14 @@ impl Spanned for CreateTable {
590587
catalog: _, // todo, Snowflake specific
591588
catalog_sync: _, // todo, Snowflake specific
592589
storage_serialization_policy: _,
593-
plain_options,
590+
table_options,
594591
} = self;
595592

596593
union_spans(
597594
core::iter::once(name.span())
595+
.chain(core::iter::once(table_options.span()))
598596
.chain(columns.iter().map(|i| i.span()))
599597
.chain(constraints.iter().map(|i| i.span()))
600-
.chain(table_properties.iter().map(|i| i.span()))
601-
.chain(with_options.iter().map(|i| i.span()))
602-
.chain(plain_options.iter().map(|i| i.span()))
603598
.chain(query.iter().map(|i| i.span()))
604599
.chain(like.iter().map(|i| i.span()))
605600
.chain(clone.iter().map(|i| i.span())),
@@ -1011,6 +1006,8 @@ impl Spanned for CreateTableOptions {
10111006
CreateTableOptions::None => Span::empty(),
10121007
CreateTableOptions::With(vec) => union_spans(vec.iter().map(|i| i.span())),
10131008
CreateTableOptions::Options(vec) => union_spans(vec.iter().map(|i| i.span())),
1009+
CreateTableOptions::Plain(vec) => union_spans(vec.iter().map(|i| i.span())),
1010+
CreateTableOptions::TableProperties(vec) => union_spans(vec.iter().map(|i| i.span())),
10141011
}
10151012
}
10161013
}

src/dialect/snowflake.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,13 @@ pub fn parse_create_table(
587587
}
588588
}
589589
}
590+
let table_options = if !plain_options.is_empty() {
591+
crate::ast::CreateTableOptions::Plain(plain_options)
592+
} else {
593+
crate::ast::CreateTableOptions::None
594+
};
590595

591-
builder = builder.plain_options(plain_options);
596+
builder = builder.table_options(table_options);
592597

593598
if iceberg && builder.base_location.is_none() {
594599
return Err(ParserError::ParserError(

0 commit comments

Comments
 (0)