Repository navigation
fix: give reset copies of AggregateExec their own dynamic filter - #27453
Open
raghavyadav01 wants to merge 1 commit into
Open
raghavyadav01 wants to merge 1 commit into
raghavyadav01 wants to merge 1 commit into
Conversation
AggregateExec::reset_state reset its MIN/MAX dynamic filter in place and then cloned the node, so every copy made by reset_plan_states shared one filter and one set of bounds. A copy that ran after another one pruned row groups it still needed and could return NULL. Keep clearing the old filter in place (the scan below still holds it), then give the copy a new filter and new bounds, as SortExec does since apache#27142. Closes apache#27452. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Raghav Yadav <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which issue does this PR close?
Rationale for this change
AggregateExec::reset_stateresets its MIN/MAX dynamic filter in place and then clones the node, so every copy made withreset_plan_statesshares one filter and one set of bounds. A copy that runs after another one starts from the bound the first one left and prunes row groups it still needs (maxreturns NULL, or 900 when copies run at the same time). #27142 fixed the same thing forSortExec.What changes are included in this PR?
reset_statestill clears the old filter and bounds in place, because the scan below keeps the filter it was given at planning time and run, reset, run (Recursive CTE: MIN/MAX aggregate dynamic filter survives reset_state, later iterations return wrong results #26054) depends on that. It then gives the copy a newDynamicFilterPhysicalExprover the same columns and new bounds, asSortExecdoes.reset_plan_stateslimitations. Running the original plan after a copy was made is still unsupported, because it updates the filter the copy's scan reads.HashJoinExeccopies still share their filter.Are these changes tested?
Yes, in
core/tests/execution/agg_dynamic_filter_reset.rs:reset_copies_have_independent_aggregate_dynamic_filters: two copies run one after the other, then 10 rounds of concurrent copies. It fails on main (NULL instead of 1000).rerun_after_reset_keeps_aggregate_result: run, reset, run gives the same result. It already passes on main; it guards the in-place reset this change keeps.I also ran the aggregate unit tests in
physical-plan, the dynamic filter and filter pushdown tests incore_integration, the related sqllogictest files, and clippy.Are there any user-facing changes?
No API changes. Reset copies of a plan with a MIN/MAX aggregate return correct results, and lose that aggregate's dynamic row-group pruning.
I used Claude Code to help reproduce the issue and write the change. I reviewed and tested it myself.
🤖 Generated with Claude Code