From cd8860bf30ad99480794f85529cfcc7230ba01ee Mon Sep 17 00:00:00 2001 From: Cheng Lian Date: Sun, 18 Jan 2015 00:29:58 -0800 Subject: [PATCH] Improves `compareConditions` to handle more subtle cases --- .../BooleanSimplificationSuite.scala | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/optimizer/BooleanSimplificationSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/optimizer/BooleanSimplificationSuite.scala index f700a12c2a678..264a0eff37d34 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/optimizer/BooleanSimplificationSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/optimizer/BooleanSimplificationSuite.scala @@ -18,14 +18,14 @@ package org.apache.spark.sql.catalyst.optimizer import org.apache.spark.sql.catalyst.analysis.EliminateAnalysisOperators -import org.apache.spark.sql.catalyst.expressions.{Or, And, Literal, Expression} +import org.apache.spark.sql.catalyst.expressions._ import org.apache.spark.sql.catalyst.plans.logical._ import org.apache.spark.sql.catalyst.plans.PlanTest import org.apache.spark.sql.catalyst.rules._ import org.apache.spark.sql.catalyst.dsl.plans._ import org.apache.spark.sql.catalyst.dsl.expressions._ -class BooleanSimplificationSuite extends PlanTest { +class BooleanSimplificationSuite extends PlanTest with PredicateHelper { object Optimize extends RuleExecutor[LogicalPlan] { val batches = @@ -40,14 +40,21 @@ class BooleanSimplificationSuite extends PlanTest { val testRelation = LocalRelation('a.int, 'b.int, 'c.int, 'd.string) + // The `foldLeft` is required to handle cases like comparing `a && (b && c)` and `(a && b) && c` def compareConditions(e1: Expression, e2: Expression): Boolean = (e1, e2) match { - case (And(l1, l2), And(r1, r2)) => - compareConditions(l1, r1) && compareConditions(l2, r2) || - compareConditions(l1, r2) && compareConditions(l2, r1) - - case (Or(l1, l2), Or(r1, r2)) => - compareConditions(l1, r1) && compareConditions(l2, r2) || - compareConditions(l1, r2) && compareConditions(l2, r1) + case (lhs: And, rhs: And) => + val lhsSet = splitConjunctivePredicates(lhs).toSet + val rhsSet = splitConjunctivePredicates(rhs).toSet + lhsSet.foldLeft(rhsSet) { (set, e) => + set.find(compareConditions(_, e)).map(set - _).getOrElse(set) + }.isEmpty + + case (lhs: Or, rhs: Or) => + val lhsSet = splitDisjunctivePredicates(lhs).toSet + val rhsSet = splitDisjunctivePredicates(rhs).toSet + lhsSet.foldLeft(rhsSet) { (set, e) => + set.find(compareConditions(_, e)).map(set - _).getOrElse(set) + }.isEmpty case (l, r) => l == r }