alex-plekhanov commented on code in PR #11972:
URL: https://github.com/apache/ignite/pull/11972#discussion_r2030951332


##########
modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java:
##########
@@ -586,6 +590,117 @@ private RelNode 
visitLeftAndRightCorrelateHands(LogicalCorrelate correlate, Corr
         return relShuttle.visit(rel);
     }
 
+    /**
+     * Due to distributive property of conjunction over disjunction we can 
extract common part of conjunctions.
+     * This can help us to simplify and push down filters.
+     * For example, condition:
+     *      (a = 0 and x = 1) or (a = 0 and y = 2) or (a = 0 and z = 3)
+     * can be translated to:
+     *      a = 0 and (x = 1 or y = 2 or z = 3)
+     * after such a transformation condition "a = 0" can be used as index 
access predicate.
+     */
+    public RelNode extractConjunctionOverDisjunctionCommonPart(RelNode rel) {
+        return new RelHomogeneousShuttle() {
+            /** {@inheritDoc} */
+            @Override public RelNode visit(LogicalFilter filter) {
+                RexNode condition = 
transform(filter.getCluster().getRexBuilder(), filter.getCondition());
+
+                if (condition != filter.getCondition())
+                    filter = filter.copy(filter.getTraitSet(), 
filter.getInput(), condition);
+
+                return super.visit(filter);
+            }
+
+            /** {@inheritDoc} */
+            @Override public RelNode visit(LogicalJoin join) {
+                RexNode condition = 
transform(join.getCluster().getRexBuilder(), join.getCondition());
+
+                if (condition != join.getCondition()) {
+                    join = join.copy(join.getTraitSet(), condition, 
join.getLeft(), join.getRight(),
+                        join.getJoinType(), join.isSemiJoinDone());
+                }
+
+                return super.visit(join);
+            }
+
+            /** */
+            private RexNode transform(RexBuilder rexBuilder, RexNode 
condition) {
+                // It makes sence to extract only top level disjunction common 
part.
+                if (!condition.isA(SqlKind.OR))
+                    return condition;
+
+                Set<RexNode> commonPart = new HashSet<>();
+
+                List<RexNode> orOps = ((RexCall)condition).getOperands();
+
+                RexNode firstOp = orOps.get(0);
+
+                for (RexNode andOpFirst : conjunctionOperands(firstOp)) {
+                    boolean found = false;
+
+                    for (int i = 1; i < orOps.size(); i++) {
+                        found = false;
+
+                        for (RexNode andOpOther : 
conjunctionOperands(orOps.get(i))) {
+                            if (andOpFirst.equals(andOpOther)) {
+                                found = true;
+                                break;
+                            }
+                        }
+
+                        if (!found)
+                            break;
+                    }
+
+                    if (found)
+                        commonPart.add(andOpFirst);
+                }
+
+                if (commonPart.isEmpty())
+                    return condition;
+
+                List<RexNode> newOrOps = new ArrayList<>(orOps.size());
+
+                for (RexNode orOp : orOps) {
+                    List<RexNode> newAndOps = new ArrayList<>();
+
+                    for (RexNode andOp : conjunctionOperands(orOp)) {
+                        if (!commonPart.contains(andOp))
+                            newAndOps.add(andOp);
+                    }
+
+                    if (!newAndOps.isEmpty()) {
+                        RexNode newAnd = 
RexUtil.composeConjunction(rexBuilder, newAndOps);

Review Comment:
   This check already exists inside `composeConjunction`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@ignite.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to