-
Notifications
You must be signed in to change notification settings - Fork 28.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SPARK-3462 push down filters and projections into Unions #2345
Conversation
Can one of the admins verify this patch? |
ok to test |
QA tests have started for PR 2345 at commit
|
Hey @koeninger, thanks for implementing this optimization! Overall this looks pretty good. A few minor suggestions:
/**
* Pushes Project and Filter operations to either side of a Union.
*/
object UnionPushdown extends Rule[LogicalPlan] {
/**
* Rewrites an expression so that it can be pushed to the right side of a Union operator.
* This method relies on the fact that the output attributes of a union are always equal to the
* left child's output.
*/
def pushToRight[A <: Expression](e: A, union: Union): A = {
assert(union.left.output.size == union.right.output.size)
// Maps Attributes from the left side to the corresponding Attribute on the right side.
val rewrites = AttributeMap(union.left.output.zip(union.right.output))
val result = e transform {
case a: Attribute => rewrites(a)
}
// We must promise the compiler that we did not discard the names in the case of project
// expressions. This is safe since the only transformation is from Attribute => Attribute.
result.asInstanceOf[A]
}
def apply(plan: LogicalPlan): LogicalPlan = plan transform {
// Push down filter into union
case Filter(condition, u @ Union(left, right)) =>
Union(
Filter(condition, left),
Filter(pushToRight(condition, u), right))
// Push down projection into union
case Project(projectList, u @ Union(left, right)) =>
Union(
Project(projectList, left),
Project(projectList.map(pushToRight(_, u)), right))
}
}
|
QA tests have finished for PR 2345 at commit
|
…, per marmbrus feedback
@marbrus I see what you mean. Updated to basically what you suggested, aside from building the map once. Let me know, once it's finalized I can try to test one more time on live data. |
QA tests have started for PR 2345 at commit
|
* This method relies on the fact that the output attributes of a union are always equal | ||
* to the left child's output. | ||
*/ | ||
def pushToRight[A <: Expression](e: A, union: Union, rewrites: AttributeMap[Attribute]): A = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: union
is not used.
QA tests have started for PR 2345 at commit
|
LGTM to me once the tests pass. |
QA tests have started for PR 2345 at commit
|
QA tests have finished for PR 2345 at commit
|
QA tests have finished for PR 2345 at commit
|
Thanks! I've merged to master. |
QA tests have finished for PR 2345 at commit
|
No description provided.