You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
InterleaveExec::with_new_children panics when optimizer rewrites change children's partitioning #21826
InterleaveExec::with_new_children uses assert_or_internal_err!(can_interleave(children.iter())) which panics when children's partitioning diverges after optimizer rewrites. This can happen when multiple physical optimizer passes modify the plan between when InterleaveExec is created and when with_new_children is called.
To Reproduce
This occurs in practice when:
EnforceDistribution creates InterleaveExec for a UnionExec whose children all have matching Hash partitioning
Subsequent optimizer passes (e.g. JoinSelection, additional EnforceDistribution/EnforceSorting passes) modify children's plan structure, changing their output partitioning
with_new_children is called on the InterleaveExec with the modified children → assertion panic
We hit this with a complex UNION ALL query (5 subqueries with JOINs, each reading from different table types — partitioned, single-file, MVs). The materialization task panics every time:
join_selection
caused by
Internal error: Assertion failed: can_interleave(children.iter()): Can not create InterleaveExec: new children can not be interleaved.
Expected behavior
InterleaveExec::with_new_children should gracefully fall back to UnionExec when children are no longer interleavable, instead of panicking. The existing comment in the code already acknowledges this possibility:
// New children are no longer interleavable, which might be a bug of optimization rewrite.
Correctness is preserved when falling back to UnionExec — EnforceDistribution will add RepartitionExec as needed. Only the interleave optimization is lost.
Activity
fix: InterleaveExec fallback to UnionExec when children partitioning …
fix: normalize `InterleaveExec` to `UnionExec` before enforcing distr…
fix: defer `InterleaveExec` partitioning check to `InvariantLevel::Ex…
Run the rules that decide requirements before enforcing them
Check the analyzer phase's contract where the phase ends