| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| #[cfg(not(feature = "std"))] | |
| use alloc::{boxed::Box, format, string::String, vec, vec::Vec}; | |
| #[cfg(feature = "serde")] | |
| use serde::{Deserialize, Serialize}; | |
| #[cfg(feature = "visitor")] | |
| use sqlparser_derive::{Visit, VisitMut}; | |
| use crate::ast::{ | |
| ClusteredBy, ColumnDef, CommentDef, CreateTable, CreateTableLikeKind, CreateTableOptions, | |
| DistStyle, Expr, FileFormat, ForValues, HiveDistributionStyle, HiveFormat, Ident, | |
| InitializeKind, ObjectName, OnCommit, OneOrManyWithParens, Query, RefreshModeKind, | |
| RowAccessPolicy, SqliteTableOptions, Statement, StorageLifecyclePolicy, | |
| StorageSerializationPolicy, TableConstraint, TableVersion, Tag, WithData, WrappedCollection, | |
| }; | |
| use crate::parser::ParserError; | |
| /// Builder for create table statement variant ([1]). | |
| /// | |
| /// This structure helps building and accessing a create table with more ease, without needing to: | |
| /// - Match the enum itself a lot of times; or | |
| /// - Moving a lot of variables around the code. | |
| /// | |
| /// # Example | |
| /// ```rust | |
| /// use sqlparser::ast::helpers::stmt_create_table::CreateTableBuilder; | |
| /// use sqlparser::ast::{ColumnDef, DataType, Ident, ObjectName}; | |
| /// let builder = CreateTableBuilder::new(ObjectName::from(vec![Ident::new("table_name")])) | |
| /// .if_not_exists(true) | |
| /// .columns(vec![ColumnDef { | |
| /// name: Ident::new("c1"), | |
| /// data_type: DataType::Int(None), | |
| /// options: vec![], | |
| /// }]); | |
| /// // You can access internal elements with ease | |
| /// assert!(builder.if_not_exists); | |
| /// // Convert to a statement | |
| /// assert_eq!( | |
| /// builder.build().to_string(), | |
| /// "CREATE TABLE IF NOT EXISTS table_name (c1 INT)" | |
| /// ) | |
| /// ``` | |
| /// | |
| /// [1]: crate::ast::Statement::CreateTable | |
| #[derive(Debug, Clone, PartialEq, Eq, Hash)] | |
| #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | |
| #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] | |
| pub struct CreateTableBuilder { | |
| /// Whether the statement uses `OR REPLACE`. | |
| pub or_replace: bool, | |
| /// Whether the table is `TEMPORARY`. | |
| pub temporary: bool, | |
| /// Whether the table is `UNLOGGED`. | |
| pub unlogged: bool, | |
| /// Whether the table is `EXTERNAL`. | |
| pub external: bool, | |
| /// Optional `GLOBAL` flag for dialects that support it. | |
| pub global: Option<bool>, | |
| /// Whether `IF NOT EXISTS` was specified. | |
| pub if_not_exists: bool, | |
| /// Whether `TRANSIENT` was specified. | |
| pub transient: bool, | |
| /// Whether `VOLATILE` was specified. | |
| pub volatile: bool, | |
| /// Iceberg-specific table flag. | |
| pub iceberg: bool, | |
| /// `SNAPSHOT` table flag. | |
| pub snapshot: bool, | |
| /// Whether `DYNAMIC` table option is set. | |
| pub dynamic: bool, | |
| /// The table name. | |
| pub name: ObjectName, | |
| /// Column definitions for the table. | |
| pub columns: Vec<ColumnDef>, | |
| /// Table-level constraints. | |
| pub constraints: Vec<TableConstraint>, | |
| /// Hive distribution style. | |
| pub hive_distribution: HiveDistributionStyle, | |
| /// Optional Hive format settings. | |
| pub hive_formats: Option<HiveFormat>, | |
| /// Optional file format for storage. | |
| pub file_format: Option<FileFormat>, | |
| /// Optional storage location. | |
| pub location: Option<String>, | |
| /// Optional `AS SELECT` query for the table. | |
| pub query: Option<Box<Query>>, | |
| /// SQLite `table-options`. | |
| pub sqlite_table_options: SqliteTableOptions, | |
| /// Optional `LIKE` clause kind. | |
| pub like: Option<CreateTableLikeKind>, | |
| /// Optional `CLONE` source object name. | |
| pub clone: Option<ObjectName>, | |
| /// Optional table version. | |
| pub version: Option<TableVersion>, | |
| /// Optional table comment. | |
| pub comment: Option<CommentDef>, | |
| /// Optional `ON COMMIT` behavior. | |
| pub on_commit: Option<OnCommit>, | |
| /// Optional cluster identifier. | |
| pub on_cluster: Option<Ident>, | |
| /// Optional primary key expression. | |
| pub primary_key: Option<Box<Expr>>, | |
| /// Optional `ORDER BY` for clustering/sorting. | |
| pub order_by: Option<OneOrManyWithParens<Expr>>, | |
| /// Optional `PARTITION BY` expression. | |
| pub partition_by: Option<Box<Expr>>, | |
| /// Optional `CLUSTER BY` expressions. | |
| pub cluster_by: Option<WrappedCollection<Vec<Expr>>>, | |
| /// Optional `CLUSTERED BY` clause. | |
| pub clustered_by: Option<ClusteredBy>, | |
| /// Optional parent tables (`INHERITS`). | |
| pub inherits: Option<Vec<ObjectName>>, | |
| /// Optional partitioned table (`PARTITION OF`) | |
| pub partition_of: Option<ObjectName>, | |
| /// Range of values associated with the partition (`FOR VALUES`) | |
| pub for_values: Option<ForValues>, | |
| /// Whether to copy grants from the source. | |
| pub copy_grants: bool, | |
| /// Optional flag for schema evolution support. | |
| pub enable_schema_evolution: Option<bool>, | |
| /// Optional change tracking flag. | |
| pub change_tracking: Option<bool>, | |
| /// Optional data retention time in days. | |
| pub data_retention_time_in_days: Option<u64>, | |
| /// Optional max data extension time in days. | |
| pub max_data_extension_time_in_days: Option<u64>, | |
| /// Optional default DDL collation. | |
| pub default_ddl_collation: Option<String>, | |
| /// Optional aggregation policy object name. | |
| pub with_aggregation_policy: Option<ObjectName>, | |
| /// Optional row access policy applied to the table. | |
| pub with_row_access_policy: Option<RowAccessPolicy>, | |
| /// Optional storage lifecycle policy applied to the table. | |
| pub with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>, | |
| /// Optional tags/labels attached to the table metadata. | |
| pub with_tags: Option<Vec<Tag>>, | |
| /// Optional base location for staged data. | |
| pub base_location: Option<String>, | |
| /// Optional external volume identifier. | |
| pub external_volume: Option<String>, | |
| /// `WITH CONNECTION` clause. | |
| /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_external_table_statement) | |
| pub with_connection: Option<ObjectName>, | |
| /// Optional catalog name. | |
| pub catalog: Option<String>, | |
| /// Optional catalog synchronization option. | |
| pub catalog_sync: Option<String>, | |
| /// Optional storage serialization policy. | |
| pub storage_serialization_policy: Option<StorageSerializationPolicy>, | |
| /// Parsed table options from the statement. | |
| pub table_options: CreateTableOptions, | |
| /// Optional target lag configuration. | |
| pub target_lag: Option<String>, | |
| /// Optional warehouse identifier. | |
| pub warehouse: Option<Ident>, | |
| /// Optional refresh mode for materialized tables. | |
| pub refresh_mode: Option<RefreshModeKind>, | |
| /// Optional initialization kind for the table. | |
| pub initialize: Option<InitializeKind>, | |
| /// Whether operations require a user identity. | |
| pub require_user: bool, | |
| /// Redshift `DISTSTYLE` option. | |
| pub diststyle: Option<DistStyle>, | |
| /// Redshift `DISTKEY` option. | |
| pub distkey: Option<Expr>, | |
| /// Redshift `SORTKEY` option. | |
| pub sortkey: Option<Vec<Expr>>, | |
| /// Redshift `BACKUP` option. | |
| pub backup: Option<bool>, | |
| /// `MULTISET | SET` table-kind prefix. | |
| pub multiset: Option<bool>, | |
| /// `FALLBACK` clause. | |
| pub fallback: Option<bool>, | |
| /// `WITH DATA` clause. | |
| pub with_data: Option<WithData>, | |
| } | |
| impl CreateTableBuilder { | |
| /// Create a new `CreateTableBuilder` for the given table name. | |
| pub fn new(name: ObjectName) -> Self { | |
| Self { | |
| or_replace: false, | |
| temporary: false, | |
| unlogged: false, | |
| external: false, | |
| global: None, | |
| if_not_exists: false, | |
| transient: false, | |
| volatile: false, | |
| iceberg: false, | |
| snapshot: false, | |
| dynamic: false, | |
| name, | |
| columns: vec![], | |
| constraints: vec![], | |
| hive_distribution: HiveDistributionStyle::NONE, | |
| hive_formats: None, | |
| file_format: None, | |
| location: None, | |
| query: None, | |
| sqlite_table_options: SqliteTableOptions::default(), | |
| like: None, | |
| clone: None, | |
| version: None, | |
| comment: None, | |
| on_commit: None, | |
| on_cluster: None, | |
| primary_key: None, | |
| order_by: None, | |
| partition_by: None, | |
| cluster_by: None, | |
| clustered_by: None, | |
| inherits: None, | |
| partition_of: None, | |
| for_values: None, | |
| copy_grants: false, | |
| enable_schema_evolution: None, | |
| change_tracking: None, | |
| data_retention_time_in_days: None, | |
| max_data_extension_time_in_days: None, | |
| default_ddl_collation: None, | |
| with_aggregation_policy: None, | |
| with_row_access_policy: None, | |
| with_storage_lifecycle_policy: None, | |
| with_tags: None, | |
| base_location: None, | |
| external_volume: None, | |
| with_connection: None, | |
| catalog: None, | |
| catalog_sync: None, | |
| storage_serialization_policy: None, | |
| table_options: CreateTableOptions::None, | |
| target_lag: None, | |
| warehouse: None, | |
| refresh_mode: None, | |
| initialize: None, | |
| require_user: false, | |
| diststyle: None, | |
| distkey: None, | |
| sortkey: None, | |
| backup: None, | |
| multiset: None, | |
| fallback: None, | |
| with_data: None, | |
| } | |
| } | |
| /// Set `OR REPLACE` for the CREATE TABLE statement. | |
| pub fn or_replace(mut self, or_replace: bool) -> Self { | |
| self.or_replace = or_replace; | |
| self | |
| } | |
| /// Mark the table as `TEMPORARY`. | |
| pub fn temporary(mut self, temporary: bool) -> Self { | |
| self.temporary = temporary; | |
| self | |
| } | |
| /// Mark the table as `UNLOGGED`. | |
| pub fn unlogged(mut self, unlogged: bool) -> Self { | |
| self.unlogged = unlogged; | |
| self | |
| } | |
| /// Mark the table as `EXTERNAL`. | |
| pub fn external(mut self, external: bool) -> Self { | |
| self.external = external; | |
| self | |
| } | |
| /// Set optional `GLOBAL` flag (dialect-specific). | |
| pub fn global(mut self, global: Option<bool>) -> Self { | |
| self.global = global; | |
| self | |
| } | |
| /// Set `IF NOT EXISTS`. | |
| pub fn if_not_exists(mut self, if_not_exists: bool) -> Self { | |
| self.if_not_exists = if_not_exists; | |
| self | |
| } | |
| /// Set `TRANSIENT` flag. | |
| pub fn transient(mut self, transient: bool) -> Self { | |
| self.transient = transient; | |
| self | |
| } | |
| /// Set `VOLATILE` flag. | |
| pub fn volatile(mut self, volatile: bool) -> Self { | |
| self.volatile = volatile; | |
| self | |
| } | |
| /// Enable Iceberg table semantics. | |
| pub fn iceberg(mut self, iceberg: bool) -> Self { | |
| self.iceberg = iceberg; | |
| self | |
| } | |
| /// Set `SNAPSHOT` table flag (BigQuery). | |
| pub fn snapshot(mut self, snapshot: bool) -> Self { | |
| self.snapshot = snapshot; | |
| self | |
| } | |
| /// Set `DYNAMIC` table option. | |
| pub fn dynamic(mut self, dynamic: bool) -> Self { | |
| self.dynamic = dynamic; | |
| self | |
| } | |
| /// Set the table column definitions. | |
| pub fn columns(mut self, columns: Vec<ColumnDef>) -> Self { | |
| self.columns = columns; | |
| self | |
| } | |
| /// Set table-level constraints. | |
| pub fn constraints(mut self, constraints: Vec<TableConstraint>) -> Self { | |
| self.constraints = constraints; | |
| self | |
| } | |
| /// Set Hive distribution style. | |
| pub fn hive_distribution(mut self, hive_distribution: HiveDistributionStyle) -> Self { | |
| self.hive_distribution = hive_distribution; | |
| self | |
| } | |
| /// Set Hive-specific formats. | |
| pub fn hive_formats(mut self, hive_formats: Option<HiveFormat>) -> Self { | |
| self.hive_formats = hive_formats; | |
| self | |
| } | |
| /// Set file format for the table (e.g., PARQUET). | |
| pub fn file_format(mut self, file_format: Option<FileFormat>) -> Self { | |
| self.file_format = file_format; | |
| self | |
| } | |
| /// Set storage `location` for the table. | |
| pub fn location(mut self, location: Option<String>) -> Self { | |
| self.location = location; | |
| self | |
| } | |
| /// Set an underlying `AS SELECT` query for the table. | |
| pub fn query(mut self, query: Option<Box<Query>>) -> Self { | |
| self.query = query; | |
| self | |
| } | |
| /// Set the SQLite `table-options` list. | |
| pub fn sqlite_table_options(mut self, sqlite_table_options: SqliteTableOptions) -> Self { | |
| self.sqlite_table_options = sqlite_table_options; | |
| self | |
| } | |
| /// Set `LIKE` clause for the table. | |
| pub fn like(mut self, like: Option<CreateTableLikeKind>) -> Self { | |
| self.like = like; | |
| self | |
| } | |
| // Different name to allow the object to be cloned | |
| /// Set `CLONE` source object name. | |
| pub fn clone_clause(mut self, clone: Option<ObjectName>) -> Self { | |
| self.clone = clone; | |
| self | |
| } | |
| /// Set table `VERSION`. | |
| pub fn version(mut self, version: Option<TableVersion>) -> Self { | |
| self.version = version; | |
| self | |
| } | |
| /// Set a comment for the table or following column definitions. | |
| pub fn comment_after_column_def(mut self, comment: Option<CommentDef>) -> Self { | |
| self.comment = comment; | |
| self | |
| } | |
| /// Set `ON COMMIT` behavior for temporary tables. | |
| pub fn on_commit(mut self, on_commit: Option<OnCommit>) -> Self { | |
| self.on_commit = on_commit; | |
| self | |
| } | |
| /// Set cluster identifier for the table. | |
| pub fn on_cluster(mut self, on_cluster: Option<Ident>) -> Self { | |
| self.on_cluster = on_cluster; | |
| self | |
| } | |
| /// Set a primary key expression for the table. | |
| pub fn primary_key(mut self, primary_key: Option<Box<Expr>>) -> Self { | |
| self.primary_key = primary_key; | |
| self | |
| } | |
| /// Set `ORDER BY` clause for clustered/sorted tables. | |
| pub fn order_by(mut self, order_by: Option<OneOrManyWithParens<Expr>>) -> Self { | |
| self.order_by = order_by; | |
| self | |
| } | |
| /// Set `PARTITION BY` expression. | |
| pub fn partition_by(mut self, partition_by: Option<Box<Expr>>) -> Self { | |
| self.partition_by = partition_by; | |
| self | |
| } | |
| /// Set `CLUSTER BY` expression(s). | |
| pub fn cluster_by(mut self, cluster_by: Option<WrappedCollection<Vec<Expr>>>) -> Self { | |
| self.cluster_by = cluster_by; | |
| self | |
| } | |
| /// Set `CLUSTERED BY` clause. | |
| pub fn clustered_by(mut self, clustered_by: Option<ClusteredBy>) -> Self { | |
| self.clustered_by = clustered_by; | |
| self | |
| } | |
| /// Set parent tables via `INHERITS`. | |
| pub fn inherits(mut self, inherits: Option<Vec<ObjectName>>) -> Self { | |
| self.inherits = inherits; | |
| self | |
| } | |
| /// Sets the table which is partitioned to create the current table. | |
| pub fn partition_of(mut self, partition_of: Option<ObjectName>) -> Self { | |
| self.partition_of = partition_of; | |
| self | |
| } | |
| /// Sets the range of values associated with the partition. | |
| pub fn for_values(mut self, for_values: Option<ForValues>) -> Self { | |
| self.for_values = for_values; | |
| self | |
| } | |
| /// Enable copying grants from source object. | |
| pub fn copy_grants(mut self, copy_grants: bool) -> Self { | |
| self.copy_grants = copy_grants; | |
| self | |
| } | |
| /// Enable or disable schema evolution features. | |
| pub fn enable_schema_evolution(mut self, enable_schema_evolution: Option<bool>) -> Self { | |
| self.enable_schema_evolution = enable_schema_evolution; | |
| self | |
| } | |
| /// Enable or disable change tracking. | |
| pub fn change_tracking(mut self, change_tracking: Option<bool>) -> Self { | |
| self.change_tracking = change_tracking; | |
| self | |
| } | |
| /// Set data retention time (in days). | |
| pub fn data_retention_time_in_days(mut self, data_retention_time_in_days: Option<u64>) -> Self { | |
| self.data_retention_time_in_days = data_retention_time_in_days; | |
| self | |
| } | |
| /// Set maximum data extension time (in days). | |
| pub fn max_data_extension_time_in_days( | |
| mut self, | |
| max_data_extension_time_in_days: Option<u64>, | |
| ) -> Self { | |
| self.max_data_extension_time_in_days = max_data_extension_time_in_days; | |
| self | |
| } | |
| /// Set default DDL collation. | |
| pub fn default_ddl_collation(mut self, default_ddl_collation: Option<String>) -> Self { | |
| self.default_ddl_collation = default_ddl_collation; | |
| self | |
| } | |
| /// Set aggregation policy object. | |
| pub fn with_aggregation_policy(mut self, with_aggregation_policy: Option<ObjectName>) -> Self { | |
| self.with_aggregation_policy = with_aggregation_policy; | |
| self | |
| } | |
| /// Attach a row access policy to the table. | |
| pub fn with_row_access_policy( | |
| mut self, | |
| with_row_access_policy: Option<RowAccessPolicy>, | |
| ) -> Self { | |
| self.with_row_access_policy = with_row_access_policy; | |
| self | |
| } | |
| /// Attach a storage lifecycle policy to the table. | |
| pub fn with_storage_lifecycle_policy( | |
| mut self, | |
| with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>, | |
| ) -> Self { | |
| self.with_storage_lifecycle_policy = with_storage_lifecycle_policy; | |
| self | |
| } | |
| /// Attach tags/labels to the table metadata. | |
| pub fn with_tags(mut self, with_tags: Option<Vec<Tag>>) -> Self { | |
| self.with_tags = with_tags; | |
| self | |
| } | |
| /// Set a base storage location for staged data. | |
| pub fn base_location(mut self, base_location: Option<String>) -> Self { | |
| self.base_location = base_location; | |
| self | |
| } | |
| /// Set an external volume identifier. | |
| pub fn external_volume(mut self, external_volume: Option<String>) -> Self { | |
| self.external_volume = external_volume; | |
| self | |
| } | |
| /// Set the `WITH CONNECTION` clause. | |
| pub fn with_connection(mut self, with_connection: Option<ObjectName>) -> Self { | |
| self.with_connection = with_connection; | |
| self | |
| } | |
| /// Set the catalog name for the table. | |
| pub fn catalog(mut self, catalog: Option<String>) -> Self { | |
| self.catalog = catalog; | |
| self | |
| } | |
| /// Set catalog synchronization option. | |
| pub fn catalog_sync(mut self, catalog_sync: Option<String>) -> Self { | |
| self.catalog_sync = catalog_sync; | |
| self | |
| } | |
| /// Set a storage serialization policy. | |
| pub fn storage_serialization_policy( | |
| mut self, | |
| storage_serialization_policy: Option<StorageSerializationPolicy>, | |
| ) -> Self { | |
| self.storage_serialization_policy = storage_serialization_policy; | |
| self | |
| } | |
| /// Set arbitrary table options parsed from the statement. | |
| pub fn table_options(mut self, table_options: CreateTableOptions) -> Self { | |
| self.table_options = table_options; | |
| self | |
| } | |
| /// Set a target lag configuration (dialect-specific). | |
| pub fn target_lag(mut self, target_lag: Option<String>) -> Self { | |
| self.target_lag = target_lag; | |
| self | |
| } | |
| /// Associate the table with a warehouse identifier. | |
| pub fn warehouse(mut self, warehouse: Option<Ident>) -> Self { | |
| self.warehouse = warehouse; | |
| self | |
| } | |
| /// Set refresh mode for materialized/managed tables. | |
| pub fn refresh_mode(mut self, refresh_mode: Option<RefreshModeKind>) -> Self { | |
| self.refresh_mode = refresh_mode; | |
| self | |
| } | |
| /// Set initialization mode for the table. | |
| pub fn initialize(mut self, initialize: Option<InitializeKind>) -> Self { | |
| self.initialize = initialize; | |
| self | |
| } | |
| /// Require a user identity for table operations. | |
| pub fn require_user(mut self, require_user: bool) -> Self { | |
| self.require_user = require_user; | |
| self | |
| } | |
| /// Set Redshift `DISTSTYLE` option. | |
| pub fn diststyle(mut self, diststyle: Option<DistStyle>) -> Self { | |
| self.diststyle = diststyle; | |
| self | |
| } | |
| /// Set Redshift `DISTKEY` option. | |
| pub fn distkey(mut self, distkey: Option<Expr>) -> Self { | |
| self.distkey = distkey; | |
| self | |
| } | |
| /// Set Redshift `SORTKEY` option. | |
| pub fn sortkey(mut self, sortkey: Option<Vec<Expr>>) -> Self { | |
| self.sortkey = sortkey; | |
| self | |
| } | |
| /// Set the Redshift `BACKUP` option. | |
| pub fn backup(mut self, backup: Option<bool>) -> Self { | |
| self.backup = backup; | |
| self | |
| } | |
| /// Set `MULTISET | SET` table-kind prefix. | |
| /// Some(true) => `MULTISET`, Some(false) => `SET`. | |
| pub fn multiset(mut self, multiset: Option<bool>) -> Self { | |
| self.multiset = multiset; | |
| self | |
| } | |
| /// Set `FALLBACK` / `NO FALLBACK` flag. | |
| pub fn fallback(mut self, fallback: Option<bool>) -> Self { | |
| self.fallback = fallback; | |
| self | |
| } | |
| /// Set `WITH DATA` clause. | |
| pub fn with_data(mut self, with_data: Option<WithData>) -> Self { | |
| self.with_data = with_data; | |
| self | |
| } | |
| /// Consume the builder and produce a `CreateTable`. | |
| pub fn build(self) -> CreateTable { | |
| CreateTable { | |
| or_replace: self.or_replace, | |
| temporary: self.temporary, | |
| unlogged: self.unlogged, | |
| external: self.external, | |
| global: self.global, | |
| if_not_exists: self.if_not_exists, | |
| transient: self.transient, | |
| volatile: self.volatile, | |
| iceberg: self.iceberg, | |
| snapshot: self.snapshot, | |
| dynamic: self.dynamic, | |
| name: self.name, | |
| columns: self.columns, | |
| constraints: self.constraints, | |
| hive_distribution: self.hive_distribution, | |
| hive_formats: self.hive_formats, | |
| file_format: self.file_format, | |
| location: self.location, | |
| query: self.query, | |
| sqlite_table_options: self.sqlite_table_options, | |
| like: self.like, | |
| clone: self.clone, | |
| version: self.version, | |
| comment: self.comment, | |
| on_commit: self.on_commit, | |
| on_cluster: self.on_cluster, | |
| primary_key: self.primary_key, | |
| order_by: self.order_by, | |
| partition_by: self.partition_by, | |
| cluster_by: self.cluster_by, | |
| clustered_by: self.clustered_by, | |
| inherits: self.inherits, | |
| partition_of: self.partition_of, | |
| for_values: self.for_values, | |
| copy_grants: self.copy_grants, | |
| enable_schema_evolution: self.enable_schema_evolution, | |
| change_tracking: self.change_tracking, | |
| data_retention_time_in_days: self.data_retention_time_in_days, | |
| max_data_extension_time_in_days: self.max_data_extension_time_in_days, | |
| default_ddl_collation: self.default_ddl_collation, | |
| with_aggregation_policy: self.with_aggregation_policy, | |
| with_row_access_policy: self.with_row_access_policy, | |
| with_storage_lifecycle_policy: self.with_storage_lifecycle_policy, | |
| with_tags: self.with_tags, | |
| base_location: self.base_location, | |
| external_volume: self.external_volume, | |
| with_connection: self.with_connection, | |
| catalog: self.catalog, | |
| catalog_sync: self.catalog_sync, | |
| storage_serialization_policy: self.storage_serialization_policy, | |
| table_options: self.table_options, | |
| target_lag: self.target_lag, | |
| warehouse: self.warehouse, | |
| refresh_mode: self.refresh_mode, | |
| initialize: self.initialize, | |
| require_user: self.require_user, | |
| diststyle: self.diststyle, | |
| distkey: self.distkey, | |
| sortkey: self.sortkey, | |
| backup: self.backup, | |
| multiset: self.multiset, | |
| fallback: self.fallback, | |
| with_data: self.with_data, | |
| } | |
| } | |
| } | |
| impl TryFrom<Statement> for CreateTableBuilder { | |
| type Error = ParserError; | |
| // As the builder can be transformed back to a statement, it shouldn't be a problem to take the | |
| // ownership. | |
| fn try_from(stmt: Statement) -> Result<Self, Self::Error> { | |
| match stmt { | |
| Statement::CreateTable(create_table) => Ok(create_table.into()), | |
| _ => Err(ParserError::ParserError(format!( | |
| "Expected create table statement, but received: {stmt}" | |
| ))), | |
| } | |
| } | |
| } | |
| impl From<CreateTable> for CreateTableBuilder { | |
| fn from(table: CreateTable) -> Self { | |
| Self { | |
| or_replace: table.or_replace, | |
| temporary: table.temporary, | |
| unlogged: table.unlogged, | |
| external: table.external, | |
| global: table.global, | |
| if_not_exists: table.if_not_exists, | |
| transient: table.transient, | |
| volatile: table.volatile, | |
| iceberg: table.iceberg, | |
| snapshot: table.snapshot, | |
| dynamic: table.dynamic, | |
| name: table.name, | |
| columns: table.columns, | |
| constraints: table.constraints, | |
| hive_distribution: table.hive_distribution, | |
| hive_formats: table.hive_formats, | |
| file_format: table.file_format, | |
| location: table.location, | |
| query: table.query, | |
| sqlite_table_options: table.sqlite_table_options, | |
| like: table.like, | |
| clone: table.clone, | |
| version: table.version, | |
| comment: table.comment, | |
| on_commit: table.on_commit, | |
| on_cluster: table.on_cluster, | |
| primary_key: table.primary_key, | |
| order_by: table.order_by, | |
| partition_by: table.partition_by, | |
| cluster_by: table.cluster_by, | |
| clustered_by: table.clustered_by, | |
| inherits: table.inherits, | |
| partition_of: table.partition_of, | |
| for_values: table.for_values, | |
| copy_grants: table.copy_grants, | |
| enable_schema_evolution: table.enable_schema_evolution, | |
| change_tracking: table.change_tracking, | |
| data_retention_time_in_days: table.data_retention_time_in_days, | |
| max_data_extension_time_in_days: table.max_data_extension_time_in_days, | |
| default_ddl_collation: table.default_ddl_collation, | |
| with_aggregation_policy: table.with_aggregation_policy, | |
| with_row_access_policy: table.with_row_access_policy, | |
| with_storage_lifecycle_policy: table.with_storage_lifecycle_policy, | |
| with_tags: table.with_tags, | |
| base_location: table.base_location, | |
| external_volume: table.external_volume, | |
| with_connection: table.with_connection, | |
| catalog: table.catalog, | |
| catalog_sync: table.catalog_sync, | |
| storage_serialization_policy: table.storage_serialization_policy, | |
| table_options: table.table_options, | |
| target_lag: table.target_lag, | |
| warehouse: table.warehouse, | |
| refresh_mode: table.refresh_mode, | |
| initialize: table.initialize, | |
| require_user: table.require_user, | |
| diststyle: table.diststyle, | |
| distkey: table.distkey, | |
| sortkey: table.sortkey, | |
| backup: table.backup, | |
| multiset: table.multiset, | |
| fallback: table.fallback, | |
| with_data: table.with_data, | |
| } | |
| } | |
| } | |
| /// Helper return type when parsing configuration for a `CREATE TABLE` statement. | |
| #[derive(Default)] | |
| pub(crate) struct CreateTableConfiguration { | |
| pub partition_by: Option<Box<Expr>>, | |
| pub cluster_by: Option<WrappedCollection<Vec<Expr>>>, | |
| pub inherits: Option<Vec<ObjectName>>, | |
| pub table_options: CreateTableOptions, | |
| } | |
| #[cfg(test)] | |
| mod tests { | |
| use crate::ast::helpers::stmt_create_table::CreateTableBuilder; | |
| use crate::ast::{Ident, ObjectName, Statement}; | |
| use crate::parser::ParserError; | |
| #[test] | |
| pub fn test_from_valid_statement() { | |
| let builder = CreateTableBuilder::new(ObjectName::from(vec![Ident::new("table_name")])); | |
| let create_table = builder.clone().build(); | |
| let stmt: Statement = create_table.into(); | |
| assert_eq!(builder, CreateTableBuilder::try_from(stmt).unwrap()); | |
| } | |
| #[test] | |
| pub fn test_from_invalid_statement() { | |
| let stmt = Statement::Commit { | |
| chain: false, | |
| end: false, | |
| modifier: None, | |
| }; | |
| assert_eq!( | |
| CreateTableBuilder::try_from(stmt).unwrap_err(), | |
| ParserError::ParserError( | |
| "Expected create table statement, but received: COMMIT".to_owned() | |
| ) | |
| ); | |
| } | |
| } |