mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-04 06:18:17 +00:00
Support PREWHERE
condition for ClickHouse dialect (#1328)
This commit is contained in:
parent
700bd03d6f
commit
0884dd920d
9 changed files with 94 additions and 0 deletions
|
@ -247,6 +247,11 @@ pub struct Select {
|
|||
pub from: Vec<TableWithJoins>,
|
||||
/// LATERAL VIEWs
|
||||
pub lateral_views: Vec<LateralView>,
|
||||
/// ClickHouse syntax: `PREWHERE a = 1 WHERE b = 2`,
|
||||
/// and it can be used together with WHERE selection.
|
||||
///
|
||||
/// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/select/prewhere)
|
||||
pub prewhere: Option<Expr>,
|
||||
/// WHERE
|
||||
pub selection: Option<Expr>,
|
||||
/// GROUP BY
|
||||
|
@ -302,6 +307,9 @@ impl fmt::Display for Select {
|
|||
write!(f, "{lv}")?;
|
||||
}
|
||||
}
|
||||
if let Some(ref prewhere) = self.prewhere {
|
||||
write!(f, " PREWHERE {prewhere}")?;
|
||||
}
|
||||
if let Some(ref selection) = self.selection {
|
||||
write!(f, " WHERE {selection}")?;
|
||||
}
|
||||
|
|
|
@ -558,6 +558,7 @@ define_keywords!(
|
|||
PRECISION,
|
||||
PREPARE,
|
||||
PRESERVE,
|
||||
PREWHERE,
|
||||
PRIMARY,
|
||||
PRIOR,
|
||||
PRIVILEGES,
|
||||
|
@ -851,6 +852,8 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
|
|||
Keyword::FOR,
|
||||
// for MYSQL PARTITION SELECTION
|
||||
Keyword::PARTITION,
|
||||
// for Clickhouse PREWHERE
|
||||
Keyword::PREWHERE,
|
||||
// for ClickHouse SELECT * FROM t SETTINGS ...
|
||||
Keyword::SETTINGS,
|
||||
// for Snowflake START WITH .. CONNECT BY
|
||||
|
|
|
@ -8329,6 +8329,14 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
let prewhere = if dialect_of!(self is ClickHouseDialect|GenericDialect)
|
||||
&& self.parse_keyword(Keyword::PREWHERE)
|
||||
{
|
||||
Some(self.parse_expr()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let selection = if self.parse_keyword(Keyword::WHERE) {
|
||||
Some(self.parse_expr()?)
|
||||
} else {
|
||||
|
@ -8440,6 +8448,7 @@ impl<'a> Parser<'a> {
|
|||
into,
|
||||
from,
|
||||
lateral_views,
|
||||
prewhere,
|
||||
selection,
|
||||
group_by,
|
||||
cluster_by,
|
||||
|
|
|
@ -63,6 +63,7 @@ fn parse_map_access_expr() {
|
|||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: Some(BinaryOp {
|
||||
left: Box::new(BinaryOp {
|
||||
left: Box::new(Identifier(Ident::new("id"))),
|
||||
|
@ -717,6 +718,56 @@ fn parse_group_by_with_modifier() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prewhere() {
|
||||
match clickhouse_and_generic().verified_stmt("SELECT * FROM t PREWHERE x = 1 WHERE y = 2") {
|
||||
Statement::Query(query) => {
|
||||
let prewhere = query.body.as_select().unwrap().prewhere.as_ref();
|
||||
assert_eq!(
|
||||
prewhere,
|
||||
Some(&BinaryOp {
|
||||
left: Box::new(Identifier(Ident::new("x"))),
|
||||
op: BinaryOperator::Eq,
|
||||
right: Box::new(Expr::Value(Value::Number("1".parse().unwrap(), false))),
|
||||
})
|
||||
);
|
||||
let selection = query.as_ref().body.as_select().unwrap().selection.as_ref();
|
||||
assert_eq!(
|
||||
selection,
|
||||
Some(&BinaryOp {
|
||||
left: Box::new(Identifier(Ident::new("y"))),
|
||||
op: BinaryOperator::Eq,
|
||||
right: Box::new(Expr::Value(Value::Number("2".parse().unwrap(), false))),
|
||||
})
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
match clickhouse_and_generic().verified_stmt("SELECT * FROM t PREWHERE x = 1 AND y = 2") {
|
||||
Statement::Query(query) => {
|
||||
let prewhere = query.body.as_select().unwrap().prewhere.as_ref();
|
||||
assert_eq!(
|
||||
prewhere,
|
||||
Some(&BinaryOp {
|
||||
left: Box::new(BinaryOp {
|
||||
left: Box::new(Identifier(Ident::new("x"))),
|
||||
op: BinaryOperator::Eq,
|
||||
right: Box::new(Expr::Value(Value::Number("1".parse().unwrap(), false))),
|
||||
}),
|
||||
op: BinaryOperator::And,
|
||||
right: Box::new(BinaryOp {
|
||||
left: Box::new(Identifier(Ident::new("y"))),
|
||||
op: BinaryOperator::Eq,
|
||||
right: Box::new(Expr::Value(Value::Number("2".parse().unwrap(), false))),
|
||||
}),
|
||||
})
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn clickhouse() -> TestedDialects {
|
||||
TestedDialects {
|
||||
dialects: vec![Box::new(ClickHouseDialect {})],
|
||||
|
|
|
@ -391,6 +391,7 @@ fn parse_update_set_from() {
|
|||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(
|
||||
vec![Expr::Identifier(Ident::new("id"))],
|
||||
|
@ -4551,6 +4552,7 @@ fn test_parse_named_window() {
|
|||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -4932,6 +4934,7 @@ fn parse_interval_and_or_xor() {
|
|||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: Some(Expr::BinaryOp {
|
||||
left: Box::new(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident {
|
||||
|
@ -6915,6 +6918,7 @@ fn lateral_function() {
|
|||
}],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -7634,6 +7638,7 @@ fn parse_merge() {
|
|||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -9141,6 +9146,7 @@ fn parse_unload() {
|
|||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -9285,6 +9291,7 @@ fn parse_connect_by() {
|
|||
}],
|
||||
into: None,
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -9369,6 +9376,7 @@ fn parse_connect_by() {
|
|||
}],
|
||||
into: None,
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: Some(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("employee_id"))),
|
||||
op: BinaryOperator::NotEq,
|
||||
|
|
|
@ -170,6 +170,7 @@ fn test_select_union_by_name() {
|
|||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -208,6 +209,7 @@ fn test_select_union_by_name() {
|
|||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
|
|
@ -111,6 +111,7 @@ fn parse_create_procedure() {
|
|||
into: None,
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -528,6 +529,7 @@ fn parse_substring_in_select() {
|
|||
joins: vec![]
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
|
|
@ -906,6 +906,7 @@ fn parse_escaped_quote_identifiers_with_escape() {
|
|||
into: None,
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -954,6 +955,7 @@ fn parse_escaped_quote_identifiers_with_no_escape() {
|
|||
into: None,
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -999,6 +1001,7 @@ fn parse_escaped_backticks_with_escape() {
|
|||
into: None,
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -1044,6 +1047,7 @@ fn parse_escaped_backticks_with_no_escape() {
|
|||
into: None,
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -1715,6 +1719,7 @@ fn parse_select_with_numeric_prefix_column_name() {
|
|||
joins: vec![]
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -1768,6 +1773,7 @@ fn parse_select_with_concatenation_of_exp_number_and_numeric_prefix_column() {
|
|||
joins: vec![]
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -2267,6 +2273,7 @@ fn parse_substring_in_select() {
|
|||
joins: vec![]
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -2572,6 +2579,7 @@ fn parse_hex_string_introducer() {
|
|||
})],
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
|
|
@ -1074,6 +1074,7 @@ fn parse_copy_to() {
|
|||
into: None,
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
having: None,
|
||||
|
@ -2383,6 +2384,7 @@ fn parse_array_subquery_expr() {
|
|||
into: None,
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
@ -2402,6 +2404,7 @@ fn parse_array_subquery_expr() {
|
|||
into: None,
|
||||
from: vec![],
|
||||
lateral_views: vec![],
|
||||
prewhere: None,
|
||||
selection: None,
|
||||
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||
cluster_by: vec![],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue