@@ -89,8 +89,6 @@ abstract class Optimizer(sessionCatalog: SessionCatalog, conf: CatalystConf)
8989 CombineFilters ,
9090 CombineLimits ,
9191 CombineUnions ,
92- // Push down Filters again after combination
93- PushDownPredicate ,
9492 // Constant folding and strength reduction
9593 NullPropagation ,
9694 FoldablePropagation ,
@@ -588,15 +586,33 @@ object CombineUnions extends Rule[LogicalPlan] {
588586 * one conjunctive predicate.
589587 */
590588object CombineFilters extends Rule [LogicalPlan ] with PredicateHelper {
589+ private def toCNF (predicate : Expression ): Expression = {
590+ val disjunctives = splitDisjunctivePredicates(predicate)
591+ var finalPredicates = splitConjunctivePredicates(disjunctives.head)
592+ disjunctives.tail.foreach { cond =>
593+ val predicates = new ArrayBuffer [Expression ]()
594+ splitConjunctivePredicates(cond).map { p =>
595+ predicates ++= finalPredicates.map(Or (_, p))
596+ }
597+ finalPredicates = predicates.toSeq
598+ }
599+ finalPredicates.reduce(And )
600+ }
591601 def apply (plan : LogicalPlan ): LogicalPlan = plan transform {
592602 case Filter (fc, nf @ Filter (nc, grandChild)) =>
593- (ExpressionSet (splitConjunctivePredicates(fc)) --
594- ExpressionSet (splitConjunctivePredicates(nc))).reduceOption(And ) match {
603+ val fcCNF = toCNF(fc)
604+ val ncCNF = toCNF(nc)
605+ val combinedFilter = (ExpressionSet (splitConjunctivePredicates(fcCNF)) --
606+ ExpressionSet (splitConjunctivePredicates(ncCNF))).reduceOption(And ) match {
595607 case Some (ac) =>
596608 Filter (And (nc, ac), grandChild)
597609 case None =>
598610 nf
599611 }
612+ // [[Filter]] can't pushdown through another [[Filter]]. Once they are combined,
613+ // [[BooleanSimplification]] rule will possibly simplify the predicate to the form that
614+ // will not be able to pushdown. So we pushdown the combined [[Filter]] immediately.
615+ PushDownPredicate (combinedFilter)
600616 }
601617}
602618
0 commit comments