maytasm commented on a change in pull request #9773:
URL: https://github.com/apache/druid/pull/9773#discussion_r421920290



##########
File path: 
sql/src/main/java/org/apache/druid/sql/calcite/rule/FilterJoinExcludePushToChildRule.java
##########
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite.rule;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+import org.apache.calcite.adapter.enumerable.EnumerableConvention;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.plan.RelOptRuleOperand;
+import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.rules.FilterJoinRule;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.tools.RelBuilder;
+import org.apache.calcite.tools.RelBuilderFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.calcite.plan.RelOptUtil.conjunctions;
+
+public abstract class FilterJoinExcludePushToChildRule extends FilterJoinRule
+{
+  /** Copied from {@link FilterJoinRule#NOT_ENUMERABLE} */
+  private static final Predicate NOT_ENUMERABLE = (join, joinType, exp) ->
+      join.getConvention() != EnumerableConvention.INSTANCE;
+
+  /**
+   * Rule that pushes predicates from a Filter into the Join below them.
+   * Similar to {@link FilterJoinRule#FILTER_ON_JOIN} but does not push 
predicate to the child
+   */
+  public static final FilterJoinRule FILTER_ON_JOIN_EXCLUDE_PUSH_TO_CHILD =
+      new FilterIntoJoinExcludePushToChildRule(RelFactories.LOGICAL_BUILDER, 
NOT_ENUMERABLE);
+
+  FilterJoinExcludePushToChildRule(RelOptRuleOperand operand,
+                                             String id,
+                                             boolean smart,
+                                             RelBuilderFactory 
relBuilderFactory,
+                                             Predicate predicate) {
+    super(operand, id, smart, relBuilderFactory, predicate);
+  }
+
+  /**
+   * Rule that tries to push filter expressions into a join
+   * condition. Exlucde pushing into the inputs (child) of the join.
+   */
+  public static class FilterIntoJoinExcludePushToChildRule extends 
FilterJoinExcludePushToChildRule
+  {
+    public FilterIntoJoinExcludePushToChildRule(RelBuilderFactory 
relBuilderFactory, Predicate predicate) {
+      super(
+          operand(Filter.class,
+                  operand(Join.class, RelOptRule.any())),
+          "FilterJoinExcludePushToChildRule:filter", true, relBuilderFactory,
+          predicate);
+    }
+
+    @Override
+    public void onMatch(RelOptRuleCall call) {
+      Filter filter = call.rel(0);
+      Join join = call.rel(1);
+      perform(call, filter, join);
+    }
+  }
+
+  /**
+   * Copied from {@link FilterJoinRule#perform}
+   * The difference is that this method will not not push filters to the 
children in classifyFilters
+   */
+  @Override
+  protected void perform(RelOptRuleCall call, Filter filter,
+                         Join join) {
+    final List<RexNode> joinFilters =
+        RelOptUtil.conjunctions(join.getCondition());
+    final List<RexNode> origJoinFilters = ImmutableList.copyOf(joinFilters);
+    // If there is only the joinRel,
+    // make sure it does not match a cartesian product joinRel
+    // (with "true" condition), otherwise this rule will be applied
+    // again on the new cartesian product joinRel.
+    if (filter == null && joinFilters.isEmpty()) {
+      return;
+    }
+
+    final List<RexNode> aboveFilters =
+        filter != null
+        ? getConjunctions(filter)
+        : new ArrayList<>();
+    final ImmutableList<RexNode> origAboveFilters =
+        ImmutableList.copyOf(aboveFilters);
+
+    // Simplify Outer Joins
+    JoinRelType joinType = join.getJoinType();
+    if (!origAboveFilters.isEmpty() && join.getJoinType() != 
JoinRelType.INNER) {
+      joinType = RelOptUtil.simplifyJoin(join, origAboveFilters, joinType);
+    }
+
+    final List<RexNode> leftFilters = new ArrayList<>();

Review comment:
       These left right thing is not needed. But I copied this whole code from 
Calcite and made minimum change (which is just the classifyFilters method). 
Hence, keeping these variables here as I don't want to refactor Calcite stuff 
more than needed.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to