Skip to content

Commit e406422

Browse files
osipovartemosipovartem
andauthored
Add support for cluster by expressions (#1883)
Co-authored-by: osipovartem <artem@PC.localdomain>
1 parent 0f2208d commit e406422

File tree

6 files changed

+31
-13
lines changed

6 files changed

+31
-13
lines changed

src/ast/dml.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,9 @@ pub struct CreateTable {
175175
pub partition_by: Option<Box<Expr>>,
176176
/// BigQuery: Table clustering column list.
177177
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
178-
pub cluster_by: Option<WrappedCollection<Vec<Ident>>>,
178+
/// Snowflake: Table clustering list which contains base column, expressions on base columns.
179+
/// <https://docs.snowflake.com/en/user-guide/tables-clustering-keys#defining-a-clustering-key-for-a-table>
180+
pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
179181
/// Hive: Table clustering column list.
180182
/// <https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateTable>
181183
pub clustered_by: Option<ClusteredBy>,

src/ast/helpers/stmt_create_table.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub struct CreateTableBuilder {
9090
pub primary_key: Option<Box<Expr>>,
9191
pub order_by: Option<OneOrManyWithParens<Expr>>,
9292
pub partition_by: Option<Box<Expr>>,
93-
pub cluster_by: Option<WrappedCollection<Vec<Ident>>>,
93+
pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
9494
pub clustered_by: Option<ClusteredBy>,
9595
pub inherits: Option<Vec<ObjectName>>,
9696
pub strict: bool,
@@ -279,7 +279,7 @@ impl CreateTableBuilder {
279279
self
280280
}
281281

282-
pub fn cluster_by(mut self, cluster_by: Option<WrappedCollection<Vec<Ident>>>) -> Self {
282+
pub fn cluster_by(mut self, cluster_by: Option<WrappedCollection<Vec<Expr>>>) -> Self {
283283
self.cluster_by = cluster_by;
284284
self
285285
}
@@ -542,7 +542,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
542542
#[derive(Default)]
543543
pub(crate) struct CreateTableConfiguration {
544544
pub partition_by: Option<Box<Expr>>,
545-
pub cluster_by: Option<WrappedCollection<Vec<Ident>>>,
545+
pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
546546
pub inherits: Option<Vec<ObjectName>>,
547547
pub table_options: CreateTableOptions,
548548
}

src/dialect/snowflake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ pub fn parse_create_table(
453453
parser.expect_keyword_is(Keyword::BY)?;
454454
parser.expect_token(&Token::LParen)?;
455455
let cluster_by = Some(WrappedCollection::Parentheses(
456-
parser.parse_comma_separated(|p| p.parse_identifier())?,
456+
parser.parse_comma_separated(|p| p.parse_expr())?,
457457
));
458458
parser.expect_token(&Token::RParen)?;
459459

src/parser/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7316,7 +7316,7 @@ impl<'a> Parser<'a> {
73167316
if dialect_of!(self is BigQueryDialect | GenericDialect) {
73177317
if self.parse_keywords(&[Keyword::CLUSTER, Keyword::BY]) {
73187318
cluster_by = Some(WrappedCollection::NoWrapping(
7319-
self.parse_comma_separated(|p| p.parse_identifier())?,
7319+
self.parse_comma_separated(|p| p.parse_expr())?,
73207320
));
73217321
};
73227322

tests/sqlparser_bigquery.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,8 +536,8 @@ fn parse_create_table_with_options() {
536536
(
537537
Some(Box::new(Expr::Identifier(Ident::new("_PARTITIONDATE")))),
538538
Some(WrappedCollection::NoWrapping(vec![
539-
Ident::new("userid"),
540-
Ident::new("age"),
539+
Expr::Identifier(Ident::new("userid")),
540+
Expr::Identifier(Ident::new("age")),
541541
])),
542542
CreateTableOptions::Options(vec![
543543
SqlOption::KeyValue {

tests/sqlparser_snowflake.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -471,15 +471,31 @@ fn test_snowflake_create_table_if_not_exists() {
471471

472472
#[test]
473473
fn test_snowflake_create_table_cluster_by() {
474-
match snowflake().verified_stmt("CREATE TABLE my_table (a INT) CLUSTER BY (a, b)") {
474+
match snowflake().verified_stmt("CREATE TABLE my_table (a INT) CLUSTER BY (a, b, my_func(c))") {
475475
Statement::CreateTable(CreateTable {
476476
name, cluster_by, ..
477477
}) => {
478478
assert_eq!("my_table", name.to_string());
479479
assert_eq!(
480480
Some(WrappedCollection::Parentheses(vec![
481-
Ident::new("a"),
482-
Ident::new("b"),
481+
Expr::Identifier(Ident::new("a")),
482+
Expr::Identifier(Ident::new("b")),
483+
Expr::Function(Function {
484+
name: ObjectName::from(vec![Ident::new("my_func")]),
485+
uses_odbc_syntax: false,
486+
parameters: FunctionArguments::None,
487+
args: FunctionArguments::List(FunctionArgumentList {
488+
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
489+
Expr::Identifier(Ident::new("c"))
490+
))],
491+
duplicate_treatment: None,
492+
clauses: vec![],
493+
}),
494+
filter: None,
495+
null_treatment: None,
496+
over: None,
497+
within_group: vec![],
498+
}),
483499
])),
484500
cluster_by
485501
)
@@ -903,8 +919,8 @@ fn test_snowflake_create_iceberg_table_all_options() {
903919
assert_eq!("my_table", name.to_string());
904920
assert_eq!(
905921
Some(WrappedCollection::Parentheses(vec![
906-
Ident::new("a"),
907-
Ident::new("b"),
922+
Expr::Identifier(Ident::new("a")),
923+
Expr::Identifier(Ident::new("b")),
908924
])),
909925
cluster_by
910926
);

0 commit comments

Comments
 (0)