1#[cfg(not(feature = "std"))]
19use alloc::{boxed::Box, format, string::String, vec, vec::Vec};
20
21#[cfg(feature = "serde")]
22use serde::{Deserialize, Serialize};
23
24#[cfg(feature = "visitor")]
25use sqlparser_derive::{Visit, VisitMut};
26
27use crate::ast::{
28 ClusteredBy, ColumnDef, CommentDef, CreateTable, CreateTableLikeKind, CreateTableOptions,
29 DistStyle, Expr, FileFormat, ForValues, HiveDistributionStyle, HiveFormat, Ident,
30 InitializeKind, ObjectName, OnCommit, OneOrManyWithParens, Query, RefreshModeKind,
31 RowAccessPolicy, Statement, StorageLifecyclePolicy, StorageSerializationPolicy,
32 TableConstraint, TableVersion, Tag, WithData, WrappedCollection,
33};
34
35use crate::parser::ParserError;
36
37#[derive(Debug, Clone, PartialEq, Eq, Hash)]
65#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
66#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
67pub struct CreateTableBuilder {
68 pub or_replace: bool,
70 pub temporary: bool,
72 pub unlogged: bool,
74 pub external: bool,
76 pub global: Option<bool>,
78 pub if_not_exists: bool,
80 pub transient: bool,
82 pub volatile: bool,
84 pub iceberg: bool,
86 pub snapshot: bool,
88 pub dynamic: bool,
90 pub name: ObjectName,
92 pub columns: Vec<ColumnDef>,
94 pub constraints: Vec<TableConstraint>,
96 pub hive_distribution: HiveDistributionStyle,
98 pub hive_formats: Option<HiveFormat>,
100 pub file_format: Option<FileFormat>,
102 pub location: Option<String>,
104 pub query: Option<Box<Query>>,
106 pub without_rowid: bool,
108 pub like: Option<CreateTableLikeKind>,
110 pub clone: Option<ObjectName>,
112 pub version: Option<TableVersion>,
114 pub comment: Option<CommentDef>,
116 pub on_commit: Option<OnCommit>,
118 pub on_cluster: Option<Ident>,
120 pub primary_key: Option<Box<Expr>>,
122 pub order_by: Option<OneOrManyWithParens<Expr>>,
124 pub partition_by: Option<Box<Expr>>,
126 pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
128 pub clustered_by: Option<ClusteredBy>,
130 pub inherits: Option<Vec<ObjectName>>,
132 pub partition_of: Option<ObjectName>,
134 pub for_values: Option<ForValues>,
136 pub strict: bool,
138 pub copy_grants: bool,
140 pub enable_schema_evolution: Option<bool>,
142 pub change_tracking: Option<bool>,
144 pub data_retention_time_in_days: Option<u64>,
146 pub max_data_extension_time_in_days: Option<u64>,
148 pub default_ddl_collation: Option<String>,
150 pub with_aggregation_policy: Option<ObjectName>,
152 pub with_row_access_policy: Option<RowAccessPolicy>,
154 pub with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>,
156 pub with_tags: Option<Vec<Tag>>,
158 pub base_location: Option<String>,
160 pub external_volume: Option<String>,
162 pub with_connection: Option<ObjectName>,
165 pub catalog: Option<String>,
167 pub catalog_sync: Option<String>,
169 pub storage_serialization_policy: Option<StorageSerializationPolicy>,
171 pub table_options: CreateTableOptions,
173 pub target_lag: Option<String>,
175 pub warehouse: Option<Ident>,
177 pub refresh_mode: Option<RefreshModeKind>,
179 pub initialize: Option<InitializeKind>,
181 pub require_user: bool,
183 pub diststyle: Option<DistStyle>,
185 pub distkey: Option<Expr>,
187 pub sortkey: Option<Vec<Expr>>,
189 pub backup: Option<bool>,
191 pub multiset: Option<bool>,
193 pub fallback: Option<bool>,
195 pub with_data: Option<WithData>,
197}
198
199impl CreateTableBuilder {
200 pub fn new(name: ObjectName) -> Self {
202 Self {
203 or_replace: false,
204 temporary: false,
205 unlogged: false,
206 external: false,
207 global: None,
208 if_not_exists: false,
209 transient: false,
210 volatile: false,
211 iceberg: false,
212 snapshot: false,
213 dynamic: false,
214 name,
215 columns: vec![],
216 constraints: vec![],
217 hive_distribution: HiveDistributionStyle::NONE,
218 hive_formats: None,
219 file_format: None,
220 location: None,
221 query: None,
222 without_rowid: false,
223 like: None,
224 clone: None,
225 version: None,
226 comment: None,
227 on_commit: None,
228 on_cluster: None,
229 primary_key: None,
230 order_by: None,
231 partition_by: None,
232 cluster_by: None,
233 clustered_by: None,
234 inherits: None,
235 partition_of: None,
236 for_values: None,
237 strict: false,
238 copy_grants: false,
239 enable_schema_evolution: None,
240 change_tracking: None,
241 data_retention_time_in_days: None,
242 max_data_extension_time_in_days: None,
243 default_ddl_collation: None,
244 with_aggregation_policy: None,
245 with_row_access_policy: None,
246 with_storage_lifecycle_policy: None,
247 with_tags: None,
248 base_location: None,
249 external_volume: None,
250 with_connection: None,
251 catalog: None,
252 catalog_sync: None,
253 storage_serialization_policy: None,
254 table_options: CreateTableOptions::None,
255 target_lag: None,
256 warehouse: None,
257 refresh_mode: None,
258 initialize: None,
259 require_user: false,
260 diststyle: None,
261 distkey: None,
262 sortkey: None,
263 backup: None,
264 multiset: None,
265 fallback: None,
266 with_data: None,
267 }
268 }
269 pub fn or_replace(mut self, or_replace: bool) -> Self {
271 self.or_replace = or_replace;
272 self
273 }
274 pub fn temporary(mut self, temporary: bool) -> Self {
276 self.temporary = temporary;
277 self
278 }
279 pub fn unlogged(mut self, unlogged: bool) -> Self {
281 self.unlogged = unlogged;
282 self
283 }
284 pub fn external(mut self, external: bool) -> Self {
286 self.external = external;
287 self
288 }
289 pub fn global(mut self, global: Option<bool>) -> Self {
291 self.global = global;
292 self
293 }
294 pub fn if_not_exists(mut self, if_not_exists: bool) -> Self {
296 self.if_not_exists = if_not_exists;
297 self
298 }
299 pub fn transient(mut self, transient: bool) -> Self {
301 self.transient = transient;
302 self
303 }
304 pub fn volatile(mut self, volatile: bool) -> Self {
306 self.volatile = volatile;
307 self
308 }
309 pub fn iceberg(mut self, iceberg: bool) -> Self {
311 self.iceberg = iceberg;
312 self
313 }
314 pub fn snapshot(mut self, snapshot: bool) -> Self {
316 self.snapshot = snapshot;
317 self
318 }
319 pub fn dynamic(mut self, dynamic: bool) -> Self {
321 self.dynamic = dynamic;
322 self
323 }
324 pub fn columns(mut self, columns: Vec<ColumnDef>) -> Self {
326 self.columns = columns;
327 self
328 }
329 pub fn constraints(mut self, constraints: Vec<TableConstraint>) -> Self {
331 self.constraints = constraints;
332 self
333 }
334 pub fn hive_distribution(mut self, hive_distribution: HiveDistributionStyle) -> Self {
336 self.hive_distribution = hive_distribution;
337 self
338 }
339 pub fn hive_formats(mut self, hive_formats: Option<HiveFormat>) -> Self {
341 self.hive_formats = hive_formats;
342 self
343 }
344 pub fn file_format(mut self, file_format: Option<FileFormat>) -> Self {
346 self.file_format = file_format;
347 self
348 }
349 pub fn location(mut self, location: Option<String>) -> Self {
351 self.location = location;
352 self
353 }
354 pub fn query(mut self, query: Option<Box<Query>>) -> Self {
356 self.query = query;
357 self
358 }
359 pub fn without_rowid(mut self, without_rowid: bool) -> Self {
361 self.without_rowid = without_rowid;
362 self
363 }
364 pub fn like(mut self, like: Option<CreateTableLikeKind>) -> Self {
366 self.like = like;
367 self
368 }
369 pub fn clone_clause(mut self, clone: Option<ObjectName>) -> Self {
372 self.clone = clone;
373 self
374 }
375 pub fn version(mut self, version: Option<TableVersion>) -> Self {
377 self.version = version;
378 self
379 }
380 pub fn comment_after_column_def(mut self, comment: Option<CommentDef>) -> Self {
382 self.comment = comment;
383 self
384 }
385 pub fn on_commit(mut self, on_commit: Option<OnCommit>) -> Self {
387 self.on_commit = on_commit;
388 self
389 }
390 pub fn on_cluster(mut self, on_cluster: Option<Ident>) -> Self {
392 self.on_cluster = on_cluster;
393 self
394 }
395 pub fn primary_key(mut self, primary_key: Option<Box<Expr>>) -> Self {
397 self.primary_key = primary_key;
398 self
399 }
400 pub fn order_by(mut self, order_by: Option<OneOrManyWithParens<Expr>>) -> Self {
402 self.order_by = order_by;
403 self
404 }
405 pub fn partition_by(mut self, partition_by: Option<Box<Expr>>) -> Self {
407 self.partition_by = partition_by;
408 self
409 }
410 pub fn cluster_by(mut self, cluster_by: Option<WrappedCollection<Vec<Expr>>>) -> Self {
412 self.cluster_by = cluster_by;
413 self
414 }
415 pub fn clustered_by(mut self, clustered_by: Option<ClusteredBy>) -> Self {
417 self.clustered_by = clustered_by;
418 self
419 }
420 pub fn inherits(mut self, inherits: Option<Vec<ObjectName>>) -> Self {
422 self.inherits = inherits;
423 self
424 }
425
426 pub fn partition_of(mut self, partition_of: Option<ObjectName>) -> Self {
428 self.partition_of = partition_of;
429 self
430 }
431
432 pub fn for_values(mut self, for_values: Option<ForValues>) -> Self {
434 self.for_values = for_values;
435 self
436 }
437
438 pub fn strict(mut self, strict: bool) -> Self {
440 self.strict = strict;
441 self
442 }
443 pub fn copy_grants(mut self, copy_grants: bool) -> Self {
445 self.copy_grants = copy_grants;
446 self
447 }
448 pub fn enable_schema_evolution(mut self, enable_schema_evolution: Option<bool>) -> Self {
450 self.enable_schema_evolution = enable_schema_evolution;
451 self
452 }
453 pub fn change_tracking(mut self, change_tracking: Option<bool>) -> Self {
455 self.change_tracking = change_tracking;
456 self
457 }
458 pub fn data_retention_time_in_days(mut self, data_retention_time_in_days: Option<u64>) -> Self {
460 self.data_retention_time_in_days = data_retention_time_in_days;
461 self
462 }
463 pub fn max_data_extension_time_in_days(
465 mut self,
466 max_data_extension_time_in_days: Option<u64>,
467 ) -> Self {
468 self.max_data_extension_time_in_days = max_data_extension_time_in_days;
469 self
470 }
471 pub fn default_ddl_collation(mut self, default_ddl_collation: Option<String>) -> Self {
473 self.default_ddl_collation = default_ddl_collation;
474 self
475 }
476 pub fn with_aggregation_policy(mut self, with_aggregation_policy: Option<ObjectName>) -> Self {
478 self.with_aggregation_policy = with_aggregation_policy;
479 self
480 }
481 pub fn with_row_access_policy(
483 mut self,
484 with_row_access_policy: Option<RowAccessPolicy>,
485 ) -> Self {
486 self.with_row_access_policy = with_row_access_policy;
487 self
488 }
489 pub fn with_storage_lifecycle_policy(
491 mut self,
492 with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>,
493 ) -> Self {
494 self.with_storage_lifecycle_policy = with_storage_lifecycle_policy;
495 self
496 }
497 pub fn with_tags(mut self, with_tags: Option<Vec<Tag>>) -> Self {
499 self.with_tags = with_tags;
500 self
501 }
502 pub fn base_location(mut self, base_location: Option<String>) -> Self {
504 self.base_location = base_location;
505 self
506 }
507 pub fn external_volume(mut self, external_volume: Option<String>) -> Self {
509 self.external_volume = external_volume;
510 self
511 }
512 pub fn with_connection(mut self, with_connection: Option<ObjectName>) -> Self {
514 self.with_connection = with_connection;
515 self
516 }
517 pub fn catalog(mut self, catalog: Option<String>) -> Self {
519 self.catalog = catalog;
520 self
521 }
522 pub fn catalog_sync(mut self, catalog_sync: Option<String>) -> Self {
524 self.catalog_sync = catalog_sync;
525 self
526 }
527 pub fn storage_serialization_policy(
529 mut self,
530 storage_serialization_policy: Option<StorageSerializationPolicy>,
531 ) -> Self {
532 self.storage_serialization_policy = storage_serialization_policy;
533 self
534 }
535 pub fn table_options(mut self, table_options: CreateTableOptions) -> Self {
537 self.table_options = table_options;
538 self
539 }
540 pub fn target_lag(mut self, target_lag: Option<String>) -> Self {
542 self.target_lag = target_lag;
543 self
544 }
545 pub fn warehouse(mut self, warehouse: Option<Ident>) -> Self {
547 self.warehouse = warehouse;
548 self
549 }
550 pub fn refresh_mode(mut self, refresh_mode: Option<RefreshModeKind>) -> Self {
552 self.refresh_mode = refresh_mode;
553 self
554 }
555 pub fn initialize(mut self, initialize: Option<InitializeKind>) -> Self {
557 self.initialize = initialize;
558 self
559 }
560 pub fn require_user(mut self, require_user: bool) -> Self {
562 self.require_user = require_user;
563 self
564 }
565 pub fn diststyle(mut self, diststyle: Option<DistStyle>) -> Self {
567 self.diststyle = diststyle;
568 self
569 }
570 pub fn distkey(mut self, distkey: Option<Expr>) -> Self {
572 self.distkey = distkey;
573 self
574 }
575 pub fn sortkey(mut self, sortkey: Option<Vec<Expr>>) -> Self {
577 self.sortkey = sortkey;
578 self
579 }
580 pub fn backup(mut self, backup: Option<bool>) -> Self {
582 self.backup = backup;
583 self
584 }
585 pub fn multiset(mut self, multiset: Option<bool>) -> Self {
588 self.multiset = multiset;
589 self
590 }
591 pub fn fallback(mut self, fallback: Option<bool>) -> Self {
593 self.fallback = fallback;
594 self
595 }
596 pub fn with_data(mut self, with_data: Option<WithData>) -> Self {
598 self.with_data = with_data;
599 self
600 }
601 pub fn build(self) -> CreateTable {
603 CreateTable {
604 or_replace: self.or_replace,
605 temporary: self.temporary,
606 unlogged: self.unlogged,
607 external: self.external,
608 global: self.global,
609 if_not_exists: self.if_not_exists,
610 transient: self.transient,
611 volatile: self.volatile,
612 iceberg: self.iceberg,
613 snapshot: self.snapshot,
614 dynamic: self.dynamic,
615 name: self.name,
616 columns: self.columns,
617 constraints: self.constraints,
618 hive_distribution: self.hive_distribution,
619 hive_formats: self.hive_formats,
620 file_format: self.file_format,
621 location: self.location,
622 query: self.query,
623 without_rowid: self.without_rowid,
624 like: self.like,
625 clone: self.clone,
626 version: self.version,
627 comment: self.comment,
628 on_commit: self.on_commit,
629 on_cluster: self.on_cluster,
630 primary_key: self.primary_key,
631 order_by: self.order_by,
632 partition_by: self.partition_by,
633 cluster_by: self.cluster_by,
634 clustered_by: self.clustered_by,
635 inherits: self.inherits,
636 partition_of: self.partition_of,
637 for_values: self.for_values,
638 strict: self.strict,
639 copy_grants: self.copy_grants,
640 enable_schema_evolution: self.enable_schema_evolution,
641 change_tracking: self.change_tracking,
642 data_retention_time_in_days: self.data_retention_time_in_days,
643 max_data_extension_time_in_days: self.max_data_extension_time_in_days,
644 default_ddl_collation: self.default_ddl_collation,
645 with_aggregation_policy: self.with_aggregation_policy,
646 with_row_access_policy: self.with_row_access_policy,
647 with_storage_lifecycle_policy: self.with_storage_lifecycle_policy,
648 with_tags: self.with_tags,
649 base_location: self.base_location,
650 external_volume: self.external_volume,
651 with_connection: self.with_connection,
652 catalog: self.catalog,
653 catalog_sync: self.catalog_sync,
654 storage_serialization_policy: self.storage_serialization_policy,
655 table_options: self.table_options,
656 target_lag: self.target_lag,
657 warehouse: self.warehouse,
658 refresh_mode: self.refresh_mode,
659 initialize: self.initialize,
660 require_user: self.require_user,
661 diststyle: self.diststyle,
662 distkey: self.distkey,
663 sortkey: self.sortkey,
664 backup: self.backup,
665 multiset: self.multiset,
666 fallback: self.fallback,
667 with_data: self.with_data,
668 }
669 }
670}
671
672impl TryFrom<Statement> for CreateTableBuilder {
673 type Error = ParserError;
674
675 fn try_from(stmt: Statement) -> Result<Self, Self::Error> {
678 match stmt {
679 Statement::CreateTable(create_table) => Ok(create_table.into()),
680 _ => Err(ParserError::ParserError(format!(
681 "Expected create table statement, but received: {stmt}"
682 ))),
683 }
684 }
685}
686
687impl From<CreateTable> for CreateTableBuilder {
688 fn from(table: CreateTable) -> Self {
689 Self {
690 or_replace: table.or_replace,
691 temporary: table.temporary,
692 unlogged: table.unlogged,
693 external: table.external,
694 global: table.global,
695 if_not_exists: table.if_not_exists,
696 transient: table.transient,
697 volatile: table.volatile,
698 iceberg: table.iceberg,
699 snapshot: table.snapshot,
700 dynamic: table.dynamic,
701 name: table.name,
702 columns: table.columns,
703 constraints: table.constraints,
704 hive_distribution: table.hive_distribution,
705 hive_formats: table.hive_formats,
706 file_format: table.file_format,
707 location: table.location,
708 query: table.query,
709 without_rowid: table.without_rowid,
710 like: table.like,
711 clone: table.clone,
712 version: table.version,
713 comment: table.comment,
714 on_commit: table.on_commit,
715 on_cluster: table.on_cluster,
716 primary_key: table.primary_key,
717 order_by: table.order_by,
718 partition_by: table.partition_by,
719 cluster_by: table.cluster_by,
720 clustered_by: table.clustered_by,
721 inherits: table.inherits,
722 partition_of: table.partition_of,
723 for_values: table.for_values,
724 strict: table.strict,
725 copy_grants: table.copy_grants,
726 enable_schema_evolution: table.enable_schema_evolution,
727 change_tracking: table.change_tracking,
728 data_retention_time_in_days: table.data_retention_time_in_days,
729 max_data_extension_time_in_days: table.max_data_extension_time_in_days,
730 default_ddl_collation: table.default_ddl_collation,
731 with_aggregation_policy: table.with_aggregation_policy,
732 with_row_access_policy: table.with_row_access_policy,
733 with_storage_lifecycle_policy: table.with_storage_lifecycle_policy,
734 with_tags: table.with_tags,
735 base_location: table.base_location,
736 external_volume: table.external_volume,
737 with_connection: table.with_connection,
738 catalog: table.catalog,
739 catalog_sync: table.catalog_sync,
740 storage_serialization_policy: table.storage_serialization_policy,
741 table_options: table.table_options,
742 target_lag: table.target_lag,
743 warehouse: table.warehouse,
744 refresh_mode: table.refresh_mode,
745 initialize: table.initialize,
746 require_user: table.require_user,
747 diststyle: table.diststyle,
748 distkey: table.distkey,
749 sortkey: table.sortkey,
750 backup: table.backup,
751 multiset: table.multiset,
752 fallback: table.fallback,
753 with_data: table.with_data,
754 }
755 }
756}
757
758#[derive(Default)]
760pub(crate) struct CreateTableConfiguration {
761 pub partition_by: Option<Box<Expr>>,
762 pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
763 pub inherits: Option<Vec<ObjectName>>,
764 pub table_options: CreateTableOptions,
765}
766
767#[cfg(test)]
768mod tests {
769 use crate::ast::helpers::stmt_create_table::CreateTableBuilder;
770 use crate::ast::{Ident, ObjectName, Statement};
771 use crate::parser::ParserError;
772
773 #[test]
774 pub fn test_from_valid_statement() {
775 let builder = CreateTableBuilder::new(ObjectName::from(vec![Ident::new("table_name")]));
776
777 let create_table = builder.clone().build();
778 let stmt: Statement = create_table.into();
779
780 assert_eq!(builder, CreateTableBuilder::try_from(stmt).unwrap());
781 }
782
783 #[test]
784 pub fn test_from_invalid_statement() {
785 let stmt = Statement::Commit {
786 chain: false,
787 end: false,
788 modifier: None,
789 };
790
791 assert_eq!(
792 CreateTableBuilder::try_from(stmt).unwrap_err(),
793 ParserError::ParserError(
794 "Expected create table statement, but received: COMMIT".to_owned()
795 )
796 );
797 }
798}