RelBuilder.project now does nothing if asked to project the identity with the 
same field names


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/b5b28f0b
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/b5b28f0b
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/b5b28f0b

Branch: refs/heads/master
Commit: b5b28f0b2d263a2e2fb6894d67c8666549f4d053
Parents: 4ae0298
Author: Julian Hyde <[email protected]>
Authored: Wed Jul 29 22:01:41 2015 -0700
Committer: Julian Hyde <[email protected]>
Committed: Sun Jan 10 00:51:24 2016 -0800

----------------------------------------------------------------------
 core/src/main/java/org/apache/calcite/plan/RelOptUtil.java   | 8 ++++++--
 .../java/org/apache/calcite/plan/SubstitutionVisitor.java    | 3 +--
 .../java/org/apache/calcite/rel/rules/ProjectMergeRule.java  | 5 +++--
 .../java/org/apache/calcite/rel/rules/ProjectRemoveRule.java | 7 ++++---
 core/src/main/java/org/apache/calcite/rex/RexUtil.java       | 7 +++++++
 core/src/main/java/org/apache/calcite/tools/RelBuilder.java  | 6 ++++++
 6 files changed, 27 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/b5b28f0b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
----------------------------------------------------------------------
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 e444612..46a1dbc 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -42,7 +42,6 @@ import org.apache.calcite.rel.logical.LogicalProject;
 import org.apache.calcite.rel.rules.AggregateProjectPullUpConstantsRule;
 import org.apache.calcite.rel.rules.FilterMergeRule;
 import org.apache.calcite.rel.rules.MultiJoin;
-import org.apache.calcite.rel.rules.ProjectRemoveRule;
 import org.apache.calcite.rel.rules.ProjectToWindowRule;
 import org.apache.calcite.rel.rules.PruneEmptyRules;
 import org.apache.calcite.rel.type.RelDataType;
@@ -2706,7 +2705,7 @@ public abstract class RelOptUtil {
             : SqlValidatorUtil.uniquify(fieldNames,
                 SqlValidatorUtil.F_SUGGESTER);
     if (optimize
-        && ProjectRemoveRule.isIdentity(exprs, child.getRowType())) {
+        && RexUtil.isIdentity(exprs, child.getRowType())) {
       if (child instanceof Project && fieldNames != null) {
         final RelDataType rowType =
             RexUtil.createStructType(
@@ -2982,6 +2981,11 @@ public abstract class RelOptUtil {
     final int leftCount = originalJoin.getLeft().getRowType().getFieldCount();
     final int rightCount = 
originalJoin.getRight().getRowType().getFieldCount();
 
+    // You cannot push a 'get' because field names might change.
+    //
+    // Pushing sub-queries is OK in principle (if they don't reference both
+    // sides of the join via correlating variables) but we'd rather not do it
+    // yet.
     if (!containsGet(joinCond)) {
       joinCond = pushDownEqualJoinConditions(
           joinCond, leftCount, rightCount, extraLeftExprs, extraRightExprs);

http://git-wip-us.apache.org/repos/asf/calcite/blob/b5b28f0b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java 
b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
index eb0331f..c88f51d 100644
--- a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
+++ b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
@@ -37,7 +37,6 @@ import org.apache.calcite.rel.logical.LogicalJoin;
 import org.apache.calcite.rel.logical.LogicalProject;
 import org.apache.calcite.rel.logical.LogicalSort;
 import org.apache.calcite.rel.logical.LogicalUnion;
-import org.apache.calcite.rel.rules.ProjectRemoveRule;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexBuilder;
@@ -2144,7 +2143,7 @@ public class SubstitutionVisitor {
     public static boolean isTrivial(MutableProject project) {
       MutableRel child = project.getInput();
       final RelDataType childRowType = child.getRowType();
-      return ProjectRemoveRule.isIdentity(project.getProjects(), childRowType);
+      return RexUtil.isIdentity(project.getProjects(), childRowType);
     }
 
     /** Equivalent to

http://git-wip-us.apache.org/repos/asf/calcite/blob/b5b28f0b/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java 
b/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java
index 4537157..9a4e849 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java
@@ -26,6 +26,7 @@ import 
org.apache.calcite.rel.core.RelFactories.ProjectFactory;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.tools.RelBuilder;
 import org.apache.calcite.tools.RelBuilderFactory;
+import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.util.Permutation;
 
 import java.util.List;
@@ -98,7 +99,7 @@ public class ProjectMergeRule extends RelOptRule {
     // If we're not in force mode and the two projects reference identical
     // inputs, then return and let ProjectRemoveRule replace the projects.
     if (!force) {
-      if (ProjectRemoveRule.isIdentity(topProject.getProjects(),
+      if (RexUtil.isIdentity(topProject.getProjects(),
           topProject.getInput().getRowType())) {
         return;
       }
@@ -107,7 +108,7 @@ public class ProjectMergeRule extends RelOptRule {
     final List<RexNode> newProjects =
         RelOptUtil.pushPastProject(topProject.getProjects(), bottomProject);
     final RelNode input = bottomProject.getInput();
-    if (ProjectRemoveRule.isIdentity(newProjects, input.getRowType())) {
+    if (RexUtil.isIdentity(newProjects, input.getRowType())) {
       if (force
           || input.getRowType().getFieldNames()
               .equals(topProject.getRowType().getFieldNames())) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/b5b28f0b/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java 
b/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java
index 81341fc..8cbbd74 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java
@@ -85,13 +85,14 @@ public class ProjectRemoveRule extends RelOptRule {
   }
 
   public static boolean isTrivial(Project project) {
-    return isIdentity(project.getProjects(), project.getInput().getRowType());
+    return RexUtil.isIdentity(project.getProjects(),
+        project.getInput().getRowType());
   }
 
+  @Deprecated // to be removed before 1.5
   public static boolean isIdentity(List<? extends RexNode> exps,
       RelDataType childRowType) {
-    return childRowType.getFieldCount() == exps.size()
-        && RexUtil.containIdentity(exps, childRowType, false);
+    return RexUtil.isIdentity(exps, childRowType);
   }
 }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/b5b28f0b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java 
b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
index 7307654..d801d1b 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -693,6 +693,13 @@ public class RexUtil {
     return true;
   }
 
+  /** Returns whether a list of expressions projects the incoming fields. */
+  public static boolean isIdentity(List<? extends RexNode> exps,
+      RelDataType inputRowType) {
+    return inputRowType.getFieldCount() == exps.size()
+        && containIdentity(exps, inputRowType, false);
+  }
+
   /**
    * Converts a collection of expressions into an AND.
    * If there are zero expressions, returns TRUE.

http://git-wip-us.apache.org/repos/asf/calcite/blob/b5b28f0b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java 
b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
index 252e703..eb9ad70 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -741,6 +741,12 @@ public class RelBuilder {
     if (ProjectRemoveRule.isIdentity(exprList, peek().getRowType())) {
       return this;
     }
+    final RelDataType inputRowType = peek().getRowType();
+    if (RexUtil.isIdentity(exprList, inputRowType)
+        && names.equals(inputRowType.getFieldNames())) {
+      // Do not create an identity project if it does not rename any fields
+      return this;
+    }
     final RelNode project =
         projectFactory.createProject(build(), ImmutableList.copyOf(exprList),
             names);

Reply via email to