| // 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, Statement, StorageLifecyclePolicy, StorageSerializationPolicy, |
| TableConstraint, TableVersion, Tag, 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 `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>>, |
| /// Whether `WITHOUT ROWID` is set. |
| pub without_rowid: bool, |
| /// 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>, |
| /// `STRICT` table flag. |
| pub strict: bool, |
| /// 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>, |
| /// 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>, |
| } |
| |
| impl CreateTableBuilder { |
| /// Create a new `CreateTableBuilder` for the given table name. |
| pub fn new(name: ObjectName) -> Self { |
| Self { |
| or_replace: false, |
| temporary: 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, |
| without_rowid: false, |
| 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, |
| strict: false, |
| 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, |
| 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, |
| } |
| } |
| /// 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 `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 `WITHOUT ROWID` option. |
| pub fn without_rowid(mut self, without_rowid: bool) -> Self { |
| self.without_rowid = without_rowid; |
| 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 |
| } |
| |
| /// Set `STRICT` option. |
| pub fn strict(mut self, strict: bool) -> Self { |
| self.strict = strict; |
| 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 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 |
| } |
| /// Consume the builder and produce a `CreateTable`. |
| pub fn build(self) -> CreateTable { |
| CreateTable { |
| or_replace: self.or_replace, |
| temporary: self.temporary, |
| 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, |
| without_rowid: self.without_rowid, |
| 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, |
| strict: self.strict, |
| 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, |
| 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, |
| } |
| } |
| } |
| |
| 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, |
| 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, |
| without_rowid: table.without_rowid, |
| 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, |
| strict: table.strict, |
| 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, |
| 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, |
| } |
| } |
| } |
| |
| /// 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() |
| ) |
| ); |
| } |
| } |