Skip to content

Commit 978bad9

Browse files
committed
[SPARK-32721][SQL][FOLLOWUP] Simplify if clauses with null and boolean
1 parent 1453a09 commit 978bad9

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,8 @@ object SimplifyConditionals extends Rule[LogicalPlan] with PredicateHelper {
465465
if cond.deterministic && trueValue.semanticEquals(falseValue) => trueValue
466466
case If(cond, l @ Literal(null, _), FalseLiteral) if !cond.nullable => And(cond, l)
467467
case If(cond, l @ Literal(null, _), TrueLiteral) if !cond.nullable => Or(Not(cond), l)
468+
case If(cond, FalseLiteral, l @ Literal(null, _)) if !cond.nullable => And(Not(cond), l)
469+
case If(cond, TrueLiteral, l @ Literal(null, _)) if !cond.nullable => Or(cond, l)
468470

469471
case e @ CaseWhen(branches, elseValue) if branches.exists(x => falseOrNullLiteral(x._1)) =>
470472
// If there are branches that are always false, remove them.

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,29 +166,37 @@ class SimplifyConditionalSuite extends PlanTest with ExpressionEvalHelper with P
166166
)
167167
}
168168

169-
test("simplify if when then clause is null and else clause is boolean") {
169+
test("simplify if when one clause is null and another is boolean") {
170170
val p = IsNull('a)
171171
val nullLiteral = Literal(null, BooleanType)
172172
assertEquivalent(If(p, nullLiteral, FalseLiteral), And(p, nullLiteral))
173173
assertEquivalent(If(p, nullLiteral, TrueLiteral), Or(IsNotNull('a), nullLiteral))
174+
assertEquivalent(If(p, FalseLiteral, nullLiteral), And(IsNotNull('a), nullLiteral))
175+
assertEquivalent(If(p, TrueLiteral, nullLiteral), Or(IsNull('a), nullLiteral))
174176

175177
// the rule should not apply to nullable predicate
176178
Seq(TrueLiteral, FalseLiteral).foreach { b =>
177179
assertEquivalent(If(GreaterThan('a, 42), nullLiteral, b),
178180
If(GreaterThan('a, 42), nullLiteral, b))
181+
assertEquivalent(If(GreaterThan('a, 42), b, nullLiteral),
182+
If(GreaterThan('a, 42), b, nullLiteral))
179183
}
180184

181185
// check evaluation also
182186
Seq(TrueLiteral, FalseLiteral).foreach { b =>
183187
checkEvaluation(If(b, nullLiteral, FalseLiteral), And(b, nullLiteral).eval(EmptyRow))
184188
checkEvaluation(If(b, nullLiteral, TrueLiteral), Or(Not(b), nullLiteral).eval(EmptyRow))
189+
checkEvaluation(If(b, FalseLiteral, nullLiteral), And(Not(b), nullLiteral).eval(EmptyRow))
190+
checkEvaluation(If(b, TrueLiteral, nullLiteral), Or(b, nullLiteral).eval(EmptyRow))
185191
}
186192

187193
// should have no effect on expressions with nullable if condition
188194
assert((Factorial(5) > 100L).nullable)
189195
Seq(TrueLiteral, FalseLiteral).foreach { b =>
190196
checkEvaluation(If(Factorial(5) > 100L, nullLiteral, b),
191197
If(Factorial(5) > 100L, nullLiteral, b).eval(EmptyRow))
198+
checkEvaluation(If(Factorial(5) > 100L, b, nullLiteral),
199+
If(Factorial(5) > 100L, b, nullLiteral).eval(EmptyRow))
192200
}
193201
}
194202
}

0 commit comments

Comments
 (0)