Skip to content

Commit d8bf122

Browse files
committed
backport 5700 and 8716 and add two test cases
1 parent a8d14cc commit d8bf122

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,11 @@ object BooleanSimplification extends Rule[LogicalPlan] with PredicateHelper {
462462
case (_, Literal(false, BooleanType)) => Literal(false)
463463
// a && a => a
464464
case (l, r) if l fastEquals r => l
465+
// a && (not(a) || b) => a && b
466+
case (l, Or(l1, r)) if (Not(l) == l1) => And(l, r)
467+
case (l, Or(r, l1)) if (Not(l) == l1) => And(l, r)
468+
case (Or(l, l1), r) if (l1 == Not(r)) => And(l, r)
469+
case (Or(l1, l), r) if (l1 == Not(r)) => And(l, r)
465470
// (a || b) && (a || c) => a || (b && c)
466471
case _ =>
467472
// 1. Split left and right to get the disjunctive predicates,
@@ -540,6 +545,10 @@ object BooleanSimplification extends Rule[LogicalPlan] with PredicateHelper {
540545
case LessThan(l, r) => GreaterThanOrEqual(l, r)
541546
// not(l <= r) => l > r
542547
case LessThanOrEqual(l, r) => GreaterThan(l, r)
548+
// not(l || r) => not(l) && not(r)
549+
case Or(l, r) => And(Not(l), Not(r))
550+
// not(l && r) => not(l) or not(r)
551+
case And(l, r) => Or(Not(l), Not(r))
543552
// not(not(e)) => e
544553
case Not(e) => e
545554
case _ => not

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,26 @@ class BooleanSimplificationSuite extends PlanTest with PredicateHelper {
8989
('a === 'b || 'b > 3 && 'a > 3 && 'a < 5))
9090
}
9191

92+
test("a && (!a || b)") {
93+
checkCondition('a && (!'a || 'b ), 'a && 'b)
94+
95+
checkCondition('a && ('b || !'a ), 'a && 'b)
96+
97+
checkCondition((!'a || 'b ) && 'a, 'b && 'a)
98+
99+
checkCondition(('b || !'a ) && 'a, 'b && 'a)
100+
}
101+
102+
test("DeMorgan's law") {
103+
checkCondition(!('a && 'b), !'a || !'b)
104+
105+
checkCondition(!('a || 'b), !'a && !'b)
106+
107+
checkCondition(!(('a && 'b) || ('c && 'd)), (!'a || !'b) && (!'c || !'d))
108+
109+
checkCondition(!(('a || 'b) && ('c || 'd)), (!'a && !'b) || (!'c && !'d))
110+
}
111+
92112
private val caseInsensitiveAnalyzer =
93113
new Analyzer(EmptyCatalog, EmptyFunctionRegistry, new SimpleCatalystConf(false))
94114

0 commit comments

Comments
 (0)