aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorptkool <michael.styles@shopify.com>2017-04-20 09:51:13 +0800
committerWenchen Fan <wenchen@databricks.com>2017-04-20 09:51:13 +0800
commit63824b2c8e010ba03013be498def236c654d4fed (patch)
tree08625bfd0cbc7a2bc6e719ba7e846cd654790edf
parent4fea7848c45d85ff3ad0863de5d1449d1fd1b4b0 (diff)
downloadspark-63824b2c8e010ba03013be498def236c654d4fed.tar.gz
spark-63824b2c8e010ba03013be498def236c654d4fed.tar.bz2
spark-63824b2c8e010ba03013be498def236c654d4fed.zip
[SPARK-20350] Add optimization rules to apply Complementation Laws.
## What changes were proposed in this pull request? Apply Complementation Laws during boolean expression simplification. ## How was this patch tested? Tested using unit tests, integration tests, and manual tests. Author: ptkool <michael.styles@shopify.com> Author: Michael Styles <michael.styles@shopify.com> Closes #17650 from ptkool/apply_complementation_laws.
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/expressions.scala5
-rw-r--r--sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/optimizer/BooleanSimplificationSuite.scala19
2 files changed, 24 insertions, 0 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/expressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/expressions.scala
index ea2c5d241d..34382bd272 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/expressions.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/expressions.scala
@@ -154,6 +154,11 @@ object BooleanSimplification extends Rule[LogicalPlan] with PredicateHelper {
case TrueLiteral Or _ => TrueLiteral
case _ Or TrueLiteral => TrueLiteral
+ case a And b if Not(a).semanticEquals(b) => FalseLiteral
+ case a Or b if Not(a).semanticEquals(b) => TrueLiteral
+ case a And b if a.semanticEquals(Not(b)) => FalseLiteral
+ case a Or b if a.semanticEquals(Not(b)) => TrueLiteral
+
case a And b if a.semanticEquals(b) => a
case a Or b if a.semanticEquals(b) => a
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 935bff7cef..c275f997ba 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
@@ -26,6 +26,7 @@ import org.apache.spark.sql.catalyst.plans.PlanTest
import org.apache.spark.sql.catalyst.plans.logical._
import org.apache.spark.sql.catalyst.rules._
import org.apache.spark.sql.internal.SQLConf
+import org.apache.spark.sql.Row
class BooleanSimplificationSuite extends PlanTest with PredicateHelper {
@@ -42,6 +43,16 @@ class BooleanSimplificationSuite extends PlanTest with PredicateHelper {
val testRelation = LocalRelation('a.int, 'b.int, 'c.int, 'd.string)
+ val testRelationWithData = LocalRelation.fromExternalRows(
+ testRelation.output, Seq(Row(1, 2, 3, "abc"))
+ )
+
+ private def checkCondition(input: Expression, expected: LogicalPlan): Unit = {
+ val plan = testRelationWithData.where(input).analyze
+ val actual = Optimize.execute(plan)
+ comparePlans(actual, expected)
+ }
+
private def checkCondition(input: Expression, expected: Expression): Unit = {
val plan = testRelation.where(input).analyze
val actual = Optimize.execute(plan)
@@ -160,4 +171,12 @@ class BooleanSimplificationSuite extends PlanTest with PredicateHelper {
testRelation.where('a > 2 || ('b > 3 && 'b < 5)))
comparePlans(actual, expected)
}
+
+ test("Complementation Laws") {
+ checkCondition('a && !'a, testRelation)
+ checkCondition(!'a && 'a, testRelation)
+
+ checkCondition('a || !'a, testRelationWithData)
+ checkCondition(!'a || 'a, testRelationWithData)
+ }
}