This is an automated email from the ASF dual-hosted git repository.

jhyde pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git

commit 36e3109fb524c13ca0a08e3ad585785aa5abc18b
Author: Haisheng Yuan <[email protected]>
AuthorDate: Thu May 30 23:53:37 2019 -0500

    [CALCITE-3089] Deprecate EquiJoin
    
    Close apache/calcite#1247
---
 .../adapter/enumerable/EnumerableHashJoin.java     | 23 ++-----
 .../adapter/enumerable/EnumerableJoinRule.java     | 45 ++++++-------
 .../adapter/enumerable/EnumerableMergeJoin.java    | 25 +++----
 .../enumerable/EnumerableMergeJoinRule.java        | 38 +++++------
 .../enumerable/EnumerableNestedLoopJoin.java       | 18 ++---
 .../java/org/apache/calcite/plan/RelOptUtil.java   | 28 +++++---
 .../java/org/apache/calcite/rel/core/EquiJoin.java |  6 ++
 .../java/org/apache/calcite/rel/core/JoinInfo.java | 78 +++++++---------------
 .../apache/calcite/rel/rules/FilterJoinRule.java   | 27 ++++----
 .../calcite/rel/rules/ReduceExpressionsRule.java   | 10 ---
 .../org/apache/calcite/test/RelMetadataTest.java   | 10 +--
 .../org/apache/calcite/test/RelOptRulesTest.java   |  2 +-
 .../org/apache/calcite/test/RelOptRulesTest.xml    |  2 +-
 .../calcite/test/PigRelBuilderStyleTest.java       |  6 +-
 14 files changed, 126 insertions(+), 192 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableHashJoin.java
 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableHashJoin.java
index ec0264a..679d7fb 100644
--- 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableHashJoin.java
+++ 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableHashJoin.java
@@ -23,12 +23,11 @@ import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.InvalidRelException;
 import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.RelNodes;
 import org.apache.calcite.rel.core.CorrelationId;
-import org.apache.calcite.rel.core.EquiJoin;
+import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.metadata.RelMdCollation;
 import org.apache.calcite.rel.metadata.RelMdUtil;
@@ -45,7 +44,7 @@ import java.util.Set;
 
 /** Implementation of {@link org.apache.calcite.rel.core.Join} in
  * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention 
enumerable calling convention}. */
-public class EnumerableHashJoin extends EquiJoin implements EnumerableRel {
+public class EnumerableHashJoin extends Join implements EnumerableRel {
   /** Creates an EnumerableHashJoin.
    *
    * <p>Use {@link #create} unless you know what you're doing. */
@@ -56,8 +55,7 @@ public class EnumerableHashJoin extends EquiJoin implements 
EnumerableRel {
       RelNode right,
       RexNode condition,
       Set<CorrelationId> variablesSet,
-      JoinRelType joinType)
-      throws InvalidRelException {
+      JoinRelType joinType) {
     super(
         cluster,
         traits,
@@ -72,7 +70,7 @@ public class EnumerableHashJoin extends EquiJoin implements 
EnumerableRel {
   protected EnumerableHashJoin(RelOptCluster cluster, RelTraitSet traits,
       RelNode left, RelNode right, RexNode condition, ImmutableIntList 
leftKeys,
       ImmutableIntList rightKeys, JoinRelType joinType,
-      Set<String> variablesStopped) throws InvalidRelException {
+      Set<String> variablesStopped) {
     this(cluster, traits, left, right, condition, 
CorrelationId.setOf(variablesStopped), joinType);
   }
 
@@ -82,8 +80,7 @@ public class EnumerableHashJoin extends EquiJoin implements 
EnumerableRel {
       RelNode right,
       RexNode condition,
       Set<CorrelationId> variablesSet,
-      JoinRelType joinType)
-      throws InvalidRelException {
+      JoinRelType joinType) {
     final RelOptCluster cluster = left.getCluster();
     final RelMetadataQuery mq = cluster.getMetadataQuery();
     final RelTraitSet traitSet =
@@ -97,14 +94,8 @@ public class EnumerableHashJoin extends EquiJoin implements 
EnumerableRel {
   @Override public EnumerableHashJoin copy(RelTraitSet traitSet, RexNode 
condition,
       RelNode left, RelNode right, JoinRelType joinType,
       boolean semiJoinDone) {
-    try {
-      return new EnumerableHashJoin(getCluster(), traitSet, left, right,
-          condition, variablesSet, joinType);
-    } catch (InvalidRelException e) {
-      // Semantic error not possible. Must be a bug. Convert to
-      // internal error.
-      throw new AssertionError(e);
-    }
+    return new EnumerableHashJoin(getCluster(), traitSet, left, right,
+        condition, variablesSet, joinType);
   }
 
   @Override public RelOptCost computeSelfCost(RelOptPlanner planner,
diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
index 76f9831..4bade2d 100644
--- 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
+++ 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
@@ -18,12 +18,13 @@ package org.apache.calcite.adapter.enumerable;
 
 import org.apache.calcite.plan.Convention;
 import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.rel.InvalidRelException;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.convert.ConverterRule;
 import org.apache.calcite.rel.core.JoinInfo;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.logical.LogicalJoin;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexUtil;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -56,37 +57,29 @@ class EnumerableJoinRule extends ConverterRule {
     final RelOptCluster cluster = join.getCluster();
     final RelNode left = newInputs.get(0);
     final RelNode right = newInputs.get(1);
-    final JoinInfo info = JoinInfo.of(left, right, join.getCondition());
+    final JoinInfo info = join.analyzeCondition();
     if (!info.isEqui() && join.getJoinType() != JoinRelType.INNER) {
-      // EnumerableJoinRel only supports equi-join. We can put a filter on top
+      // EnumerableHashJoin only supports equi-join. We can put a filter on top
       // if it is an inner join.
-      try {
-        return EnumerableNestedLoopJoin.create(
-            left,
-            right,
-            join.getCondition(),
-            join.getVariablesSet(),
-            join.getJoinType());
-      } catch (InvalidRelException e) {
-        EnumerableRules.LOGGER.debug(e.toString());
-        return null;
-      }
+      return EnumerableNestedLoopJoin.create(
+          left,
+          right,
+          join.getCondition(),
+          join.getVariablesSet(),
+          join.getJoinType());
     } else {
       RelNode newRel;
-      try {
-        newRel = EnumerableHashJoin.create(
-            left,
-            right,
-            info.getEquiCondition(left, right, cluster.getRexBuilder()),
-            join.getVariablesSet(),
-            join.getJoinType());
-      } catch (InvalidRelException e) {
-        EnumerableRules.LOGGER.debug(e.toString());
-        return null;
-      }
+      newRel = EnumerableHashJoin.create(
+          left,
+          right,
+          info.getEquiCondition(left, right, cluster.getRexBuilder()),
+          join.getVariablesSet(),
+          join.getJoinType());
       if (!info.isEqui()) {
+        RexNode nonEqui = RexUtil.composeConjunction(cluster.getRexBuilder(),
+            info.nonEquiConditions);
         newRel = new EnumerableFilter(cluster, newRel.getTraitSet(),
-            newRel, info.getRemaining(cluster.getRexBuilder()));
+            newRel, nonEqui);
       }
       return newRel;
     }
diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
index 2ff7b50..d17184b 100644
--- 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
+++ 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
@@ -26,13 +26,12 @@ import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.InvalidRelException;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelCollations;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.CorrelationId;
-import org.apache.calcite.rel.core.EquiJoin;
+import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.metadata.RelMdCollation;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
@@ -54,7 +53,7 @@ import java.util.Set;
 /** Implementation of {@link org.apache.calcite.rel.core.Join} in
  * {@link EnumerableConvention enumerable calling convention} using
  * a merge algorithm. */
-public class EnumerableMergeJoin extends EquiJoin implements EnumerableRel {
+public class EnumerableMergeJoin extends Join implements EnumerableRel {
   EnumerableMergeJoin(
       RelOptCluster cluster,
       RelTraitSet traits,
@@ -62,8 +61,7 @@ public class EnumerableMergeJoin extends EquiJoin implements 
EnumerableRel {
       RelNode right,
       RexNode condition,
       Set<CorrelationId> variablesSet,
-      JoinRelType joinType)
-      throws InvalidRelException {
+      JoinRelType joinType) {
     super(cluster, traits, left, right, condition, variablesSet, joinType);
     final List<RelCollation> collations =
         traits.getTraits(RelCollationTraitDef.INSTANCE);
@@ -74,7 +72,7 @@ public class EnumerableMergeJoin extends EquiJoin implements 
EnumerableRel {
   EnumerableMergeJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left,
       RelNode right, RexNode condition, ImmutableIntList leftKeys,
       ImmutableIntList rightKeys, Set<CorrelationId> variablesSet,
-      JoinRelType joinType) throws InvalidRelException {
+      JoinRelType joinType) {
     this(cluster, traits, left, right, condition, variablesSet, joinType);
   }
 
@@ -82,15 +80,14 @@ public class EnumerableMergeJoin extends EquiJoin 
implements EnumerableRel {
   EnumerableMergeJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left,
       RelNode right, RexNode condition, ImmutableIntList leftKeys,
       ImmutableIntList rightKeys, JoinRelType joinType,
-      Set<String> variablesStopped) throws InvalidRelException {
+      Set<String> variablesStopped) {
     this(cluster, traits, left, right, condition, leftKeys, rightKeys,
         CorrelationId.setOf(variablesStopped), joinType);
   }
 
   public static EnumerableMergeJoin create(RelNode left, RelNode right,
       RexLiteral condition, ImmutableIntList leftKeys,
-      ImmutableIntList rightKeys, JoinRelType joinType)
-      throws InvalidRelException {
+      ImmutableIntList rightKeys, JoinRelType joinType) {
     final RelOptCluster cluster = right.getCluster();
     RelTraitSet traitSet = cluster.traitSet();
     if (traitSet.isEnabled(RelCollationTraitDef.INSTANCE)) {
@@ -106,14 +103,8 @@ public class EnumerableMergeJoin extends EquiJoin 
implements EnumerableRel {
   @Override public EnumerableMergeJoin copy(RelTraitSet traitSet,
       RexNode condition, RelNode left, RelNode right, JoinRelType joinType,
       boolean semiJoinDone) {
-    try {
-      return new EnumerableMergeJoin(getCluster(), traitSet, left, right,
-          condition, variablesSet, joinType);
-    } catch (InvalidRelException e) {
-      // Semantic error not possible. Must be a bug. Convert to
-      // internal error.
-      throw new AssertionError(e);
-    }
+    return new EnumerableMergeJoin(getCluster(), traitSet, left, right,
+        condition, variablesSet, joinType);
   }
 
   @Override public RelOptCost computeSelfCost(RelOptPlanner planner,
diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
index 44e4798..b993d94 100644
--- 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
+++ 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
@@ -20,7 +20,6 @@ import org.apache.calcite.linq4j.Ord;
 import org.apache.calcite.plan.Convention;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.InvalidRelException;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelCollations;
 import org.apache.calcite.rel.RelFieldCollation;
@@ -29,6 +28,8 @@ import org.apache.calcite.rel.convert.ConverterRule;
 import org.apache.calcite.rel.core.JoinInfo;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.logical.LogicalJoin;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexUtil;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -49,8 +50,7 @@ class EnumerableMergeJoinRule extends ConverterRule {
 
   @Override public RelNode convert(RelNode rel) {
     LogicalJoin join = (LogicalJoin) rel;
-    final JoinInfo info =
-        JoinInfo.of(join.getLeft(), join.getRight(), join.getCondition());
+    final JoinInfo info = join.analyzeCondition();
     if (join.getJoinType() != JoinRelType.INNER) {
       // EnumerableMergeJoin only supports inner join.
       // (It supports non-equi join, using a post-filter; see below.)
@@ -84,26 +84,24 @@ class EnumerableMergeJoinRule extends ConverterRule {
     final RelNode right = newInputs.get(1);
     final RelOptCluster cluster = join.getCluster();
     RelNode newRel;
-    try {
-      RelTraitSet traitSet = join.getTraitSet()
-          .replace(EnumerableConvention.INSTANCE);
-      if (!collations.isEmpty()) {
-        traitSet = traitSet.replace(collations);
-      }
-      newRel = new EnumerableMergeJoin(cluster,
-          traitSet,
-          left,
-          right,
-          info.getEquiCondition(left, right, cluster.getRexBuilder()),
-          join.getVariablesSet(),
-          join.getJoinType());
-    } catch (InvalidRelException e) {
-      EnumerableRules.LOGGER.debug(e.toString());
-      return null;
+
+    RelTraitSet traitSet = join.getTraitSet()
+        .replace(EnumerableConvention.INSTANCE);
+    if (!collations.isEmpty()) {
+      traitSet = traitSet.replace(collations);
     }
+    newRel = new EnumerableMergeJoin(cluster,
+        traitSet,
+        left,
+        right,
+        info.getEquiCondition(left, right, cluster.getRexBuilder()),
+        join.getVariablesSet(),
+        join.getJoinType());
     if (!info.isEqui()) {
+      RexNode nonEqui = RexUtil.composeConjunction(cluster.getRexBuilder(),
+          info.nonEquiConditions);
       newRel = new EnumerableFilter(cluster, newRel.getTraitSet(),
-          newRel, info.getRemaining(cluster.getRexBuilder()));
+          newRel, nonEqui);
     }
     return newRel;
   }
diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableNestedLoopJoin.java
 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableNestedLoopJoin.java
index 99fac65..a4e7b81 100644
--- 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableNestedLoopJoin.java
+++ 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableNestedLoopJoin.java
@@ -25,7 +25,6 @@ import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.InvalidRelException;
 import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.CorrelationId;
@@ -50,15 +49,14 @@ public class EnumerableNestedLoopJoin extends Join 
implements EnumerableRel {
   /** Creates an EnumerableNestedLoopJoin. */
   protected EnumerableNestedLoopJoin(RelOptCluster cluster, RelTraitSet traits,
       RelNode left, RelNode right, RexNode condition,
-      Set<CorrelationId> variablesSet, JoinRelType joinType)
-      throws InvalidRelException {
+      Set<CorrelationId> variablesSet, JoinRelType joinType) {
     super(cluster, traits, left, right, condition, variablesSet, joinType);
   }
 
   @Deprecated // to be removed before 2.0
   protected EnumerableNestedLoopJoin(RelOptCluster cluster, RelTraitSet traits,
       RelNode left, RelNode right, RexNode condition, JoinRelType joinType,
-      Set<String> variablesStopped) throws InvalidRelException {
+      Set<String> variablesStopped) {
     this(cluster, traits, left, right, condition,
         CorrelationId.setOf(variablesStopped), joinType);
   }
@@ -66,14 +64,8 @@ public class EnumerableNestedLoopJoin extends Join 
implements EnumerableRel {
   @Override public EnumerableNestedLoopJoin copy(RelTraitSet traitSet,
       RexNode condition, RelNode left, RelNode right, JoinRelType joinType,
       boolean semiJoinDone) {
-    try {
-      return new EnumerableNestedLoopJoin(getCluster(), traitSet, left, right,
-          condition, variablesSet, joinType);
-    } catch (InvalidRelException e) {
-      // Semantic error not possible. Must be a bug. Convert to
-      // internal error.
-      throw new AssertionError(e);
-    }
+    return new EnumerableNestedLoopJoin(getCluster(), traitSet, left, right,
+        condition, variablesSet, joinType);
   }
 
   /** Creates an EnumerableNestedLoopJoin. */
@@ -82,7 +74,7 @@ public class EnumerableNestedLoopJoin extends Join implements 
EnumerableRel {
       RelNode right,
       RexNode condition,
       Set<CorrelationId> variablesSet,
-      JoinRelType joinType) throws InvalidRelException {
+      JoinRelType joinType) {
     final RelOptCluster cluster = left.getCluster();
     final RelMetadataQuery mq = cluster.getMetadataQuery();
     final RelTraitSet traitSet =
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java 
b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index d29eebf..4645e9c 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -34,7 +34,6 @@ import org.apache.calcite.rel.core.Aggregate;
 import org.apache.calcite.rel.core.AggregateCall;
 import org.apache.calcite.rel.core.Calc;
 import org.apache.calcite.rel.core.CorrelationId;
-import org.apache.calcite.rel.core.EquiJoin;
 import org.apache.calcite.rel.core.Filter;
 import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.rel.core.JoinRelType;
@@ -862,6 +861,24 @@ public abstract class RelOptUtil {
       List<Boolean> filterNulls) {
     final List<RexNode> nonEquiList = new ArrayList<>();
 
+    splitJoinCondition(left, right, condition, leftKeys, rightKeys,
+        filterNulls, nonEquiList);
+
+    return RexUtil.composeConjunction(
+        left.getCluster().getRexBuilder(), nonEquiList);
+  }
+
+  /** As
+   * {@link #splitJoinCondition(RelNode, RelNode, RexNode, List, List, List)},
+   * but writes non-equi conditions to a conjunctive list. */
+  public static void splitJoinCondition(
+      RelNode left,
+      RelNode right,
+      RexNode condition,
+      List<Integer> leftKeys,
+      List<Integer> rightKeys,
+      List<Boolean> filterNulls,
+      List<RexNode> nonEquiList) {
     splitJoinCondition(
         left.getCluster().getRexBuilder(),
         left.getRowType().getFieldCount(),
@@ -870,9 +887,6 @@ public abstract class RelOptUtil {
         rightKeys,
         filterNulls,
         nonEquiList);
-
-    return RexUtil.composeConjunction(
-        left.getCluster().getRexBuilder(), nonEquiList);
   }
 
   @Deprecated // to be removed before 2.0
@@ -3921,12 +3935,6 @@ public abstract class RelOptUtil {
       this.outerJoin = outerJoin;
     }
   }
-
-  /** Check if it is the join whose condition is based on column equality,
-   * this mostly depends on the physical implementation of the join. */
-  public static boolean forceEquiJoin(Join join) {
-    return join.isSemiJoin() || join instanceof EquiJoin;
-  }
 }
 
 // End RelOptUtil.java
diff --git a/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java 
b/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java
index f2c496f..3821c6d 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java
@@ -37,7 +37,13 @@ import java.util.Set;
  * eliminate some optimize logic for {@code EquiJoin} in some planning rules.
  * e.g. {@link org.apache.calcite.rel.rules.FilterJoinRule} would not push 
non-equi
  * join conditions of the above filter into the join underneath if it is an 
{@code EquiJoin}.
+ *
+ * @deprecated This class is no longer needed; if you are writing a sub-class 
of
+ * Join that only accepts equi conditions, it is sufficient that it extends
+ * {@link Join}. It will be evident that it is an equi-join when its
+ * {@link JoinInfo#nonEquiConditions} is an empty list.
  */
+@Deprecated // to be removed before 2.0
 public abstract class EquiJoin extends Join {
   public final ImmutableIntList leftKeys;
   public final ImmutableIntList rightKeys;
diff --git a/core/src/main/java/org/apache/calcite/rel/core/JoinInfo.java 
b/core/src/main/java/org/apache/calcite/rel/core/JoinInfo.java
index 6588ffa..468cb97 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/JoinInfo.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/JoinInfo.java
@@ -20,34 +20,39 @@ import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.runtime.FlatLists;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.calcite.util.ImmutableIntList;
 import org.apache.calcite.util.mapping.IntPair;
 
+import com.google.common.collect.ImmutableList;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 
 /** An analyzed join condition.
  *
- * <p>It is useful for the many algorithms that care whether a join is an
- * equi-join.
+ * <p>It is useful for the many algorithms that care whether a join has an
+ * equi-join condition.
  *
  * <p>You can create one using {@link #of}, or call
  * {@link Join#analyzeCondition()}; many kinds of join cache their
- * join info, especially those that are equi-joins and sub-class
- * {@link org.apache.calcite.rel.core.EquiJoin}.</p>
+ * join info, especially those that are equi-joins.</p>
  *
  * @see Join#analyzeCondition() */
-public abstract class JoinInfo {
+public class JoinInfo {
   public final ImmutableIntList leftKeys;
   public final ImmutableIntList rightKeys;
+  public final ImmutableList<RexNode> nonEquiConditions;
 
   /** Creates a JoinInfo. */
-  protected JoinInfo(ImmutableIntList leftKeys, ImmutableIntList rightKeys) {
+  protected JoinInfo(ImmutableIntList leftKeys, ImmutableIntList rightKeys,
+      ImmutableList<RexNode> nonEquiConditions) {
     this.leftKeys = Objects.requireNonNull(leftKeys);
     this.rightKeys = Objects.requireNonNull(rightKeys);
+    this.nonEquiConditions = Objects.requireNonNull(nonEquiConditions);
     assert leftKeys.size() == rightKeys.size();
   }
 
@@ -56,26 +61,23 @@ public abstract class JoinInfo {
     final List<Integer> leftKeys = new ArrayList<>();
     final List<Integer> rightKeys = new ArrayList<>();
     final List<Boolean> filterNulls = new ArrayList<>();
-    RexNode remaining =
-        RelOptUtil.splitJoinCondition(left, right, condition, leftKeys,
-            rightKeys, filterNulls);
-    if (remaining.isAlwaysTrue()) {
-      return new EquiJoinInfo(ImmutableIntList.copyOf(leftKeys),
-          ImmutableIntList.copyOf(rightKeys));
-    } else {
-      return new NonEquiJoinInfo(ImmutableIntList.copyOf(leftKeys),
-          ImmutableIntList.copyOf(rightKeys), remaining);
-    }
+    final List<RexNode> nonEquiList = new ArrayList<>();
+    RelOptUtil.splitJoinCondition(left, right, condition, leftKeys, rightKeys,
+        filterNulls, nonEquiList);
+    return new JoinInfo(ImmutableIntList.copyOf(leftKeys),
+        ImmutableIntList.copyOf(rightKeys), ImmutableList.copyOf(nonEquiList));
   }
 
   /** Creates an equi-join. */
   public static JoinInfo of(ImmutableIntList leftKeys,
       ImmutableIntList rightKeys) {
-    return new EquiJoinInfo(leftKeys, rightKeys);
+    return new JoinInfo(leftKeys, rightKeys, ImmutableList.of());
   }
 
   /** Returns whether this is an equi-join. */
-  public abstract boolean isEqui();
+  public boolean isEqui() {
+    return nonEquiConditions.isEmpty();
+  }
 
   /** Returns a list of (left, right) key ordinals. */
   public List<IntPair> pairs() {
@@ -90,7 +92,10 @@ public abstract class JoinInfo {
     return ImmutableBitSet.of(rightKeys);
   }
 
-  public abstract RexNode getRemaining(RexBuilder rexBuilder);
+  @Deprecated // to be removed before 2.0
+  public RexNode getRemaining(RexBuilder rexBuilder) {
+    return RexUtil.composeConjunction(rexBuilder, nonEquiConditions);
+  }
 
   public RexNode getEquiCondition(RelNode left, RelNode right,
       RexBuilder rexBuilder) {
@@ -102,41 +107,6 @@ public abstract class JoinInfo {
     return FlatLists.of(leftKeys, rightKeys);
   }
 
-  /** JoinInfo that represents an equi-join. */
-  private static class EquiJoinInfo extends JoinInfo {
-    protected EquiJoinInfo(ImmutableIntList leftKeys,
-        ImmutableIntList rightKeys) {
-      super(leftKeys, rightKeys);
-    }
-
-    @Override public boolean isEqui() {
-      return true;
-    }
-
-    @Override public RexNode getRemaining(RexBuilder rexBuilder) {
-      return rexBuilder.makeLiteral(true);
-    }
-  }
-
-  /** JoinInfo that represents a non equi-join. */
-  private static class NonEquiJoinInfo extends JoinInfo {
-    public final RexNode remaining;
-
-    protected NonEquiJoinInfo(ImmutableIntList leftKeys,
-        ImmutableIntList rightKeys, RexNode remaining) {
-      super(leftKeys, rightKeys);
-      this.remaining = Objects.requireNonNull(remaining);
-      assert !remaining.isAlwaysTrue();
-    }
-
-    @Override public boolean isEqui() {
-      return false;
-    }
-
-    @Override public RexNode getRemaining(RexBuilder rexBuilder) {
-      return remaining;
-    }
-  }
 }
 
 // End JoinInfo.java
diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java 
b/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
index 144af2c..a0b15ea 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
@@ -16,6 +16,7 @@
  */
 package org.apache.calcite.rel.rules;
 
+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;
@@ -52,21 +53,28 @@ public abstract class FilterJoinRule extends RelOptRule {
    * will be pushed into the ON clause. */
   public static final Predicate TRUE_PREDICATE = (join, joinType, exp) -> true;
 
+  /** Predicate that returns true if the join is not Enumerable convention,
+   * will be replaced by {@link #TRUE_PREDICATE} once enumerable join supports
+   * non-equi join. */
+  // to be removed before 1.22.0
+  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. */
   public static final FilterJoinRule FILTER_ON_JOIN =
       new FilterIntoJoinRule(true, RelFactories.LOGICAL_BUILDER,
-          TRUE_PREDICATE);
+          NOT_ENUMERABLE);
 
   /** Dumber version of {@link #FILTER_ON_JOIN}. Not intended for production
    * use, but keeps some tests working for which {@code FILTER_ON_JOIN} is too
    * smart. */
   public static final FilterJoinRule DUMB_FILTER_ON_JOIN =
       new FilterIntoJoinRule(false, RelFactories.LOGICAL_BUILDER,
-          TRUE_PREDICATE);
+          NOT_ENUMERABLE);
 
   /** Rule that pushes predicates in a Join into the inputs to the join. */
   public static final FilterJoinRule JOIN =
-      new JoinConditionPushRule(RelFactories.LOGICAL_BUILDER, TRUE_PREDICATE);
+      new JoinConditionPushRule(RelFactories.LOGICAL_BUILDER, NOT_ENUMERABLE);
 
   /** Whether to try to strengthen join-type. */
   private final boolean smart;
@@ -98,7 +106,7 @@ public abstract class FilterJoinRule extends RelOptRule {
       boolean smart, RelFactories.FilterFactory filterFactory,
       RelFactories.ProjectFactory projectFactory) {
     this(operand, id, smart, RelBuilder.proto(filterFactory, projectFactory),
-        TRUE_PREDICATE);
+        NOT_ENUMERABLE);
   }
 
   /**
@@ -116,15 +124,6 @@ public abstract class FilterJoinRule extends RelOptRule {
 
   //~ Methods ----------------------------------------------------------------
 
-  /** Returns if it is needed to push the filter condition above join
-   * into the join condition.
-   */
-  private boolean needsPushInto(Join join) {
-    // If the join force the join info to be based on column equality,
-    // or it is a non-correlated semijoin, returns false.
-    return !RelOptUtil.forceEquiJoin(join);
-  }
-
   protected void perform(RelOptRuleCall call, Filter filter,
       Join join) {
     final List<RexNode> joinFilters =
@@ -171,7 +170,7 @@ public abstract class FilterJoinRule extends RelOptRule {
         join,
         aboveFilters,
         joinType,
-        needsPushInto(join),
+        true,
         !joinType.generatesNullsOnLeft(),
         !joinType.generatesNullsOnRight(),
         joinFilters,
diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java 
b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
index 467827d..e91dc88 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
@@ -28,7 +28,6 @@ import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.Calc;
 import org.apache.calcite.rel.core.Filter;
 import org.apache.calcite.rel.core.Join;
-import org.apache.calcite.rel.core.JoinInfo;
 import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rel.core.Window;
@@ -346,15 +345,6 @@ public abstract class ReduceExpressionsRule extends 
RelOptRule {
           matchNullability)) {
         return;
       }
-      if (RelOptUtil.forceEquiJoin(join)) {
-        final JoinInfo joinInfo =
-            JoinInfo.of(join.getLeft(), join.getRight(), expList.get(0));
-        if (!joinInfo.isEqui()) {
-          // This kind of join must be an equi-join, and the condition is
-          // no longer an equi-join. SemiJoin is an example of this.
-          return;
-        }
-      }
       call.transformTo(
           join.copy(
               join.getTraitSet(),
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java 
b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index 8964c1a..d0719d1 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -24,7 +24,6 @@ import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelOptPredicateList;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.InvalidRelException;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelCollations;
@@ -90,7 +89,6 @@ import org.apache.calcite.tools.RelBuilder;
 import org.apache.calcite.util.BuiltInMethod;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.calcite.util.ImmutableIntList;
-import org.apache.calcite.util.TestUtil;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
@@ -1130,12 +1128,8 @@ public class RelMetadataTest extends SqlToRelTestBase {
     final ImmutableIntList leftKeys = ImmutableIntList.of(2);
     final ImmutableIntList rightKeys = ImmutableIntList.of(0);
     final EnumerableMergeJoin join;
-    try {
-      join = EnumerableMergeJoin.create(project, deptSort,
-          rexBuilder.makeLiteral(true), leftKeys, rightKeys, 
JoinRelType.INNER);
-    } catch (InvalidRelException e) {
-      throw TestUtil.rethrow(e);
-    }
+    join = EnumerableMergeJoin.create(project, deptSort,
+        rexBuilder.makeLiteral(true), leftKeys, rightKeys, JoinRelType.INNER);
     collations =
         RelMdCollation.mergeJoin(mq, project, deptSort, leftKeys,
             rightKeys);
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java 
b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 915f626..eb0effd 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -1097,7 +1097,7 @@ public class RelOptRulesTest extends RelOptTestBase {
         .withTrim(true)
         .withPre(preProgram)
         .with(program)
-        .checkUnchanged();
+        .check();
   }
 
   @Test public void testSemiJoinTrim() throws Exception {
diff --git 
a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml 
b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 896215e..c987c22 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -1260,7 +1260,7 @@ LogicalProject(SAL=[$0])
         <Resource name="planAfter">
             <![CDATA[
 LogicalProject(SAL=[$0])
-  LogicalJoin(condition=[=($1, $2)], joinType=[semi])
+  LogicalJoin(condition=[=(200, $2)], joinType=[semi])
     LogicalFilter(condition=[=($1, 200)])
       LogicalProject(SAL=[$5], DEPTNO=[$7])
         LogicalTableScan(table=[[CATALOG, SALES, EMP]])
diff --git 
a/pig/src/test/java/org/apache/calcite/test/PigRelBuilderStyleTest.java 
b/pig/src/test/java/org/apache/calcite/test/PigRelBuilderStyleTest.java
index fd1f9ea..8bc1a32 100644
--- a/pig/src/test/java/org/apache/calcite/test/PigRelBuilderStyleTest.java
+++ b/pig/src/test/java/org/apache/calcite/test/PigRelBuilderStyleTest.java
@@ -253,8 +253,10 @@ public class PigRelBuilderStyleTest extends 
AbstractPigTest {
     planner.removeRule(FilterAggregateTransposeRule.INSTANCE);
     planner.removeRule(FilterJoinRule.FILTER_ON_JOIN);
     planner.addRule(
-        new FilterAggregateTransposeRule(PigFilter.class, builderFactory, 
PigAggregate.class));
-    planner.addRule(new FilterIntoJoinRule(true, builderFactory, 
TRUE_PREDICATE));
+        new FilterAggregateTransposeRule(PigFilter.class, builderFactory,
+            PigAggregate.class));
+    planner.addRule(
+        new FilterIntoJoinRule(true, builderFactory, TRUE_PREDICATE));
     planner.setRoot(root);
     return planner;
   }

Reply via email to