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);
