fix: remove partition aware union logic#6009
Conversation
`UnionExec` shall be a simple node and not perform some optimizations on its own. If repartition / partition concatenation is desired, then there should be an optimizer pass for that. Fixes apache#5970.
|
Could you please add a flag to turn on/off the partition aware logic ? And in SparkSQL, it has similar optimization. For |
|
And I do not think it is bug. |
|
@mingmwang do you think we could change the optimizer to add a |
I mean #5970 clearly shows that there is SOME bug in the DF code base and as illustrated there different parts of the code could be hold responsible for it. So while the technical bug is probably in the optimizer, the fact that |
I get your points. Agree that this internal optimization logic inside the UnionExec is not visible to others, this is not good. Basically, we need to consider the following requirements
|
|
Good points. I esp. like the "keep ordering VS keep partition" semantics. How about we split |
At the very begin, I thought we could have two types of Union, a normal |
|
I spent a non trivial time thinking about what a "PartitionAware" Union even means It is entirely undocumented in Thanks to @mingmwang and @crepererum 's comment on #5970 (comment) Given the operation seems so different, if we are going to keep the partition aware union, I think we should use a different structure name. Maybe we could call what is currently named "UnionExec with preserve partitioning" as
I will try and make a PR to do this to make the current state of affairs easier to understand |
|
Update: 🤔 it seems from my experiment on #6013 that we have no explain coverage (at all) for UnionExec with preserve partitioning. @mingmwang do you know of tests / examples of it being used so that I can add coverage? |
|
This week I plan to extend this PR by the new node type (partition aware Union / interleave) and an optimizer pass that inserts it. |
|
@alamb |
|
@crepererum In the method else if is_union(plan) {
// UnionExec does not have real sort requirements for its input. Here we change the adjusted_request_ordering to UnionExec's output ordering and
// propagate the sort requirements down to correct the unnecessary descendant SortExec under the UnionExec
Ok(Some(vec![
parent_required.map(|elem| elem.to_vec());
plan.children().len()
]))
}change to else if let Some(UnionExec {
partition_aware: false, ..
}) = plan.as_any().downcast_ref::<UnionExec>()
{
// UnionExec does not have real sort requirements for its input. Here we change the adjusted_request_ordering to UnionExec's output ordering and
// propagate the sort requirements down to correct the unnecessary descendant SortExec under the UnionExec
Ok(Some(vec![
parent_required.map(|elem| elem.to_vec());
plan.children().len()
]))
} |
|
Sorry that #5970 is my bug, I wrote the first version of the Top-Down sort enforcement and forgot to handle the |
|
Filed #6045 as a more advanced solution. I think this is the best of both worlds. |
Which issue does this PR close?
Fixes #5970.
Rationale for this change
UnionExecshall be a simple node and not perform some optimizations on its own. If repartition / partition concatenation is desired, then there should be an optimizer pass for that. Being a simple node avoids confusion and optimizer bugs like #5970.What changes are included in this PR?
Remove the entire "partition aware" logic from
UnionExecAre these changes tested?
Are there any user-facing changes?
Less bugs.