Skip to content

Commit 7b314e1

Browse files
committed
no nulll filtering is added for compound expressions.
1 parent 4d535d1 commit 7b314e1

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -606,11 +606,12 @@ object NullPropagation extends Rule[LogicalPlan] {
606606
object NullFiltering extends Rule[LogicalPlan] with PredicateHelper {
607607
def apply(plan: LogicalPlan): LogicalPlan = plan transform {
608608
case filter @ Filter(condition, child) =>
609-
// We generate a list of additional isNotNull filters from the operator's existing constraints
610-
// but remove those that are either already part of the filter condition or are part of the
611-
// operator's child constraints.
612-
val newIsNotNullConstraints = filter.constraints.filter(_.isInstanceOf[IsNotNull]) --
613-
(child.constraints ++ splitConjunctivePredicates(condition))
609+
// We generate a list of additional isNotNull filters from the operator's existing
610+
// non-compound constraints but remove those that are either already part of the filter
611+
// condition or are part of the operator's child constraints.
612+
val newIsNotNullConstraints =
613+
filter.constraints.filter(isNullFilteringForNonCompoundExpr) --
614+
(child.constraints ++ splitConjunctivePredicates(condition))
614615
if (newIsNotNullConstraints.nonEmpty) {
615616
Filter(And(newIsNotNullConstraints.reduce(And), condition), child)
616617
} else {
@@ -619,11 +620,11 @@ object NullFiltering extends Rule[LogicalPlan] with PredicateHelper {
619620

620621
case join @ Join(left, right, joinType, condition) =>
621622
val leftIsNotNullConstraints = join.constraints
622-
.filter(_.isInstanceOf[IsNotNull])
623+
.filter(isNullFilteringForNonCompoundExpr)
623624
.filter(_.references.subsetOf(left.outputSet)) -- left.constraints
624625
val rightIsNotNullConstraints =
625626
join.constraints
626-
.filter(_.isInstanceOf[IsNotNull])
627+
.filter(isNullFilteringForNonCompoundExpr)
627628
.filter(_.references.subsetOf(right.outputSet)) -- right.constraints
628629
val newLeftChild = if (leftIsNotNullConstraints.nonEmpty) {
629630
Filter(leftIsNotNullConstraints.reduce(And), left)
@@ -641,6 +642,12 @@ object NullFiltering extends Rule[LogicalPlan] with PredicateHelper {
641642
join
642643
}
643644
}
645+
private def isNullFilteringForNonCompoundExpr(exp: Expression): Boolean = {
646+
exp match {
647+
case c: IsNotNull if c.child.isInstanceOf[AttributeReference] => true
648+
case _ => false
649+
}
650+
}
644651
}
645652

646653
/**

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/optimizer/NullFilteringSuite.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ class NullFilteringSuite extends PlanTest {
4040
comparePlans(optimized, correctAnswer)
4141
}
4242

43+
test("filter: do not push Null-filtering of compound expressions") {
44+
val originalQuery = testRelation.where('a + 'b === 1).analyze
45+
val optimized = Optimize.execute(originalQuery)
46+
comparePlans(optimized, originalQuery)
47+
}
48+
4349
test("single inner join: filter out nulls on either side on equi-join keys") {
4450
val x = testRelation.subquery('x)
4551
val y = testRelation.subquery('y)
@@ -83,6 +89,15 @@ class NullFilteringSuite extends PlanTest {
8389
comparePlans(optimized, correctAnswer)
8490
}
8591

92+
test("single inner join: no null filters are generated for compound expression") {
93+
val x = testRelation.subquery('x)
94+
val y = testRelation.subquery('y)
95+
val originalQuery = x.join(y,
96+
condition = Some("x.a".attr * 2 === "y.a".attr - 4)).analyze
97+
val optimized = Optimize.execute(originalQuery)
98+
comparePlans(optimized, originalQuery)
99+
}
100+
86101
test("single outer join: no null filters are generated") {
87102
val x = testRelation.subquery('x)
88103
val y = testRelation.subquery('y)

0 commit comments

Comments
 (0)