Skip to content

Commit

Permalink
clickhouse: add support for parsing ARRAY JOIN
Browse files Browse the repository at this point in the history
  • Loading branch information
lustefaniak committed Sep 25, 2023
1 parent 7723ea5 commit d923cc6
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/ast/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,10 @@ pub enum TableFactor {
/// [Partition selection](https://dev.mysql.com/doc/refman/8.0/en/partitioning-selection.html), supported by MySQL.
partitions: Vec<Ident>,
},
FieldAccessor {
expr: Expr,
alias: Option<TableAlias>,
},
Derived {
lateral: bool,
subquery: Box<Query>,
Expand Down Expand Up @@ -802,6 +806,13 @@ impl fmt::Display for TableFactor {
}
Ok(())
}
TableFactor::FieldAccessor { expr, alias } => {
write!(f, "{expr}")?;
if let Some(alias) = alias {
write!(f, " AS {alias}")?;
}
Ok(())
}
TableFactor::Pivot {
name,
table_alias,
Expand Down Expand Up @@ -961,6 +972,7 @@ impl fmt::Display for Join {
),
JoinOperator::CrossApply => write!(f, " CROSS APPLY {}", self.relation),
JoinOperator::OuterApply => write!(f, " OUTER APPLY {}", self.relation),
JoinOperator::Array => write!(f, " ARRAY JOIN {}", self.relation),
}
}
}
Expand All @@ -986,6 +998,8 @@ pub enum JoinOperator {
CrossApply,
/// OUTER APPLY (non-standard)
OuterApply,
/// ARRAY JOIN (ClickHouse)
Array,
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
Expand Down
1 change: 1 addition & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
Keyword::END,
// for MYSQL PARTITION SELECTION
Keyword::PARTITION,
Keyword::ARRAY,
];

/// Can't be used as a column alias, so that `SELECT <expr> alias`
Expand Down
16 changes: 16 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6040,6 +6040,12 @@ impl<'a> Parser<'a> {
relation: self.parse_table_factor()?,
join_operator: JoinOperator::OuterApply,
}
} else if self.parse_keyword(Keyword::ARRAY) {
self.expect_keyword(Keyword::JOIN)?;
Join {
relation: self.parse_array_join_table_factor()?,
join_operator: JoinOperator::Array,
}
} else {
let natural = self.parse_keyword(Keyword::NATURAL);
let peek_keyword = if let Token::Word(w) = self.peek_token().token {
Expand Down Expand Up @@ -6216,6 +6222,7 @@ impl<'a> Parser<'a> {
| TableFactor::Table { alias, .. }
| TableFactor::UNNEST { alias, .. }
| TableFactor::TableFunction { alias, .. }
| TableFactor::FieldAccessor { alias, .. }
| TableFactor::Pivot {
pivot_alias: alias, ..
}
Expand Down Expand Up @@ -6338,6 +6345,15 @@ impl<'a> Parser<'a> {
}
}

pub fn parse_array_join_table_factor(&mut self) -> Result<TableFactor, ParserError> {
{
let expr = self.parse_expr()?;

let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
Ok(TableFactor::FieldAccessor { expr, alias })
}
}

pub fn parse_derived_table_factor(
&mut self,
lateral: IsLateral,
Expand Down
7 changes: 7 additions & 0 deletions tests/sqlparser_clickhouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,13 @@ fn parse_create_table() {
);
}

#[test]
fn parse_array_join() {
clickhouse().verified_stmt(r#"SELECT asset AS a FROM runs AS r ARRAY JOIN r.assets AS asset"#);
clickhouse().verified_stmt(r#"SELECT asset AS a FROM runs ARRAY JOIN assets AS asset"#);
clickhouse().verified_stmt(r#"SELECT assets FROM runs ARRAY JOIN assets"#);
}

fn clickhouse() -> TestedDialects {
TestedDialects {
dialects: vec![Box::new(ClickHouseDialect {})],
Expand Down

0 comments on commit d923cc6

Please sign in to comment.