Uh oh!
There was an error while loading. Please reload this page.
Improve volatile expression handling in CommonSubexprEliminate - #11265
Conversation
CommonSubexprEliminate ruleCommonSubexprEliminate4b395e1 to
6532b97Compare
alamb
left a comment
There was a problem hiding this comment.
Thank you @peter-toth -- this looks quite cool. I had one question about the test and some comment suggestions. The test is the only thing I think is needed before merging this PR
cc @waynexia and @haohuaijin in case you have comments
It may also be worth writing a few .slt tests showing this in action and how it interacts with multiple subexpressions
Uh oh!
There was an error while loading. Please reload this page.
| impl<'n> ExprIdentifierVisitor<'_, 'n> { | ||
| /// Find the first `EnterMark` in the stack, and accumulates every `ExprItem` | ||
| /// before it. |
There was a problem hiding this comment.
Could you possibly update this doc string to explain the 4-tuple that is now returned? Specifically document the two different bool values?
There was a problem hiding this comment.
Sure, good idea, I've added the comment in 79b2e02
| let plan = LogicalPlanBuilder::from(table_scan.clone()) | ||
| .project(vec![ | ||
| not_extracted_volatile_short_circuit_1.clone().alias("c1"), | ||
| not_extracted_volatile_short_circuit_1.alias("c2"), |
There was a problem hiding this comment.
🤔 I was thinking -- why can't we extract the a = 0 part of a = 0 OR random() = 0 out?
It seems like it would be ok to rewrite
SELECT a =0OR random() =0as c1,
a =0OR random() =0as c2,
..to something like this:
SELECT __subexpr_1 OR random() as c1,
__subexpr_1 OR random() as c2,
...
FROM (
SELECT a=0as __subexpr_1 FROM ...There was a problem hiding this comment.
This question is similar to #11197 (comment). We can extract the surely evaluated expressions (1st legs) from those short circuiting Or, And and CaseWhen expressions, but we are not there yet with this PR.
My 3rd PR in the #11194 epic will implement that logic, but I want to add the improvements gradually as it will require to recurse into only certain children of a parent and that's not straightforward with the current treenode APIs (i.e. we need to stop recursion at the parent with a Jump and start a new recursion only on the interresting children).
| fn pop_enter_mark(&mut self) -> (usize, bool, Option<Identifier<'n>>) { | ||
| fn pop_enter_mark(&mut self) -> (usize, bool, Option<Identifier<'n>>, bool) { | ||
| let mut expr_id = None; | ||
| let mut is_valid = true; |
There was a problem hiding this comment.
Could you please document what "valid" means in this context? I think it means "is valid for CSE" as in "this sub expression could potentially be removed via CSE" but I am not quite sure
There was a problem hiding this comment.
I added a comment to the method in 79b2e02, I think it explains what "valid" means in this case, but let me know if we should document the variable as well.
peter-toth
commented
Jul 5, 2024
Sure, I will add some tests tomorrow. |
haohuaijin
left a comment
There was a problem hiding this comment.
Looks good to me, thanks @peter-toth and @alamb.
I've added CSE tests in 1aa8848, it contais TODOs for #11265 (comment), but I will fix them in the next PR. |
alamb
left a comment
There was a problem hiding this comment.
Thank you @peter-toth and @haohuaijin
I merged up from main and updated the unit test to avoid a new dependency on datafusion-functions.
alamb
commented
Jul 8, 2024
Thanks again @peter-toth and @haohuaijin |
peter-toth
commented
Jul 8, 2024
Thanks @alamb and @haohuaijin for the review! |
…che#11265) * Improve volatile expression handling in `CommonSubexprEliminate` rule * fix volatile handling with short circuits * fix comments * add slt tests for CSE * Avoid adding datafusion function dependency * revert changes to datafusion-cli.lock --------- Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
…che#11265) * Improve volatile expression handling in `CommonSubexprEliminate` rule * fix volatile handling with short circuits * fix comments * add slt tests for CSE * Avoid adding datafusion function dependency * revert changes to datafusion-cli.lock --------- Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
Which issue does this PR close?
Part of #11194.
Rationale for this change
Curently
CommonSubexprEliminatealways skips expressions doesn't allow volatile expressions to be extracted, but this can be improved by allowing non-volatile subexpressions of volatile expressions to be extracted:I.e. from the plan:
the expression
a + bcan be extracted as common expression despite the fact that(a + b) + rand()is volatile.What changes are included in this PR?
Changes the rule to handle volatile expressions better by adding a new boolean flag to
VisitRecord::ExprItemand propagating up volatility (validity for CSE).Are these changes tested?
Yes, added new UT.
Are there any user-facing changes?
No.