Skip to content

Commit 2d3c4f1

Browse files
Merge branch 'main' into postgres-regression-2
2 parents e8056c7 + 6f8e7b8 commit 2d3c4f1

26 files changed

+1514
-308
lines changed

src/ast/ddl.rs

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ use crate::ast::{
4848
HiveFormat, HiveIOFormat, HiveRowFormat, HiveSetLocation, Ident, InitializeKind,
4949
MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens, OperateFunctionArg,
5050
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy, SequenceOptions,
51-
Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag, TriggerEvent,
52-
TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value, ValueWithSpan,
53-
WrappedCollection,
51+
Spanned, SqlOption, StorageLifecyclePolicy, StorageSerializationPolicy, TableVersion, Tag,
52+
TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
53+
ValueWithSpan, WrappedCollection,
5454
};
5555
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
5656
use crate::keywords::Keyword;
@@ -457,6 +457,12 @@ pub enum AlterTableOperation {
457457
},
458458
/// Remove the clustering key from the table.
459459
DropClusteringKey,
460+
/// Redshift `ALTER SORTKEY (column_list)`
461+
/// <https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html>
462+
AlterSortKey {
463+
/// Column references in the sort key.
464+
columns: Vec<Expr>,
465+
},
460466
/// Suspend background reclustering operations.
461467
SuspendRecluster,
462468
/// Resume background reclustering operations.
@@ -993,6 +999,10 @@ impl fmt::Display for AlterTableOperation {
993999
write!(f, "DROP CLUSTERING KEY")?;
9941000
Ok(())
9951001
}
1002+
AlterTableOperation::AlterSortKey { columns } => {
1003+
write!(f, "ALTER SORTKEY({})", display_comma_separated(columns))?;
1004+
Ok(())
1005+
}
9961006
AlterTableOperation::SuspendRecluster => {
9971007
write!(f, "SUSPEND RECLUSTER")?;
9981008
Ok(())
@@ -2903,6 +2913,9 @@ pub struct CreateTable {
29032913
pub volatile: bool,
29042914
/// `ICEBERG` clause
29052915
pub iceberg: bool,
2916+
/// `SNAPSHOT` clause
2917+
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_snapshot_table_statement>
2918+
pub snapshot: bool,
29062919
/// Table name
29072920
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
29082921
pub name: ObjectName,
@@ -2999,6 +3012,9 @@ pub struct CreateTable {
29993012
/// Snowflake "WITH ROW ACCESS POLICY" clause
30003013
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
30013014
pub with_row_access_policy: Option<RowAccessPolicy>,
3015+
/// Snowflake `WITH STORAGE LIFECYCLE POLICY` clause
3016+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
3017+
pub with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>,
30023018
/// Snowflake "WITH TAG" clause
30033019
/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
30043020
pub with_tags: Option<Vec<Tag>>,
@@ -3037,7 +3053,13 @@ pub struct CreateTable {
30373053
pub diststyle: Option<DistStyle>,
30383054
/// Redshift `DISTKEY` option
30393055
/// <https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html>
3040-
pub distkey: Option<Ident>,
3056+
pub distkey: Option<Expr>,
3057+
/// Redshift `SORTKEY` option
3058+
/// <https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html>
3059+
pub sortkey: Option<Vec<Expr>>,
3060+
/// Redshift `BACKUP` option: `BACKUP { YES | NO }`
3061+
/// <https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html>
3062+
pub backup: Option<bool>,
30413063
}
30423064

30433065
impl fmt::Display for CreateTable {
@@ -3051,9 +3073,10 @@ impl fmt::Display for CreateTable {
30513073
// `CREATE TABLE t (a INT) AS SELECT a from t2`
30523074
write!(
30533075
f,
3054-
"CREATE {or_replace}{external}{global}{temporary}{transient}{volatile}{dynamic}{iceberg}TABLE {if_not_exists}{name}",
3076+
"CREATE {or_replace}{external}{global}{temporary}{transient}{volatile}{dynamic}{iceberg}{snapshot}TABLE {if_not_exists}{name}",
30553077
or_replace = if self.or_replace { "OR REPLACE " } else { "" },
30563078
external = if self.external { "EXTERNAL " } else { "" },
3079+
snapshot = if self.snapshot { "SNAPSHOT " } else { "" },
30573080
global = self.global
30583081
.map(|global| {
30593082
if global {
@@ -3300,6 +3323,10 @@ impl fmt::Display for CreateTable {
33003323
write!(f, " {row_access_policy}",)?;
33013324
}
33023325

3326+
if let Some(storage_lifecycle_policy) = &self.with_storage_lifecycle_policy {
3327+
write!(f, " {storage_lifecycle_policy}",)?;
3328+
}
3329+
33033330
if let Some(tag) = &self.with_tags {
33043331
write!(f, " WITH TAG ({})", display_comma_separated(tag.as_slice()))?;
33053332
}
@@ -3336,12 +3363,18 @@ impl fmt::Display for CreateTable {
33363363
if self.strict {
33373364
write!(f, " STRICT")?;
33383365
}
3366+
if let Some(backup) = self.backup {
3367+
write!(f, " BACKUP {}", if backup { "YES" } else { "NO" })?;
3368+
}
33393369
if let Some(diststyle) = &self.diststyle {
33403370
write!(f, " DISTSTYLE {diststyle}")?;
33413371
}
33423372
if let Some(distkey) = &self.distkey {
33433373
write!(f, " DISTKEY({distkey})")?;
33443374
}
3375+
if let Some(sortkey) = &self.sortkey {
3376+
write!(f, " SORTKEY({})", display_comma_separated(sortkey))?;
3377+
}
33453378
if let Some(query) = &self.query {
33463379
write!(f, " AS {query}")?;
33473380
}
@@ -3506,6 +3539,28 @@ impl fmt::Display for CreateDomain {
35063539
}
35073540
}
35083541

3542+
/// The return type of a `CREATE FUNCTION` statement.
3543+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3544+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3545+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3546+
pub enum FunctionReturnType {
3547+
/// `RETURNS <type>`
3548+
DataType(DataType),
3549+
/// `RETURNS SETOF <type>`
3550+
///
3551+
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
3552+
SetOf(DataType),
3553+
}
3554+
3555+
impl fmt::Display for FunctionReturnType {
3556+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3557+
match self {
3558+
FunctionReturnType::DataType(data_type) => write!(f, "{data_type}"),
3559+
FunctionReturnType::SetOf(data_type) => write!(f, "SETOF {data_type}"),
3560+
}
3561+
}
3562+
}
3563+
35093564
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
35103565
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
35113566
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
@@ -3526,7 +3581,7 @@ pub struct CreateFunction {
35263581
/// List of arguments for the function.
35273582
pub args: Option<Vec<OperateFunctionArg>>,
35283583
/// The return type of the function.
3529-
pub return_type: Option<DataType>,
3584+
pub return_type: Option<FunctionReturnType>,
35303585
/// The expression that defines the function.
35313586
///
35323587
/// Examples:
@@ -4277,6 +4332,9 @@ pub struct CreateView {
42774332
pub if_not_exists: bool,
42784333
/// if true, has SQLite `TEMP` or `TEMPORARY` clause <https://www.sqlite.org/lang_createview.html>
42794334
pub temporary: bool,
4335+
/// Snowflake: `COPY GRANTS` clause
4336+
/// <https://docs.snowflake.com/en/sql-reference/sql/create-view>
4337+
pub copy_grants: bool,
42804338
/// if not None, has Clickhouse `TO` clause, specify the table into which to insert results
42814339
/// <https://clickhouse.com/docs/en/sql-reference/statements/create/view#materialized-view>
42824340
pub to: Option<ObjectName>,
@@ -4320,6 +4378,9 @@ impl fmt::Display for CreateView {
43204378
.map(|to| format!(" TO {to}"))
43214379
.unwrap_or_default()
43224380
)?;
4381+
if self.copy_grants {
4382+
write!(f, " COPY GRANTS")?;
4383+
}
43234384
if !self.columns.is_empty() {
43244385
write!(f, " ({})", display_comma_separated(&self.columns))?;
43254386
}

src/ast/dml.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub struct Insert {
6161
/// `table_name foo` (for Oracle)
6262
pub table_alias: Option<TableAliasWithoutColumns>,
6363
/// COLUMNS
64-
pub columns: Vec<Ident>,
64+
pub columns: Vec<ObjectName>,
6565
/// Overwrite (Hive)
6666
pub overwrite: bool,
6767
/// A SQL query that specifies what to insert

src/ast/helpers/key_value_options.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use serde::{Deserialize, Serialize};
2929
#[cfg(feature = "visitor")]
3030
use sqlparser_derive::{Visit, VisitMut};
3131

32-
use crate::ast::{display_comma_separated, display_separated, Value};
32+
use crate::ast::{display_comma_separated, display_separated, ValueWithSpan};
3333

3434
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3535
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -75,9 +75,9 @@ pub struct KeyValueOption {
7575
/// The kind of value for a key-value option.
7676
pub enum KeyValueOptionKind {
7777
/// A single value.
78-
Single(Value),
78+
Single(ValueWithSpan),
7979
/// Multiple values.
80-
Multi(Vec<Value>),
80+
Multi(Vec<ValueWithSpan>),
8181
/// A nested list of key-value options.
8282
KeyValueOptions(Box<KeyValueOptions>),
8383
}

src/ast/helpers/stmt_create_table.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use crate::ast::{
2828
ClusteredBy, ColumnDef, CommentDef, CreateTable, CreateTableLikeKind, CreateTableOptions,
2929
DistStyle, Expr, FileFormat, ForValues, HiveDistributionStyle, HiveFormat, Ident,
3030
InitializeKind, ObjectName, OnCommit, OneOrManyWithParens, Query, RefreshModeKind,
31-
RowAccessPolicy, Statement, StorageSerializationPolicy, TableConstraint, TableVersion, Tag,
32-
WrappedCollection,
31+
RowAccessPolicy, Statement, StorageLifecyclePolicy, StorageSerializationPolicy,
32+
TableConstraint, TableVersion, Tag, WrappedCollection,
3333
};
3434

3535
use crate::parser::ParserError;
@@ -81,6 +81,8 @@ pub struct CreateTableBuilder {
8181
pub volatile: bool,
8282
/// Iceberg-specific table flag.
8383
pub iceberg: bool,
84+
/// `SNAPSHOT` table flag.
85+
pub snapshot: bool,
8486
/// Whether `DYNAMIC` table option is set.
8587
pub dynamic: bool,
8688
/// The table name.
@@ -147,6 +149,8 @@ pub struct CreateTableBuilder {
147149
pub with_aggregation_policy: Option<ObjectName>,
148150
/// Optional row access policy applied to the table.
149151
pub with_row_access_policy: Option<RowAccessPolicy>,
152+
/// Optional storage lifecycle policy applied to the table.
153+
pub with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>,
150154
/// Optional tags/labels attached to the table metadata.
151155
pub with_tags: Option<Vec<Tag>>,
152156
/// Optional base location for staged data.
@@ -174,7 +178,11 @@ pub struct CreateTableBuilder {
174178
/// Redshift `DISTSTYLE` option.
175179
pub diststyle: Option<DistStyle>,
176180
/// Redshift `DISTKEY` option.
177-
pub distkey: Option<Ident>,
181+
pub distkey: Option<Expr>,
182+
/// Redshift `SORTKEY` option.
183+
pub sortkey: Option<Vec<Expr>>,
184+
/// Redshift `BACKUP` option.
185+
pub backup: Option<bool>,
178186
}
179187

180188
impl CreateTableBuilder {
@@ -189,6 +197,7 @@ impl CreateTableBuilder {
189197
transient: false,
190198
volatile: false,
191199
iceberg: false,
200+
snapshot: false,
192201
dynamic: false,
193202
name,
194203
columns: vec![],
@@ -222,6 +231,7 @@ impl CreateTableBuilder {
222231
default_ddl_collation: None,
223232
with_aggregation_policy: None,
224233
with_row_access_policy: None,
234+
with_storage_lifecycle_policy: None,
225235
with_tags: None,
226236
base_location: None,
227237
external_volume: None,
@@ -236,6 +246,8 @@ impl CreateTableBuilder {
236246
require_user: false,
237247
diststyle: None,
238248
distkey: None,
249+
sortkey: None,
250+
backup: None,
239251
}
240252
}
241253
/// Set `OR REPLACE` for the CREATE TABLE statement.
@@ -278,6 +290,11 @@ impl CreateTableBuilder {
278290
self.iceberg = iceberg;
279291
self
280292
}
293+
/// Set `SNAPSHOT` table flag (BigQuery).
294+
pub fn snapshot(mut self, snapshot: bool) -> Self {
295+
self.snapshot = snapshot;
296+
self
297+
}
281298
/// Set `DYNAMIC` table option.
282299
pub fn dynamic(mut self, dynamic: bool) -> Self {
283300
self.dynamic = dynamic;
@@ -448,6 +465,14 @@ impl CreateTableBuilder {
448465
self.with_row_access_policy = with_row_access_policy;
449466
self
450467
}
468+
/// Attach a storage lifecycle policy to the table.
469+
pub fn with_storage_lifecycle_policy(
470+
mut self,
471+
with_storage_lifecycle_policy: Option<StorageLifecyclePolicy>,
472+
) -> Self {
473+
self.with_storage_lifecycle_policy = with_storage_lifecycle_policy;
474+
self
475+
}
451476
/// Attach tags/labels to the table metadata.
452477
pub fn with_tags(mut self, with_tags: Option<Vec<Tag>>) -> Self {
453478
self.with_tags = with_tags;
@@ -517,10 +542,20 @@ impl CreateTableBuilder {
517542
self
518543
}
519544
/// Set Redshift `DISTKEY` option.
520-
pub fn distkey(mut self, distkey: Option<Ident>) -> Self {
545+
pub fn distkey(mut self, distkey: Option<Expr>) -> Self {
521546
self.distkey = distkey;
522547
self
523548
}
549+
/// Set Redshift `SORTKEY` option.
550+
pub fn sortkey(mut self, sortkey: Option<Vec<Expr>>) -> Self {
551+
self.sortkey = sortkey;
552+
self
553+
}
554+
/// Set the Redshift `BACKUP` option.
555+
pub fn backup(mut self, backup: Option<bool>) -> Self {
556+
self.backup = backup;
557+
self
558+
}
524559
/// Consume the builder and produce a `CreateTable`.
525560
pub fn build(self) -> CreateTable {
526561
CreateTable {
@@ -532,6 +567,7 @@ impl CreateTableBuilder {
532567
transient: self.transient,
533568
volatile: self.volatile,
534569
iceberg: self.iceberg,
570+
snapshot: self.snapshot,
535571
dynamic: self.dynamic,
536572
name: self.name,
537573
columns: self.columns,
@@ -565,6 +601,7 @@ impl CreateTableBuilder {
565601
default_ddl_collation: self.default_ddl_collation,
566602
with_aggregation_policy: self.with_aggregation_policy,
567603
with_row_access_policy: self.with_row_access_policy,
604+
with_storage_lifecycle_policy: self.with_storage_lifecycle_policy,
568605
with_tags: self.with_tags,
569606
base_location: self.base_location,
570607
external_volume: self.external_volume,
@@ -579,6 +616,8 @@ impl CreateTableBuilder {
579616
require_user: self.require_user,
580617
diststyle: self.diststyle,
581618
distkey: self.distkey,
619+
sortkey: self.sortkey,
620+
backup: self.backup,
582621
}
583622
}
584623
}
@@ -609,6 +648,7 @@ impl From<CreateTable> for CreateTableBuilder {
609648
transient: table.transient,
610649
volatile: table.volatile,
611650
iceberg: table.iceberg,
651+
snapshot: table.snapshot,
612652
dynamic: table.dynamic,
613653
name: table.name,
614654
columns: table.columns,
@@ -642,6 +682,7 @@ impl From<CreateTable> for CreateTableBuilder {
642682
default_ddl_collation: table.default_ddl_collation,
643683
with_aggregation_policy: table.with_aggregation_policy,
644684
with_row_access_policy: table.with_row_access_policy,
685+
with_storage_lifecycle_policy: table.with_storage_lifecycle_policy,
645686
with_tags: table.with_tags,
646687
base_location: table.base_location,
647688
external_volume: table.external_volume,
@@ -656,6 +697,8 @@ impl From<CreateTable> for CreateTableBuilder {
656697
require_user: table.require_user,
657698
diststyle: table.diststyle,
658699
distkey: table.distkey,
700+
sortkey: table.sortkey,
701+
backup: table.backup,
659702
}
660703
}
661704
}

0 commit comments

Comments
 (0)