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 external: bool,
74 pub global: Option<bool>,
76 pub if_not_exists: bool,
78 pub transient: bool,
80 pub volatile: bool,
82 pub iceberg: bool,
84 pub snapshot: bool,
86 pub dynamic: bool,
88 pub name: ObjectName,
90 pub columns: Vec<ColumnDef>,
92 pub constraints: Vec<TableConstraint>,
94 pub hive_distribution: HiveDistributionStyle,
96 pub hive_formats: Option<HiveFormat>,
98 pub file_format: Option<FileFormat>,
100 pub location: Option<String>,
102 pub query: Option<Box<Query>>,
104 pub without_rowid: bool,
106 pub like: Option<CreateTableLikeKind>,
108 pub clone: Option<ObjectName>,
110 pub version: Option<TableVersion>,
112 pub comment: Option<CommentDef>,
114 pub on_commit: Option<OnCommit>,
116 pub on_cluster: Option<Ident>,
118 pub primary_key: Option<Box<Expr>>,
120 pub order_by: Option<OneOrManyWithParens<Expr>>,
122 pub partition_by: Option<Box<Expr>>,
124 pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
126 pub clustered_by: Option<ClusteredBy>,
128 pub inherits: Option<Vec<ObjectName>>,
130 pub partition_of: Option<ObjectName>,
132 pub for_values: Option<ForValues>,
134 pub strict: bool,
136 pub copy_grants: bool,
138 pub enable_schema_evolution: Option<bool>,
140 pub change_tracking: Option<bool>,
142 pub data_retention_time_in_days: Option<u64>,
144 pub max_data_extension_time_in_days: Option<u64>,
146 pub default_ddl_collation: Option<String>,
148 pub with_aggregation_policy: Option<ObjectName>,
150 pub with_row_access_policy: Option<RowAccessPolicy>,
152 pub with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>,
154 pub with_tags: Option<Vec<Tag>>,
156 pub base_location: Option<String>,
158 pub external_volume: Option<String>,
160 pub with_connection: Option<ObjectName>,
163 pub catalog: Option<String>,
165 pub catalog_sync: Option<String>,
167 pub storage_serialization_policy: Option<StorageSerializationPolicy>,
169 pub table_options: CreateTableOptions,
171 pub target_lag: Option<String>,
173 pub warehouse: Option<Ident>,
175 pub refresh_mode: Option<RefreshModeKind>,
177 pub initialize: Option<InitializeKind>,
179 pub require_user: bool,
181 pub diststyle: Option<DistStyle>,
183 pub distkey: Option<Expr>,
185 pub sortkey: Option<Vec<Expr>>,
187 pub backup: Option<bool>,
189 pub multiset: Option<bool>,
191 pub fallback: Option<bool>,
193 pub with_data: Option<WithData>,
195}
196
197impl CreateTableBuilder {
198 pub fn new(name: ObjectName) -> Self {
200 Self {
201 or_replace: false,
202 temporary: false,
203 external: false,
204 global: None,
205 if_not_exists: false,
206 transient: false,
207 volatile: false,
208 iceberg: false,
209 snapshot: false,
210 dynamic: false,
211 name,
212 columns: vec![],
213 constraints: vec![],
214 hive_distribution: HiveDistributionStyle::NONE,
215 hive_formats: None,
216 file_format: None,
217 location: None,
218 query: None,
219 without_rowid: false,
220 like: None,
221 clone: None,
222 version: None,
223 comment: None,
224 on_commit: None,
225 on_cluster: None,
226 primary_key: None,
227 order_by: None,
228 partition_by: None,
229 cluster_by: None,
230 clustered_by: None,
231 inherits: None,
232 partition_of: None,
233 for_values: None,
234 strict: false,
235 copy_grants: false,
236 enable_schema_evolution: None,
237 change_tracking: None,
238 data_retention_time_in_days: None,
239 max_data_extension_time_in_days: None,
240 default_ddl_collation: None,
241 with_aggregation_policy: None,
242 with_row_access_policy: None,
243 with_storage_lifecycle_policy: None,
244 with_tags: None,
245 base_location: None,
246 external_volume: None,
247 with_connection: None,
248 catalog: None,
249 catalog_sync: None,
250 storage_serialization_policy: None,
251 table_options: CreateTableOptions::None,
252 target_lag: None,
253 warehouse: None,
254 refresh_mode: None,
255 initialize: None,
256 require_user: false,
257 diststyle: None,
258 distkey: None,
259 sortkey: None,
260 backup: None,
261 multiset: None,
262 fallback: None,
263 with_data: None,
264 }
265 }
266 pub fn or_replace(mut self, or_replace: bool) -> Self {
268 self.or_replace = or_replace;
269 self
270 }
271 pub fn temporary(mut self, temporary: bool) -> Self {
273 self.temporary = temporary;
274 self
275 }
276 pub fn external(mut self, external: bool) -> Self {
278 self.external = external;
279 self
280 }
281 pub fn global(mut self, global: Option<bool>) -> Self {
283 self.global = global;
284 self
285 }
286 pub fn if_not_exists(mut self, if_not_exists: bool) -> Self {
288 self.if_not_exists = if_not_exists;
289 self
290 }
291 pub fn transient(mut self, transient: bool) -> Self {
293 self.transient = transient;
294 self
295 }
296 pub fn volatile(mut self, volatile: bool) -> Self {
298 self.volatile = volatile;
299 self
300 }
301 pub fn iceberg(mut self, iceberg: bool) -> Self {
303 self.iceberg = iceberg;
304 self
305 }
306 pub fn snapshot(mut self, snapshot: bool) -> Self {
308 self.snapshot = snapshot;
309 self
310 }
311 pub fn dynamic(mut self, dynamic: bool) -> Self {
313 self.dynamic = dynamic;
314 self
315 }
316 pub fn columns(mut self, columns: Vec<ColumnDef>) -> Self {
318 self.columns = columns;
319 self
320 }
321 pub fn constraints(mut self, constraints: Vec<TableConstraint>) -> Self {
323 self.constraints = constraints;
324 self
325 }
326 pub fn hive_distribution(mut self, hive_distribution: HiveDistributionStyle) -> Self {
328 self.hive_distribution = hive_distribution;
329 self
330 }
331 pub fn hive_formats(mut self, hive_formats: Option<HiveFormat>) -> Self {
333 self.hive_formats = hive_formats;
334 self
335 }
336 pub fn file_format(mut self, file_format: Option<FileFormat>) -> Self {
338 self.file_format = file_format;
339 self
340 }
341 pub fn location(mut self, location: Option<String>) -> Self {
343 self.location = location;
344 self
345 }
346 pub fn query(mut self, query: Option<Box<Query>>) -> Self {
348 self.query = query;
349 self
350 }
351 pub fn without_rowid(mut self, without_rowid: bool) -> Self {
353 self.without_rowid = without_rowid;
354 self
355 }
356 pub fn like(mut self, like: Option<CreateTableLikeKind>) -> Self {
358 self.like = like;
359 self
360 }
361 pub fn clone_clause(mut self, clone: Option<ObjectName>) -> Self {
364 self.clone = clone;
365 self
366 }
367 pub fn version(mut self, version: Option<TableVersion>) -> Self {
369 self.version = version;
370 self
371 }
372 pub fn comment_after_column_def(mut self, comment: Option<CommentDef>) -> Self {
374 self.comment = comment;
375 self
376 }
377 pub fn on_commit(mut self, on_commit: Option<OnCommit>) -> Self {
379 self.on_commit = on_commit;
380 self
381 }
382 pub fn on_cluster(mut self, on_cluster: Option<Ident>) -> Self {
384 self.on_cluster = on_cluster;
385 self
386 }
387 pub fn primary_key(mut self, primary_key: Option<Box<Expr>>) -> Self {
389 self.primary_key = primary_key;
390 self
391 }
392 pub fn order_by(mut self, order_by: Option<OneOrManyWithParens<Expr>>) -> Self {
394 self.order_by = order_by;
395 self
396 }
397 pub fn partition_by(mut self, partition_by: Option<Box<Expr>>) -> Self {
399 self.partition_by = partition_by;
400 self
401 }
402 pub fn cluster_by(mut self, cluster_by: Option<WrappedCollection<Vec<Expr>>>) -> Self {
404 self.cluster_by = cluster_by;
405 self
406 }
407 pub fn clustered_by(mut self, clustered_by: Option<ClusteredBy>) -> Self {
409 self.clustered_by = clustered_by;
410 self
411 }
412 pub fn inherits(mut self, inherits: Option<Vec<ObjectName>>) -> Self {
414 self.inherits = inherits;
415 self
416 }
417
418 pub fn partition_of(mut self, partition_of: Option<ObjectName>) -> Self {
420 self.partition_of = partition_of;
421 self
422 }
423
424 pub fn for_values(mut self, for_values: Option<ForValues>) -> Self {
426 self.for_values = for_values;
427 self
428 }
429
430 pub fn strict(mut self, strict: bool) -> Self {
432 self.strict = strict;
433 self
434 }
435 pub fn copy_grants(mut self, copy_grants: bool) -> Self {
437 self.copy_grants = copy_grants;
438 self
439 }
440 pub fn enable_schema_evolution(mut self, enable_schema_evolution: Option<bool>) -> Self {
442 self.enable_schema_evolution = enable_schema_evolution;
443 self
444 }
445 pub fn change_tracking(mut self, change_tracking: Option<bool>) -> Self {
447 self.change_tracking = change_tracking;
448 self
449 }
450 pub fn data_retention_time_in_days(mut self, data_retention_time_in_days: Option<u64>) -> Self {
452 self.data_retention_time_in_days = data_retention_time_in_days;
453 self
454 }
455 pub fn max_data_extension_time_in_days(
457 mut self,
458 max_data_extension_time_in_days: Option<u64>,
459 ) -> Self {
460 self.max_data_extension_time_in_days = max_data_extension_time_in_days;
461 self
462 }
463 pub fn default_ddl_collation(mut self, default_ddl_collation: Option<String>) -> Self {
465 self.default_ddl_collation = default_ddl_collation;
466 self
467 }
468 pub fn with_aggregation_policy(mut self, with_aggregation_policy: Option<ObjectName>) -> Self {
470 self.with_aggregation_policy = with_aggregation_policy;
471 self
472 }
473 pub fn with_row_access_policy(
475 mut self,
476 with_row_access_policy: Option<RowAccessPolicy>,
477 ) -> Self {
478 self.with_row_access_policy = with_row_access_policy;
479 self
480 }
481 pub fn with_storage_lifecycle_policy(
483 mut self,
484 with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>,
485 ) -> Self {
486 self.with_storage_lifecycle_policy = with_storage_lifecycle_policy;
487 self
488 }
489 pub fn with_tags(mut self, with_tags: Option<Vec<Tag>>) -> Self {
491 self.with_tags = with_tags;
492 self
493 }
494 pub fn base_location(mut self, base_location: Option<String>) -> Self {
496 self.base_location = base_location;
497 self
498 }
499 pub fn external_volume(mut self, external_volume: Option<String>) -> Self {
501 self.external_volume = external_volume;
502 self
503 }
504 pub fn with_connection(mut self, with_connection: Option<ObjectName>) -> Self {
506 self.with_connection = with_connection;
507 self
508 }
509 pub fn catalog(mut self, catalog: Option<String>) -> Self {
511 self.catalog = catalog;
512 self
513 }
514 pub fn catalog_sync(mut self, catalog_sync: Option<String>) -> Self {
516 self.catalog_sync = catalog_sync;
517 self
518 }
519 pub fn storage_serialization_policy(
521 mut self,
522 storage_serialization_policy: Option<StorageSerializationPolicy>,
523 ) -> Self {
524 self.storage_serialization_policy = storage_serialization_policy;
525 self
526 }
527 pub fn table_options(mut self, table_options: CreateTableOptions) -> Self {
529 self.table_options = table_options;
530 self
531 }
532 pub fn target_lag(mut self, target_lag: Option<String>) -> Self {
534 self.target_lag = target_lag;
535 self
536 }
537 pub fn warehouse(mut self, warehouse: Option<Ident>) -> Self {
539 self.warehouse = warehouse;
540 self
541 }
542 pub fn refresh_mode(mut self, refresh_mode: Option<RefreshModeKind>) -> Self {
544 self.refresh_mode = refresh_mode;
545 self
546 }
547 pub fn initialize(mut self, initialize: Option<InitializeKind>) -> Self {
549 self.initialize = initialize;
550 self
551 }
552 pub fn require_user(mut self, require_user: bool) -> Self {
554 self.require_user = require_user;
555 self
556 }
557 pub fn diststyle(mut self, diststyle: Option<DistStyle>) -> Self {
559 self.diststyle = diststyle;
560 self
561 }
562 pub fn distkey(mut self, distkey: Option<Expr>) -> Self {
564 self.distkey = distkey;
565 self
566 }
567 pub fn sortkey(mut self, sortkey: Option<Vec<Expr>>) -> Self {
569 self.sortkey = sortkey;
570 self
571 }
572 pub fn backup(mut self, backup: Option<bool>) -> Self {
574 self.backup = backup;
575 self
576 }
577 pub fn multiset(mut self, multiset: Option<bool>) -> Self {
580 self.multiset = multiset;
581 self
582 }
583 pub fn fallback(mut self, fallback: Option<bool>) -> Self {
585 self.fallback = fallback;
586 self
587 }
588 pub fn with_data(mut self, with_data: Option<WithData>) -> Self {
590 self.with_data = with_data;
591 self
592 }
593 pub fn build(self) -> CreateTable {
595 CreateTable {
596 or_replace: self.or_replace,
597 temporary: self.temporary,
598 external: self.external,
599 global: self.global,
600 if_not_exists: self.if_not_exists,
601 transient: self.transient,
602 volatile: self.volatile,
603 iceberg: self.iceberg,
604 snapshot: self.snapshot,
605 dynamic: self.dynamic,
606 name: self.name,
607 columns: self.columns,
608 constraints: self.constraints,
609 hive_distribution: self.hive_distribution,
610 hive_formats: self.hive_formats,
611 file_format: self.file_format,
612 location: self.location,
613 query: self.query,
614 without_rowid: self.without_rowid,
615 like: self.like,
616 clone: self.clone,
617 version: self.version,
618 comment: self.comment,
619 on_commit: self.on_commit,
620 on_cluster: self.on_cluster,
621 primary_key: self.primary_key,
622 order_by: self.order_by,
623 partition_by: self.partition_by,
624 cluster_by: self.cluster_by,
625 clustered_by: self.clustered_by,
626 inherits: self.inherits,
627 partition_of: self.partition_of,
628 for_values: self.for_values,
629 strict: self.strict,
630 copy_grants: self.copy_grants,
631 enable_schema_evolution: self.enable_schema_evolution,
632 change_tracking: self.change_tracking,
633 data_retention_time_in_days: self.data_retention_time_in_days,
634 max_data_extension_time_in_days: self.max_data_extension_time_in_days,
635 default_ddl_collation: self.default_ddl_collation,
636 with_aggregation_policy: self.with_aggregation_policy,
637 with_row_access_policy: self.with_row_access_policy,
638 with_storage_lifecycle_policy: self.with_storage_lifecycle_policy,
639 with_tags: self.with_tags,
640 base_location: self.base_location,
641 external_volume: self.external_volume,
642 with_connection: self.with_connection,
643 catalog: self.catalog,
644 catalog_sync: self.catalog_sync,
645 storage_serialization_policy: self.storage_serialization_policy,
646 table_options: self.table_options,
647 target_lag: self.target_lag,
648 warehouse: self.warehouse,
649 refresh_mode: self.refresh_mode,
650 initialize: self.initialize,
651 require_user: self.require_user,
652 diststyle: self.diststyle,
653 distkey: self.distkey,
654 sortkey: self.sortkey,
655 backup: self.backup,
656 multiset: self.multiset,
657 fallback: self.fallback,
658 with_data: self.with_data,
659 }
660 }
661}
662
663impl TryFrom<Statement> for CreateTableBuilder {
664 type Error = ParserError;
665
666 fn try_from(stmt: Statement) -> Result<Self, Self::Error> {
669 match stmt {
670 Statement::CreateTable(create_table) => Ok(create_table.into()),
671 _ => Err(ParserError::ParserError(format!(
672 "Expected create table statement, but received: {stmt}"
673 ))),
674 }
675 }
676}
677
678impl From<CreateTable> for CreateTableBuilder {
679 fn from(table: CreateTable) -> Self {
680 Self {
681 or_replace: table.or_replace,
682 temporary: table.temporary,
683 external: table.external,
684 global: table.global,
685 if_not_exists: table.if_not_exists,
686 transient: table.transient,
687 volatile: table.volatile,
688 iceberg: table.iceberg,
689 snapshot: table.snapshot,
690 dynamic: table.dynamic,
691 name: table.name,
692 columns: table.columns,
693 constraints: table.constraints,
694 hive_distribution: table.hive_distribution,
695 hive_formats: table.hive_formats,
696 file_format: table.file_format,
697 location: table.location,
698 query: table.query,
699 without_rowid: table.without_rowid,
700 like: table.like,
701 clone: table.clone,
702 version: table.version,
703 comment: table.comment,
704 on_commit: table.on_commit,
705 on_cluster: table.on_cluster,
706 primary_key: table.primary_key,
707 order_by: table.order_by,
708 partition_by: table.partition_by,
709 cluster_by: table.cluster_by,
710 clustered_by: table.clustered_by,
711 inherits: table.inherits,
712 partition_of: table.partition_of,
713 for_values: table.for_values,
714 strict: table.strict,
715 copy_grants: table.copy_grants,
716 enable_schema_evolution: table.enable_schema_evolution,
717 change_tracking: table.change_tracking,
718 data_retention_time_in_days: table.data_retention_time_in_days,
719 max_data_extension_time_in_days: table.max_data_extension_time_in_days,
720 default_ddl_collation: table.default_ddl_collation,
721 with_aggregation_policy: table.with_aggregation_policy,
722 with_row_access_policy: table.with_row_access_policy,
723 with_storage_lifecycle_policy: table.with_storage_lifecycle_policy,
724 with_tags: table.with_tags,
725 base_location: table.base_location,
726 external_volume: table.external_volume,
727 with_connection: table.with_connection,
728 catalog: table.catalog,
729 catalog_sync: table.catalog_sync,
730 storage_serialization_policy: table.storage_serialization_policy,
731 table_options: table.table_options,
732 target_lag: table.target_lag,
733 warehouse: table.warehouse,
734 refresh_mode: table.refresh_mode,
735 initialize: table.initialize,
736 require_user: table.require_user,
737 diststyle: table.diststyle,
738 distkey: table.distkey,
739 sortkey: table.sortkey,
740 backup: table.backup,
741 multiset: table.multiset,
742 fallback: table.fallback,
743 with_data: table.with_data,
744 }
745 }
746}
747
748#[derive(Default)]
750pub(crate) struct CreateTableConfiguration {
751 pub partition_by: Option<Box<Expr>>,
752 pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
753 pub inherits: Option<Vec<ObjectName>>,
754 pub table_options: CreateTableOptions,
755}
756
757#[cfg(test)]
758mod tests {
759 use crate::ast::helpers::stmt_create_table::CreateTableBuilder;
760 use crate::ast::{Ident, ObjectName, Statement};
761 use crate::parser::ParserError;
762
763 #[test]
764 pub fn test_from_valid_statement() {
765 let builder = CreateTableBuilder::new(ObjectName::from(vec![Ident::new("table_name")]));
766
767 let create_table = builder.clone().build();
768 let stmt: Statement = create_table.into();
769
770 assert_eq!(builder, CreateTableBuilder::try_from(stmt).unwrap());
771 }
772
773 #[test]
774 pub fn test_from_invalid_statement() {
775 let stmt = Statement::Commit {
776 chain: false,
777 end: false,
778 modifier: None,
779 };
780
781 assert_eq!(
782 CreateTableBuilder::try_from(stmt).unwrap_err(),
783 ParserError::ParserError(
784 "Expected create table statement, but received: COMMIT".to_owned()
785 )
786 );
787 }
788}