fix: remove WorkTableExec special case in reset_plan_states
#18803
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?
This PR fixes an oversight in #16469 that broke wrapper nodes in recursive queries.
When
with_new_state()was added as a generic state injection mechanism,reset_plan_states()kept a concrete type check forWorkTableExec. This means wrapper nodes that delegateas_any()to their inner node won't be recognized, causing them to keep stale state across iterations. This breaks recursive queries for external crates that wrap execution plans (like tracing or monitoring tools).Rationale for this change
The
reset_plan_states()function usesplan.as_any().is::<WorkTableExec>()to decide which nodes to skip resetting. This works fine for bareWorkTableExecbut fails when it's wrapped by custom nodes as the type check can't see through the wrapper.This defeats the whole point of
with_new_state(), which was designed to let wrapper and third-party nodes participate in recursive queries without concrete type checks.The special case was added to save one
Arc::clone()per iteration, but it's not worth it sinceWorkTableExec::with_new_children()already just returnsArc::clone(&self)anyway. The sharedWorkTablestate is preserved through theArc<WorkTable>reference, so the optimization doesn't buy us much while breaking wrapper nodes.What changes are included in this PR?
WorkTableExectype check inreset_plan_states()- just reset all nodes uniformly viareset_state().WorkTablestate stays correct becauseWorkTableExec::with_new_children()returnsArc::clone(&self).Are these changes tested?
Yes, covered by existing tests:
WorkTableExecis identical.Since this restores functionality for wrapper nodes rather than changing core DataFusion behavior, it fixes test failures in external crates (like
datafusion-tracing) without needing new tests here.Are there any user-facing changes?
No Breaking Changes:
Benefits:
WorkTableExecand implementwith_new_state()without breaking recursive queries.with_new_statea trait method forExecutionPlan#16469 was designed to provide.