fix: don't extract common sub expr in CASE WHEN clause#8833
fix: don't extract common sub expr in CASE WHEN clause#8833liukun4515 merged 3 commits intoapache:mainfrom
CASE WHEN clause#8833Conversation
|
cc @liukun4515 |
| fn pre_visit(&mut self, expr: &Expr) -> Result<VisitRecursion> { | ||
| // related to https://github.com/apache/arrow-datafusion/issues/8814 | ||
| // If the expr contain volatile expression or is a case expression, skip it. | ||
| if matches!(expr, Expr::Case(..)) || is_volatile_expression(expr)? { |
There was a problem hiding this comment.
Check volatile expression is this place is because the previous method only can deal with a single random() function, the below query wil return true in main branch
SELECT r FROM (SELECT r1 == r2 r, r1, r2 FROM (SELECT random()+1 r1, random()+1 r2) WHERE r1 > 0 AND r2 > 0)
| } | ||
|
|
||
| /// check whether the expression is volatile predicates | ||
| pub(crate) fn is_volatile_expression(e: &Expr) -> Result<bool> { |
There was a problem hiding this comment.
move is_volatile_expression to utils for reuse.
thanks @haohuaijin I will help to review this pr this week. |
datafusion/optimizer/src/utils.rs
Outdated
| VisitRecursion::Continue | ||
| }) | ||
| }) | ||
| .unwrap(); |
There was a problem hiding this comment.
should we use the unwrap? or the ?
There was a problem hiding this comment.
because the result of is_volatile_expression is result
There was a problem hiding this comment.
Thanks for pointing this out. I forgot to change it when I moved the code.
| statement ok | ||
| DROP TABLE t; | ||
|
|
||
| # related to https://github.com/apache/arrow-datafusion/issues/8814 |
|
@jackwener could you please help to take a look this issue? |
| fn pre_visit(&mut self, expr: &Expr) -> Result<VisitRecursion> { | ||
| // related to https://github.com/apache/arrow-datafusion/issues/8814 | ||
| // If the expr contain volatile expression or is a case expression, skip it. | ||
| if matches!(expr, Expr::Case(..)) || is_volatile_expression(expr)? { |
There was a problem hiding this comment.
I think this problem could exist in other function/expression like COALESCE | OR
It can be tracked as a future ticket.
There was a problem hiding this comment.
The inner expressions in these expressions may be short-circuited.
There was a problem hiding this comment.
I comment in the #8874, Do we have any method for this rule to make sure the new function/expr or other cases we can't find will not bring the same bug
There was a problem hiding this comment.
In general, look great to me, but some details need improve.
Thanks @haohuaijin & @liukun4515
| }) | ||
| .partition(|(_, value)| is_volatile_expression(value)); | ||
| .partition(|(_, value)| { | ||
| is_volatile_expression(value).unwrap_or(true) |
There was a problem hiding this comment.
If we don't know whether the scalar function is volatile, default set it to a volatile function.
|
Thanks @jackwener and @liukun4515 for reviews. |
|
Thanks for @haohuaijin to fix this issue. |
|
@alamb i will merge this pr. |
* fix: don't extract common sub expr in CASE WHEN clause * fix ci * fix
… to v34 (#227) * fix: don't extract common sub expr in `CASE WHEN` clause (apache#8833) * fix: don't extract common sub expr in CASE WHEN clause * fix ci * fix * fix: common_subexpr_eliminate rule should not apply to short-circuit expression (apache#8928) * fix: common_subexpr_eliminate rule should not apply to short-circuit expression * add more tests * format * minor * apply reviews * add some commont * fmt --------- Co-authored-by: Huaijin <[email protected]>
Which issue does this PR close?
Closes #8814
Rationale for this change
as shown in #8814, in
CASE WHEN A THEN B ELSE C ENDexpr, the B and C only have one can run,so for query
the
A.column1/B.column1actually should not run, but we extract it as a common sub expr(see below plan), which results inA.column1/B.column1running and getting a divide zero error.What changes are included in this PR?
Are these changes tested?
yes, add a test.
Are there any user-facing changes?