Repository: calcite Updated Branches: refs/heads/master 5bf7b9a4d -> 03ec2cfda
[CALCITE-2201] Pass RelBuilder into RelDecorrelator and RelStructuredTypeFlattener (Volodymyr Vysotskyi) Add a method RelBuilder.projectNamed to replace RelOptUtil.createProject, and change various other methods in RelOptUtil to use RelBuilder. Deprecate obsolete methods in RelOptUtil. Close apache/calcite#640 Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/03ec2cfd Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/03ec2cfd Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/03ec2cfd Branch: refs/heads/master Commit: 03ec2cfda469f9e401ff0ad1045f94cee4a80e1f Parents: 5bf7b9a Author: Volodymyr Vysotskyi <[email protected]> Authored: Wed Feb 7 15:05:27 2018 +0200 Committer: Julian Hyde <[email protected]> Committed: Mon Mar 26 14:21:54 2018 -0700 ---------------------------------------------------------------------- .../org/apache/calcite/plan/RelOptUtil.java | 203 +++++++++---------- .../org/apache/calcite/prepare/PlannerImpl.java | 17 +- .../calcite/rel/rules/JoinCommuteRule.java | 33 +-- .../apache/calcite/rel/rules/PushProjector.java | 18 +- .../apache/calcite/sql2rel/RelDecorrelator.java | 182 ++++++++++------- .../sql2rel/RelStructuredTypeFlattener.java | 42 ++-- .../calcite/sql2rel/SqlToRelConverter.java | 88 ++++---- .../java/org/apache/calcite/tools/Programs.java | 4 +- .../org/apache/calcite/tools/RelBuilder.java | 46 +++++ .../plan/volcano/VolcanoPlannerTest.java | 16 +- .../org/apache/calcite/test/MutableRelTest.java | 6 +- .../org/apache/calcite/test/RelOptTestBase.java | 10 +- .../calcite/test/SqlToRelConverterTest.xml | 55 +++-- 13 files changed, 400 insertions(+), 320 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/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 52407f8..beaa2c1 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java @@ -91,7 +91,6 @@ import org.apache.calcite.sql.SqlOperator; import org.apache.calcite.sql.fun.SqlStdOperatorTable; import org.apache.calcite.sql.type.MultisetSqlType; import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.sql.validate.SqlValidatorUtil; import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.tools.RelBuilderFactory; import org.apache.calcite.util.ImmutableBitSet; @@ -486,7 +485,6 @@ public abstract class RelOptUtil { if (extraExpr != null) { RexBuilder rexBuilder = cluster.getRexBuilder(); - RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory(); assert extraExpr == rexBuilder.makeLiteral(true); @@ -495,7 +493,11 @@ public abstract class RelOptUtil { // agg does not like no agg functions so just pretend it is // doing a min(TRUE) - ret = createProject(ret, ImmutableList.of(extraExpr), null); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(cluster, null); + ret = relBuilder.push(ret) + .project(ImmutableList.of(extraExpr)) + .build(); final AggregateCall aggCall = AggregateCall.create(SqlStdOperatorTable.MIN, @@ -516,6 +518,17 @@ public abstract class RelOptUtil { return ret; } + @Deprecated // to be removed before 2.0 + public static Exists createExistsPlan( + RelNode seekRel, + SubQueryType subQueryType, + Logic logic, + boolean notIn) { + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(seekRel.getCluster(), null); + return createExistsPlan(seekRel, subQueryType, logic, notIn, relBuilder); + } + /** * Creates a plan suitable for use in <code>EXISTS</code> or <code>IN</code> * statements. @@ -527,6 +540,7 @@ public abstract class RelOptUtil { * @param subQueryType Sub-query type * @param logic Whether to use 2- or 3-valued boolean logic * @param notIn Whether the operator is NOT IN + * @param relBuilder Builder for relational expressions * * @return A pair of a relational expression which outer joins a boolean * condition column, and a numeric offset. The offset is 2 if column 0 is @@ -537,7 +551,8 @@ public abstract class RelOptUtil { RelNode seekRel, SubQueryType subQueryType, Logic logic, - boolean notIn) { + boolean notIn, + RelBuilder relBuilder) { switch (subQueryType) { case SCALAR: return new Exists(seekRel, false, true); @@ -574,7 +589,7 @@ public abstract class RelOptUtil { final int projectedKeyCount = exprs.size(); exprs.add(rexBuilder.makeLiteral(true)); - ret = createProject(ret, exprs, null); + ret = relBuilder.push(ret).project(exprs).build(); final AggregateCall aggCall = AggregateCall.create(SqlStdOperatorTable.MIN, @@ -625,7 +640,11 @@ public abstract class RelOptUtil { inputField.getIndex()), outputField.getName())); } - return createProject(rel, Pair.left(renames), Pair.right(renames)); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(rel.getCluster(), null); + return relBuilder.push(rel) + .project(Pair.left(renames), Pair.right(renames), true) + .build(); } @Deprecated // to be removed before 2.0 @@ -1660,18 +1679,21 @@ public abstract class RelOptUtil { } } + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(cluster, null); + // added project if need to produce new keys than the original input // fields if (newLeftKeyCount > 0) { - leftRel = createProject(leftRel, newLeftFields, - SqlValidatorUtil.uniquify(newLeftFieldNames, - typeSystem.isSchemaCaseSensitive())); + leftRel = relBuilder.push(leftRel) + .project(newLeftFields, newLeftFieldNames, true) + .build(); } if (newRightKeyCount > 0) { - rightRel = createProject(rightRel, newRightFields, - SqlValidatorUtil.uniquify(newRightFieldNames, - typeSystem.isSchemaCaseSensitive())); + rightRel = relBuilder.push(rightRel) + .project(newRightFields, newRightFieldNames) + .build(); } inputRels[0] = leftRel; @@ -1692,7 +1714,9 @@ public abstract class RelOptUtil { if ((newProjectOutputSize > 0) && (newProjectOutputSize < joinOutputFields.size())) { final List<Pair<RexNode, String>> newProjects = new ArrayList<>(); - RexBuilder rexBuilder = joinRel.getCluster().getRexBuilder(); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(joinRel.getCluster(), null); + final RexBuilder rexBuilder = relBuilder.getRexBuilder(); for (int fieldIndex : outputProj) { final RelDataTypeField field = joinOutputFields.get(fieldIndex); newProjects.add( @@ -1702,10 +1726,9 @@ public abstract class RelOptUtil { } // Create a project rel on the output of the join. - return createProject( - joinRel, - Pair.left(newProjects), - Pair.right(newProjects)); + return relBuilder.push(joinRel) + .project(Pair.left(newProjects), Pair.right(newProjects), true) + .build(); } return joinRel; @@ -2844,34 +2867,29 @@ public abstract class RelOptUtil { Mappings.apply3(mapping, rowType.getFieldList())); } - /** - * Creates a relational expression which projects a list of expressions. - * - * @param child input relational expression - * @param exprList list of expressions for the input columns - * @param fieldNameList aliases of the expressions, or null to generate - */ + @Deprecated // to be removed before 2.0 public static RelNode createProject( RelNode child, List<? extends RexNode> exprList, List<String> fieldNameList) { - return createProject(child, exprList, fieldNameList, false); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(child.getCluster(), null); + return relBuilder.push(child) + .project(exprList, fieldNameList, true) + .build(); } - /** - * Creates a relational expression which projects a list of (expression, name) - * pairs. - * - * @param child input relational expression - * @param projectList list of (expression, name) pairs - * @param optimize Whether to optimize - */ + @Deprecated // to be removed before 2.0 public static RelNode createProject( RelNode child, List<Pair<RexNode, String>> projectList, boolean optimize) { - return createProject(child, Pair.left(projectList), Pair.right(projectList), - optimize, RelFactories.LOGICAL_BUILDER.create(child.getCluster(), null)); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(child.getCluster(), null); + return relBuilder.push(child) + .projectNamed(Pair.left(projectList), Pair.right(projectList), + !optimize) + .build(); } /** @@ -2890,71 +2908,31 @@ public abstract class RelOptUtil { RelFactories.DEFAULT_PROJECT_FACTORY, child, posList); } - /** - * Creates a relational expression which projects an array of expressions, - * and optionally optimizes. - * - * <p>The result may not be a - * {@link org.apache.calcite.rel.logical.LogicalProject}. If the - * projection is trivial, <code>child</code> is returned directly; and future - * versions may return other formulations of expressions, such as - * {@link org.apache.calcite.rel.logical.LogicalCalc}. - * - * @param child input relational expression - * @param exprs list of expressions for the input columns - * @param fieldNames aliases of the expressions, or null to generate - * @param optimize Whether to return <code>child</code> unchanged if the - * projections are trivial. - */ + @Deprecated // to be removed before 2.0 public static RelNode createProject( RelNode child, List<? extends RexNode> exprs, List<String> fieldNames, boolean optimize) { - return createProject(child, exprs, fieldNames, optimize, - RelFactories.LOGICAL_BUILDER.create(child.getCluster(), null)); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(child.getCluster(), null); + return relBuilder.push(child) + .projectNamed(exprs, fieldNames, !optimize) + .build(); } - /** - * Creates a relational expression which projects an array of expressions, - * and optionally optimizes. - * - * <p>The result may not be a - * {@link org.apache.calcite.rel.logical.LogicalProject}. If the - * projection is trivial, <code>child</code> is returned directly; and future - * versions may return other formulations of expressions, such as - * {@link org.apache.calcite.rel.logical.LogicalCalc}. - * - * @param child input relational expression - * @param exprs list of expressions for the input columns - * @param fieldNames aliases of the expressions, or null to generate - * @param optimize Whether to return <code>child</code> unchanged if the - * projections are trivial. - * @param relBuilder Factory to create project operators - */ + /** @deprecated Use + * {@link RelBuilder#projectNamed(Iterable, Iterable, boolean)} */ + @Deprecated // to be removed before 2.0 public static RelNode createProject( RelNode child, List<? extends RexNode> exprs, List<String> fieldNames, boolean optimize, RelBuilder relBuilder) { - final RelOptCluster cluster = child.getCluster(); - final RelDataType rowType = - RexUtil.createStructType(cluster.getTypeFactory(), exprs, - fieldNames, SqlValidatorUtil.F_SUGGESTER); - if (optimize - && RexUtil.isIdentity(exprs, child.getRowType())) { - if (child instanceof Project && fieldNames != null) { - // Rename columns of child projection if desired field names are given. - Project childProject = (Project) child; - child = childProject.copy(childProject.getTraitSet(), - childProject.getInput(), childProject.getProjects(), rowType); - } - return child; - } - relBuilder.push(child); - relBuilder.project(exprs, rowType.getFieldNames(), !optimize); - return relBuilder.build(); + return relBuilder.push(child) + .projectNamed(exprs, fieldNames, !optimize) + .build(); } @Deprecated // to be removed before 2.0 @@ -2973,7 +2951,11 @@ public abstract class RelOptUtil { return RexInputRef.of(index, fields); } }; - return createProject(rel, refs, fieldNames, true); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(rel.getCluster(), null); + return relBuilder.push(rel) + .projectNamed(refs, fieldNames, false) + .build(); } /** @@ -3072,29 +3054,32 @@ public abstract class RelOptUtil { final RelNode child, final List<Integer> posList) { RelDataType rowType = child.getRowType(); final List<String> fieldNames = rowType.getFieldNames(); - final RexBuilder rexBuilder = child.getCluster().getRexBuilder(); - return createProject(child, - new AbstractList<RexNode>() { - public int size() { - return posList.size(); - } + final RelBuilder relBuilder = + RelBuilder.proto(factory).create(child.getCluster(), null); + final List<RexNode> exprs = new AbstractList<RexNode>() { + public int size() { + return posList.size(); + } - public RexNode get(int index) { - final int pos = posList.get(index); - return rexBuilder.makeInputRef(child, pos); - } - }, - new AbstractList<String>() { - public int size() { - return posList.size(); - } + public RexNode get(int index) { + final int pos = posList.get(index); + return relBuilder.getRexBuilder().makeInputRef(child, pos); + } + }; + final List<String> names = new AbstractList<String>() { + public int size() { + return posList.size(); + } - public String get(int index) { - final int pos = posList.get(index); - return fieldNames.get(pos); - } - }, true, - RelBuilder.proto(factory).create(child.getCluster(), null)); + public String get(int index) { + final int pos = posList.get(index); + return fieldNames.get(pos); + } + }; + return relBuilder + .push(child) + .projectNamed(exprs, names, false) + .build(); } @Deprecated // to be removed before 2.0 http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java index cf0e4cf..e5f2ae0 100644 --- a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java +++ b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java @@ -51,6 +51,7 @@ import org.apache.calcite.tools.FrameworkConfig; import org.apache.calcite.tools.Frameworks; import org.apache.calcite.tools.Planner; import org.apache.calcite.tools.Program; +import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.tools.RelConversionException; import org.apache.calcite.tools.ValidationException; import org.apache.calcite.util.Pair; @@ -239,7 +240,10 @@ public class PlannerImpl implements Planner { root = sqlToRelConverter.convertQuery(validatedSqlNode, false, true); root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); - root = root.withRel(RelDecorrelator.decorrelateQuery(root.rel)); + final RelBuilder relBuilder = + config.getRelBuilderFactory().create(cluster, null); + root = root.withRel( + RelDecorrelator.decorrelateQuery(root.rel, relBuilder)); state = State.STATE_5_CONVERTED; return root; } @@ -280,7 +284,10 @@ public class PlannerImpl implements Planner { root = sqlToRelConverter.convertQuery(validatedSqlNode, true, false); root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); - root = root.withRel(RelDecorrelator.decorrelateQuery(root.rel)); + final RelBuilder relBuilder = + config.getRelBuilderFactory().create(cluster, null); + root = root.withRel( + RelDecorrelator.decorrelateQuery(root.rel, relBuilder)); return PlannerImpl.this.root; } @@ -288,9 +295,9 @@ public class PlannerImpl implements Planner { // CalciteCatalogReader is stateless; no need to store one private CalciteCatalogReader createCatalogReader() { - SchemaPlus rootSchema = rootSchema(defaultSchema); - Context context = config.getContext(); - CalciteConnectionConfig connectionConfig = null; + final SchemaPlus rootSchema = rootSchema(defaultSchema); + final Context context = config.getContext(); + final CalciteConnectionConfig connectionConfig; if (context != null) { connectionConfig = context.unwrap(CalciteConnectionConfig.class); http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java b/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java index 28d48af..315a0cd 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java @@ -89,13 +89,16 @@ public class JoinCommuteRule extends RelOptRule { //~ Methods ---------------------------------------------------------------- - /** - * Returns a relational expression with the inputs switched round. Does not - * modify <code>join</code>. Returns null if the join cannot be swapped (for - * example, because it is an outer join). - */ + @Deprecated // to be removed before 2.0 public static RelNode swap(Join join) { - return swap(join, false); + return swap(join, false, + RelFactories.LOGICAL_BUILDER.create(join.getCluster(), null)); + } + + @Deprecated // to be removed before 2.0 + public static RelNode swap(Join join, boolean swapOuterJoins) { + return swap(join, swapOuterJoins, + RelFactories.LOGICAL_BUILDER.create(join.getCluster(), null)); } /** @@ -103,11 +106,13 @@ public class JoinCommuteRule extends RelOptRule { * modify <code>join</code>. Returns null if the join cannot be swapped (for * example, because it is an outer join). * - * @param join join to be swapped - * @param swapOuterJoins whether outer joins should be swapped + * @param join join to be swapped + * @param swapOuterJoins whether outer joins should be swapped + * @param relBuilder Builder for relational expressions * @return swapped join if swapping possible; else null */ - public static RelNode swap(Join join, boolean swapOuterJoins) { + public static RelNode swap(Join join, boolean swapOuterJoins, + RelBuilder relBuilder) { final JoinRelType joinType = join.getJoinType(); if (!swapOuterJoins && joinType != JoinRelType.INNER) { return null; @@ -130,11 +135,9 @@ public class JoinCommuteRule extends RelOptRule { join.getLeft(), joinType.swap(), join.isSemiJoinDone()); final List<RexNode> exps = RelOptUtil.createSwappedJoinExprs(newJoin, join, true); - return RelOptUtil.createProject( - newJoin, - exps, - join.getRowType().getFieldNames(), - true); + return relBuilder.push(newJoin) + .project(exps, join.getRowType().getFieldNames()) + .build(); } public void onMatch(final RelOptRuleCall call) { @@ -145,7 +148,7 @@ public class JoinCommuteRule extends RelOptRule { return; } - final RelNode swapped = swap(join, this.swapOuter); + final RelNode swapped = swap(join, this.swapOuter, call.builder()); if (swapped == null) { return; } http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/main/java/org/apache/calcite/rel/rules/PushProjector.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/rules/PushProjector.java b/core/src/main/java/org/apache/calcite/rel/rules/PushProjector.java index e822d31..8eaf1a4 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/PushProjector.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/PushProjector.java @@ -508,12 +508,9 @@ public class PushProjector { ((RexCall) projExpr).getOperator().getName())); } - return (Project) RelOptUtil.createProject( - projChild, - Pair.left(newProjects), - Pair.right(newProjects), - false, - relBuilder); + return (Project) relBuilder.push(projChild) + .projectNamed(Pair.left(newProjects), Pair.right(newProjects), true) + .build(); } /** @@ -597,12 +594,9 @@ public class PushProjector { field.e.getType(), field.i), field.e.getName())); } } - return RelOptUtil.createProject( - projChild, - Pair.left(projects), - Pair.right(projects), - true /* optimize to avoid trivial projections, as per javadoc */, - relBuilder); + return relBuilder.push(projChild) + .project(Pair.left(projects), Pair.right(projects)) + .build(); } //~ Inner Classes ---------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java index cb71879..7d9bf1e 100644 --- a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java +++ b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java @@ -75,6 +75,7 @@ import org.apache.calcite.sql.fun.SqlCountAggFunction; import org.apache.calcite.sql.fun.SqlSingleValueAggFunction; import org.apache.calcite.sql.fun.SqlStdOperatorTable; import org.apache.calcite.tools.RelBuilder; +import org.apache.calcite.tools.RelBuilderFactory; import org.apache.calcite.util.Bug; import org.apache.calcite.util.Holder; import org.apache.calcite.util.ImmutableBitSet; @@ -154,8 +155,6 @@ public class RelDecorrelator implements ReflectiveVisitor { ReflectUtil.createMethodDispatcher(Frame.class, this, "decorrelateRel", RelNode.class); - private final RexBuilder rexBuilder; - // The rel which is being visited private RelNode currentRel; @@ -171,28 +170,35 @@ public class RelDecorrelator implements ReflectiveVisitor { //~ Constructors ----------------------------------------------------------- private RelDecorrelator( - RelOptCluster cluster, CorelMap cm, - Context context) { + Context context, + RelBuilder relBuilder) { this.cm = cm; - this.rexBuilder = cluster.getRexBuilder(); this.context = context; - relBuilder = RelFactories.LOGICAL_BUILDER.create(cluster, null); - + this.relBuilder = relBuilder; } //~ Methods ---------------------------------------------------------------- + @Deprecated // to be removed before 2.0 + public static RelNode decorrelateQuery(RelNode rootRel) { + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(rootRel.getCluster(), null); + return decorrelateQuery(rootRel, relBuilder); + } + /** Decorrelates a query. * * <p>This is the main entry point to {@code RelDecorrelator}. * - * @param rootRel Root node of the query + * @param rootRel Root node of the query + * @param relBuilder Builder for relational expressions * * @return Equivalent query with all * {@link org.apache.calcite.rel.logical.LogicalCorrelate} instances removed */ - public static RelNode decorrelateQuery(RelNode rootRel) { + public static RelNode decorrelateQuery(RelNode rootRel, + RelBuilder relBuilder) { final CorelMap corelMap = new CorelMapBuilder().build(rootRel); if (!corelMap.hasCorrelation()) { return rootRel; @@ -200,8 +206,8 @@ public class RelDecorrelator implements ReflectiveVisitor { final RelOptCluster cluster = rootRel.getCluster(); final RelDecorrelator decorrelator = - new RelDecorrelator(cluster, corelMap, - cluster.getPlanner().getContext()); + new RelDecorrelator(corelMap, + cluster.getPlanner().getContext(), relBuilder); RelNode newRootRel = decorrelator.removeCorrelationViaRule(rootRel); @@ -225,14 +231,23 @@ public class RelDecorrelator implements ReflectiveVisitor { } } + private RelBuilderFactory relBuilderFactory() { + return RelBuilder.proto(relBuilder); + } + private RelNode decorrelate(RelNode root) { // first adjust count() expression if any + final RelBuilderFactory f = relBuilderFactory(); HepProgram program = HepProgram.builder() - .addRuleInstance(new AdjustProjectForCountAggregateRule(false)) - .addRuleInstance(new AdjustProjectForCountAggregateRule(true)) - .addRuleInstance(FilterJoinRule.FILTER_ON_JOIN) - .addRuleInstance(FilterProjectTransposeRule.INSTANCE) - .addRuleInstance(FilterCorrelateRule.INSTANCE) + .addRuleInstance(new AdjustProjectForCountAggregateRule(false, f)) + .addRuleInstance(new AdjustProjectForCountAggregateRule(true, f)) + .addRuleInstance( + new FilterJoinRule.FilterIntoJoinRule(true, f, + FilterJoinRule.TRUE_PREDICATE)) + .addRuleInstance( + new FilterProjectTransposeRule(Filter.class, Project.class, true, + true, f)) + .addRuleInstance(new FilterCorrelateRule(f)) .build(); HepPlanner planner = createPlanner(program); @@ -247,8 +262,14 @@ public class RelDecorrelator implements ReflectiveVisitor { if (frame != null) { // has been rewritten; apply rules post-decorrelation final HepProgram program2 = HepProgram.builder() - .addRuleInstance(FilterJoinRule.FILTER_ON_JOIN) - .addRuleInstance(FilterJoinRule.JOIN) + .addRuleInstance( + new FilterJoinRule.FilterIntoJoinRule( + true, f, + FilterJoinRule.TRUE_PREDICATE)) + .addRuleInstance( + new FilterJoinRule.JoinConditionPushRule( + f, + FilterJoinRule.TRUE_PREDICATE)) .build(); final HepPlanner planner2 = createPlanner(program2); @@ -296,10 +317,11 @@ public class RelDecorrelator implements ReflectiveVisitor { } public RelNode removeCorrelationViaRule(RelNode root) { + final RelBuilderFactory f = relBuilderFactory(); HepProgram program = HepProgram.builder() - .addRuleInstance(new RemoveSingleAggregateRule()) - .addRuleInstance(new RemoveCorrelationForScalarProjectRule()) - .addRuleInstance(new RemoveCorrelationForScalarAggregateRule()) + .addRuleInstance(new RemoveSingleAggregateRule(f)) + .addRuleInstance(new RemoveCorrelationForScalarProjectRule(f)) + .addRuleInstance(new RemoveCorrelationForScalarAggregateRule(f)) .build(); HepPlanner planner = createPlanner(program); @@ -319,7 +341,7 @@ public class RelDecorrelator implements ReflectiveVisitor { RexNode exp, boolean projectPulledAboveLeftCorrelator) { RemoveCorrelationRexShuttle shuttle = - new RemoveCorrelationRexShuttle(rexBuilder, + new RemoveCorrelationRexShuttle(relBuilder.getRexBuilder(), projectPulledAboveLeftCorrelator, null, ImmutableSet.<Integer>of()); return exp.accept(shuttle); } @@ -329,7 +351,7 @@ public class RelDecorrelator implements ReflectiveVisitor { boolean projectPulledAboveLeftCorrelator, RexInputRef nullIndicator) { RemoveCorrelationRexShuttle shuttle = - new RemoveCorrelationRexShuttle(rexBuilder, + new RemoveCorrelationRexShuttle(relBuilder.getRexBuilder(), projectPulledAboveLeftCorrelator, nullIndicator, ImmutableSet.<Integer>of()); return exp.accept(shuttle); @@ -340,7 +362,7 @@ public class RelDecorrelator implements ReflectiveVisitor { boolean projectPulledAboveLeftCorrelator, Set<Integer> isCount) { RemoveCorrelationRexShuttle shuttle = - new RemoveCorrelationRexShuttle(rexBuilder, + new RemoveCorrelationRexShuttle(relBuilder.getRexBuilder(), projectPulledAboveLeftCorrelator, null, isCount); return exp.accept(shuttle); } @@ -516,8 +538,9 @@ public class RelDecorrelator implements ReflectiveVisitor { // This Project will be what the old input maps to, // replacing any previous mapping from old input). - RelNode newProject = - RelOptUtil.createProject(newInput, projects, false); + RelNode newProject = relBuilder.push(newInput) + .projectNamed(Pair.left(projects), Pair.right(projects), true) + .build(); // update mappings: // oldInput ----> newInput @@ -669,8 +692,9 @@ public class RelDecorrelator implements ReflectiveVisitor { newPos++; } - RelNode newProject = - RelOptUtil.createProject(frame.r, projects, false); + RelNode newProject = relBuilder.push(frame.r) + .projectNamed(Pair.left(projects), Pair.right(projects), true) + .build(); return register(rel, newProject, mapOldToNewOutputs, corDefOutputs); } @@ -901,7 +925,7 @@ public class RelDecorrelator implements ReflectiveVisitor { createValueGenerator(corVarList, leftInputOutputCount, corDefOutputs); RelNode join = - LogicalJoin.create(frame.r, valueGen, rexBuilder.makeLiteral(true), + LogicalJoin.create(frame.r, valueGen, relBuilder.literal(true), ImmutableSet.<CorrelationId>of(), JoinRelType.INNER); // Join or Filter does not change the old input ordering. All @@ -1077,7 +1101,7 @@ public class RelDecorrelator implements ReflectiveVisitor { final int newLeftPos = leftFrame.oldToNewOutputs.get(corDef.field); final int newRightPos = rightOutput.getValue(); conditions.add( - rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, + relBuilder.call(SqlStdOperatorTable.EQUALS, RexInputRef.of(newLeftPos, newLeftOutput), new RexInputRef(newLeftFieldCount + newRightPos, newRightOutput.get(newRightPos).getType()))); @@ -1117,7 +1141,8 @@ public class RelDecorrelator implements ReflectiveVisitor { } final RexNode condition = - RexUtil.composeConjunction(rexBuilder, conditions, false); + RexUtil.composeConjunction(relBuilder.getRexBuilder(), conditions, + false); RelNode newJoin = LogicalJoin.create(leftFrame.r, rightFrame.r, condition, ImmutableSet.<CorrelationId>of(), rel.getJoinType().toJoinType()); @@ -1283,7 +1308,9 @@ public class RelDecorrelator implements ReflectiveVisitor { newProjExprs.add(Pair.of(newProjExpr, pair.right)); } - return RelOptUtil.createProject(join, newProjExprs, false); + return relBuilder.push(join) + .projectNamed(Pair.left(newProjExprs), Pair.right(newProjExprs), true) + .build(); } /** @@ -1330,7 +1357,9 @@ public class RelDecorrelator implements ReflectiveVisitor { newProjects.add(Pair.of(newProjExpr, pair.right)); } - return RelOptUtil.createProject(correlate, newProjects, false); + return relBuilder.push(correlate) + .projectNamed(Pair.left(newProjects), Pair.right(newProjects), true) + .build(); } /** @@ -1416,12 +1445,14 @@ public class RelDecorrelator implements ReflectiveVisitor { for (Ord<RelDataTypeField> field : Ord.zip(fieldList)) { projects.add( Pair.of( - (RexNode) rexBuilder.makeInputRef( + (RexNode) relBuilder.getRexBuilder().makeInputRef( field.e.getType(), field.i), field.e.getName())); } projects.addAll(additionalExprs); - return RelOptUtil.createProject(input, projects, false); + return relBuilder.push(input) + .projectNamed(Pair.left(projects), Pair.right(projects), true) + .build(); } /* Returns an immutable map with the identity [0: 0, .., count-1: count-1]. */ @@ -1718,13 +1749,14 @@ public class RelDecorrelator implements ReflectiveVisitor { * AggRel single group</blockquote> */ private final class RemoveSingleAggregateRule extends RelOptRule { - RemoveSingleAggregateRule() { + RemoveSingleAggregateRule(RelBuilderFactory relBuilderFactory) { super( operand( LogicalAggregate.class, operand( LogicalProject.class, - operand(LogicalAggregate.class, any())))); + operand(LogicalAggregate.class, any()))), + relBuilderFactory, null); } public void onMatch(RelOptRuleCall call) { @@ -1755,29 +1787,28 @@ public class RelDecorrelator implements ReflectiveVisitor { // singleAggRel produces a nullable type, so create the new // projection that casts proj expr to a nullable type. - final RelOptCluster cluster = project.getCluster(); - RelNode newProject = - RelOptUtil.createProject(aggregate, - ImmutableList.of( - rexBuilder.makeCast( - cluster.getTypeFactory().createTypeWithNullability( - projExprs.get(0).getType(), - true), - projExprs.get(0))), - null); - call.transformTo(newProject); + final RelBuilder relBuilder = call.builder(); + final RelDataType type = + relBuilder.getTypeFactory() + .createTypeWithNullability(projExprs.get(0).getType(), true); + final RexNode cast = + relBuilder.getRexBuilder().makeCast(type, projExprs.get(0)); + relBuilder.push(aggregate) + .project(cast); + call.transformTo(relBuilder.build()); } } /** Planner rule that removes correlations for scalar projects. */ private final class RemoveCorrelationForScalarProjectRule extends RelOptRule { - RemoveCorrelationForScalarProjectRule() { + RemoveCorrelationForScalarProjectRule(RelBuilderFactory relBuilderFactory) { super( operand(LogicalCorrelate.class, operand(RelNode.class, any()), operand(LogicalAggregate.class, operand(LogicalProject.class, - operand(RelNode.class, any()))))); + operand(RelNode.class, any())))), + relBuilderFactory, null); } public void onMatch(RelOptRuleCall call) { @@ -1803,9 +1834,9 @@ public class RelDecorrelator implements ReflectiveVisitor { // corRel.getCondition was here, however Correlate was updated so it // never includes a join condition. The code was not modified for brevity. - RexNode joinCond = rexBuilder.makeLiteral(true); + RexNode joinCond = relBuilder.literal(true); if ((joinType != JoinRelType.LEFT) - || (joinCond != rexBuilder.makeLiteral(true))) { + || (joinCond != relBuilder.literal(true))) { return; } @@ -1935,8 +1966,7 @@ public class RelDecorrelator implements ReflectiveVisitor { right = createProjectWithAdditionalExprs(right, ImmutableList.of( - Pair.<RexNode, String>of( - rexBuilder.makeLiteral(true), "nullIndicator"))); + Pair.of(relBuilder.literal(true), "nullIndicator"))); // make the new aggRel right = @@ -1969,14 +1999,15 @@ public class RelDecorrelator implements ReflectiveVisitor { /** Planner rule that removes correlations for scalar aggregates. */ private final class RemoveCorrelationForScalarAggregateRule extends RelOptRule { - RemoveCorrelationForScalarAggregateRule() { + RemoveCorrelationForScalarAggregateRule(RelBuilderFactory relBuilderFactory) { super( operand(LogicalCorrelate.class, operand(RelNode.class, any()), operand(LogicalProject.class, operand(LogicalAggregate.class, null, Aggregate.IS_SIMPLE, operand(LogicalProject.class, - operand(RelNode.class, any())))))); + operand(RelNode.class, any()))))), + relBuilderFactory, null); } public void onMatch(RelOptRuleCall call) { @@ -1986,6 +2017,8 @@ public class RelDecorrelator implements ReflectiveVisitor { final LogicalAggregate aggregate = call.rel(3); final LogicalProject aggInputProject = call.rel(4); RelNode right = call.rel(5); + final RelBuilder builder = call.builder(); + final RexBuilder rexBuilder = builder.getRexBuilder(); final RelOptCluster cluster = correlate.getCluster(); setCurrent(call.getPlanner().getRoot(), correlate); @@ -2267,11 +2300,9 @@ public class RelDecorrelator implements ReflectiveVisitor { joinOutputProjects.add( rexBuilder.makeInputRef(join, nullIndicatorPos)); - RelNode joinOutputProject = - RelOptUtil.createProject( - join, - joinOutputProjects, - null); + final RelNode joinOutputProject = builder.push(join) + .project(joinOutputProjects) + .build(); // nullIndicator is now at a different location in the output of // the join @@ -2324,13 +2355,9 @@ public class RelDecorrelator implements ReflectiveVisitor { true), newAggOutputProjects)); - RelNode newAggOutputProject = - RelOptUtil.createProject( - newAggregate, - newAggOutputProjectList, - null); - - call.transformTo(newAggOutputProject); + builder.push(newAggregate) + .project(newAggOutputProjectList); + call.transformTo(builder.build()); removeCorVarFromTree(correlate); } @@ -2348,7 +2375,8 @@ public class RelDecorrelator implements ReflectiveVisitor { private final class AdjustProjectForCountAggregateRule extends RelOptRule { final boolean flavor; - AdjustProjectForCountAggregateRule(boolean flavor) { + AdjustProjectForCountAggregateRule(boolean flavor, + RelBuilderFactory relBuilderFactory) { super( flavor ? operand(LogicalCorrelate.class, @@ -2357,7 +2385,8 @@ public class RelDecorrelator implements ReflectiveVisitor { operand(LogicalAggregate.class, any()))) : operand(LogicalCorrelate.class, operand(RelNode.class, any()), - operand(LogicalAggregate.class, any()))); + operand(LogicalAggregate.class, any())), + relBuilderFactory, null); this.flavor = flavor; } @@ -2379,11 +2408,10 @@ public class RelDecorrelator implements ReflectiveVisitor { for (int i = 0; i < fields.size(); i++) { projects.add(RexInputRef.of2(projects.size(), fields)); } - aggOutputProject = - (LogicalProject) RelOptUtil.createProject( - aggregate, - projects, - false); + final RelBuilder relBuilder = call.builder(); + relBuilder.push(aggregate) + .projectNamed(Pair.left(projects), Pair.right(projects), true); + aggOutputProject = (LogicalProject) relBuilder.build(); } onMatch2(call, correlate, left, aggOutputProject, aggregate); } @@ -2420,9 +2448,9 @@ public class RelDecorrelator implements ReflectiveVisitor { JoinRelType joinType = correlate.getJoinType().toJoinType(); // corRel.getCondition was here, however Correlate was updated so it // never includes a join condition. The code was not modified for brevity. - RexNode joinCond = rexBuilder.makeLiteral(true); + RexNode joinCond = relBuilder.literal(true); if ((joinType != JoinRelType.LEFT) - || (joinCond != rexBuilder.makeLiteral(true))) { + || (joinCond != relBuilder.literal(true))) { return; } http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java index f07d665..28ed8f1 100644 --- a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java +++ b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java @@ -18,13 +18,13 @@ package org.apache.calcite.sql2rel; import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelOptTable; -import org.apache.calcite.plan.RelOptUtil; import org.apache.calcite.rel.RelCollation; import org.apache.calcite.rel.RelFieldCollation; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.RelVisitor; import org.apache.calcite.rel.core.Collect; import org.apache.calcite.rel.core.CorrelationId; +import org.apache.calcite.rel.core.RelFactories; import org.apache.calcite.rel.core.Sample; import org.apache.calcite.rel.core.Sort; import org.apache.calcite.rel.core.TableScan; @@ -65,6 +65,7 @@ import org.apache.calcite.sql.SqlOperator; import org.apache.calcite.sql.fun.SqlStdOperatorTable; import org.apache.calcite.sql.type.SqlTypeName; import org.apache.calcite.sql.type.SqlTypeUtil; +import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.Pair; import org.apache.calcite.util.ReflectUtil; @@ -125,6 +126,7 @@ import java.util.SortedSet; public class RelStructuredTypeFlattener implements ReflectiveVisitor { //~ Instance fields -------------------------------------------------------- + private final RelBuilder relBuilder; private final RexBuilder rexBuilder; private final boolean restructure; @@ -137,10 +139,21 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor { //~ Constructors ----------------------------------------------------------- + @Deprecated // to be removed before 2.0 public RelStructuredTypeFlattener( RexBuilder rexBuilder, RelOptTable.ToRelContext toRelContext, boolean restructure) { + this(RelFactories.LOGICAL_BUILDER.create(toRelContext.getCluster(), null), + rexBuilder, toRelContext, restructure); + } + + public RelStructuredTypeFlattener( + RelBuilder relBuilder, + RexBuilder rexBuilder, + RelOptTable.ToRelContext toRelContext, + boolean restructure) { + this.relBuilder = relBuilder; this.rexBuilder = rexBuilder; this.toRelContext = toRelContext; this.restructure = restructure; @@ -191,10 +204,10 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor { // REVIEW jvs 23-Mar-2005: How do we make sure that this // implementation stays in Java? Fennel can't handle // structured types. - return RelOptUtil.createProject( - flattened, - structuringExps, - root.getRowType().getFieldNames()); + return relBuilder.push(flattened) + .projectNamed(structuringExps, root.getRowType().getFieldNames(), + true) + .build(); } else { return flattened; } @@ -473,12 +486,10 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor { rel.getRowType().getFieldNames(), "", flattenedExpList); - RelNode newRel = - RelOptUtil.createProject( - getNewForOldRel(rel.getInput()), - flattenedExpList, - false); - setNewForOldRel(rel, newRel); + relBuilder.push(getNewForOldRel(rel.getInput())) + .projectNamed(Pair.left(flattenedExpList), Pair.right(flattenedExpList), + true); + setNewForOldRel(rel, relBuilder.build()); } public void rewriteRel(LogicalCalc rel) { @@ -660,8 +671,10 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor { flattenInputs(rel.getRowType().getFieldList(), rexBuilder.makeRangeReference(newRel), flattenedExpList); - newRel = - RelOptUtil.createProject(newRel, flattenedExpList, false); + newRel = relBuilder.push(newRel) + .projectNamed(Pair.left(flattenedExpList), + Pair.right(flattenedExpList), true) + .build(); } setNewForOldRel(rel, newRel); } @@ -828,7 +841,8 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor { @Override public RexNode visitSubQuery(RexSubQuery subQuery) { subQuery = (RexSubQuery) super.visitSubQuery(subQuery); RelStructuredTypeFlattener flattener = - new RelStructuredTypeFlattener(rexBuilder, toRelContext, restructure); + new RelStructuredTypeFlattener(relBuilder, rexBuilder, + toRelContext, restructure); RelNode rel = flattener.rewrite(subQuery.rel); return subQuery.clone(rel); } http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java index cc6d815..4a96172 100644 --- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java +++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java @@ -459,7 +459,8 @@ public class SqlToRelConverter { RelNode rootRel, boolean restructure) { RelStructuredTypeFlattener typeFlattener = - new RelStructuredTypeFlattener(rexBuilder, createToRelContext(), restructure); + new RelStructuredTypeFlattener(relBuilder, + rexBuilder, createToRelContext(), restructure); return typeFlattener.rewrite(rootRel); } @@ -1508,7 +1509,8 @@ public class SqlToRelConverter { final Blackboard seekBb = createBlackboard(seekScope, null, false); RelNode seekRel = convertQueryOrInList(seekBb, seek, targetDataType); - return RelOptUtil.createExistsPlan(seekRel, subQueryType, logic, notIn); + return RelOptUtil.createExistsPlan(seekRel, + subQueryType, logic, notIn, relBuilder); } private RelNode convertQueryOrInList( @@ -2087,14 +2089,13 @@ public class SqlToRelConverter { exprs.add(bb.convertExpression(node.e)); fieldNames.add(validator.deriveAlias(node.e, node.i)); } - final RelNode input = - RelOptUtil.createProject( - (null != bb.root) ? bb.root : LogicalValues.createOneRow(cluster), - exprs, fieldNames, true); + RelNode child = + (null != bb.root) ? bb.root : LogicalValues.createOneRow(cluster); + relBuilder.push(child).projectNamed(exprs, fieldNames, false); Uncollect uncollect = new Uncollect(cluster, cluster.traitSetOf(Convention.NONE), - input, operator.withOrdinality); + relBuilder.build(), operator.withOrdinality); bb.setRoot(uncollect, true); return; @@ -2773,10 +2774,9 @@ public class SqlToRelConverter { // Project the expressions required by agg and having. bb.setRoot( - RelOptUtil.createProject( - inputRel, - preExprs, - true), + relBuilder.push(inputRel) + .projectNamed(Pair.left(preExprs), Pair.right(preExprs), false) + .build(), false); bb.mapRootRelToFieldProjection.put(bb.root, r.groupExprProjection); @@ -3027,7 +3027,7 @@ public class SqlToRelConverter { } protected RelNode decorrelateQuery(RelNode rootRel) { - return RelDecorrelator.decorrelateQuery(rootRel); + return RelDecorrelator.decorrelateQuery(rootRel, relBuilder); } /** @@ -3190,11 +3190,10 @@ public class SqlToRelConverter { field.getName())); } - source = RelOptUtil.createProject(source, projects, true); - if (filters.size() > 0) { - source = RelOptUtil.createFilter(source, filters); - } - return source; + return relBuilder.push(source) + .projectNamed(Pair.left(projects), Pair.right(projects), false) + .filter(filters) + .build(); } private RelOptTable.ToRelContext createToRelContext() { @@ -3337,7 +3336,9 @@ public class SqlToRelConverter { } } - return RelOptUtil.createProject(source, sourceExps, fieldNames, true); + return relBuilder.push(source) + .projectNamed(sourceExps, fieldNames, false) + .build(); } /** Creates a blackboard for translating the expressions of generated columns @@ -3577,11 +3578,12 @@ public class SqlToRelConverter { Util.skip(project.getProjects(), nSourceFields)); } - RelNode massagedRel = - RelOptUtil.createProject(join, projects, null, true); + relBuilder.push(join) + .project(projects); - return LogicalTableModify.create(targetTable, catalogReader, massagedRel, - LogicalTableModify.Operation.MERGE, targetColumnNameList, null, false); + return LogicalTableModify.create(targetTable, catalogReader, + relBuilder.build(), LogicalTableModify.Operation.MERGE, + targetColumnNameList, null, false); } /** @@ -3777,13 +3779,10 @@ public class SqlToRelConverter { fieldNameList.add(SqlUtil.deriveAliasFromOrdinal(j)); } - RelNode projRel = - RelOptUtil.createProject( - LogicalValues.createOneRow(cluster), - selectList, - fieldNameList); + relBuilder.push(LogicalValues.createOneRow(cluster)) + .projectNamed(selectList, fieldNameList, true); - joinList.set(i, projRel); + joinList.set(i, relBuilder.build()); } } @@ -3845,9 +3844,9 @@ public class SqlToRelConverter { fieldNames = SqlValidatorUtil.uniquify(fieldNames, catalogReader.nameMatcher().isCaseSensitive()); - bb.setRoot( - RelOptUtil.createProject(bb.root, exprs, fieldNames), - false); + relBuilder.push(bb.root) + .projectNamed(exprs, fieldNames, true); + bb.setRoot(relBuilder.build(), false); assert bb.columnMonotonicities.isEmpty(); bb.columnMonotonicities.addAll(columnMonotonicityList); @@ -3960,12 +3959,9 @@ public class SqlToRelConverter { (null == tmpBb.root) ? LogicalValues.createOneRow(cluster) : tmpBb.root; - unionRels.add( - RelOptUtil.createProject( - in, - Pair.left(exps), - Pair.right(exps), - true)); + unionRels.add(relBuilder.push(in) + .project(Pair.left(exps), Pair.right(exps)) + .build()); } if (unionRels.size() == 0) { @@ -4096,27 +4092,25 @@ public class SqlToRelConverter { final RexNode joinCond; final int origLeftInputCount = root.getRowType().getFieldCount(); if (leftKeys != null) { - List<RexNode> newLeftInputExpr = Lists.newArrayList(); + List<RexNode> newLeftInputExprs = Lists.newArrayList(); for (int i = 0; i < origLeftInputCount; i++) { - newLeftInputExpr.add(rexBuilder.makeInputRef(root, i)); + newLeftInputExprs.add(rexBuilder.makeInputRef(root, i)); } final List<Integer> leftJoinKeys = Lists.newArrayList(); for (RexNode leftKey : leftKeys) { - int index = newLeftInputExpr.indexOf(leftKey); + int index = newLeftInputExprs.indexOf(leftKey); if (index < 0 || joinType == JoinRelType.LEFT) { - index = newLeftInputExpr.size(); - newLeftInputExpr.add(leftKey); + index = newLeftInputExprs.size(); + newLeftInputExprs.add(leftKey); } leftJoinKeys.add(index); } RelNode newLeftInput = - RelOptUtil.createProject( - root, - newLeftInputExpr, - null, - true); + relBuilder.push(root) + .project(newLeftInputExprs) + .build(); // maintain the group by mapping in the new LogicalProject if (mapRootRelToFieldProjection.containsKey(root)) { http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/main/java/org/apache/calcite/tools/Programs.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/tools/Programs.java b/core/src/main/java/org/apache/calcite/tools/Programs.java index edf4be5..a37313c 100644 --- a/core/src/main/java/org/apache/calcite/tools/Programs.java +++ b/core/src/main/java/org/apache/calcite/tools/Programs.java @@ -406,7 +406,9 @@ public class Programs { final CalciteConnectionConfig config = planner.getContext().unwrap(CalciteConnectionConfig.class); if (config != null && config.forceDecorrelate()) { - return RelDecorrelator.decorrelateQuery(rel); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(rel.getCluster(), null); + return RelDecorrelator.decorrelateQuery(rel, relBuilder); } return rel; } http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/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 680cded..e5fb2aa 100644 --- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java +++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java @@ -65,6 +65,7 @@ import org.apache.calcite.sql.validate.SqlValidatorUtil; import org.apache.calcite.util.Holder; import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.ImmutableIntList; +import org.apache.calcite.util.ImmutableNullableList; import org.apache.calcite.util.Litmus; import org.apache.calcite.util.NlsString; import org.apache.calcite.util.Pair; @@ -1070,6 +1071,51 @@ public class RelBuilder { return project(ImmutableList.copyOf(nodes)); } + /** Creates a {@link org.apache.calcite.rel.core.Project} of the given + * expressions and field names, and optionally optimizing. + * + * <p>If {@code fieldNames} is null, or if a particular entry in + * {@code fieldNames} is null, derives field names from the input + * expressions. + * + * <p>If {@code force} is false, + * and the input is a {@code Project}, + * and the expressions make the trivial projection ($0, $1, ...), + * modifies the input. + * + * @param nodes Expressions + * @param fieldNames Suggested field names, or null to generate + * @param force Whether to create a renaming Project if the + * projections are trivial + */ + public RelBuilder projectNamed(Iterable<? extends RexNode> nodes, + Iterable<String> fieldNames, boolean force) { + @SuppressWarnings("unchecked") final List<? extends RexNode> nodeList = + nodes instanceof List ? (List) nodes : ImmutableList.copyOf(nodes); + final List<String> fieldNameList = + fieldNames == null ? null + : fieldNames instanceof List ? (List<String>) fieldNames + : ImmutableNullableList.copyOf(fieldNames); + final RelNode input = peek(); + final RelDataType rowType = + RexUtil.createStructType(cluster.getTypeFactory(), nodeList, + fieldNameList, SqlValidatorUtil.F_SUGGESTER); + if (!force + && RexUtil.isIdentity(nodeList, input.getRowType())) { + if (input instanceof Project && fieldNames != null) { + // Rename columns of child projection if desired field names are given. + final Frame frame = stack.pop(); + final Project childProject = (Project) frame.rel; + final Project newInput = childProject.copy(childProject.getTraitSet(), + childProject.getInput(), childProject.getProjects(), rowType); + stack.push(new Frame(newInput, frame.fields)); + } + } else { + project(nodeList, rowType.getFieldNames(), force); + } + return this; + } + /** Ensures that the field names match those given. * * <p>If all fields have the same name, adds nothing; http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java b/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java index 337d3cf..a0a7028 100644 --- a/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java +++ b/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java @@ -23,16 +23,14 @@ import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelOptListener; import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.plan.RelOptRuleCall; -import org.apache.calcite.plan.RelOptUtil; import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.convert.ConverterImpl; import org.apache.calcite.rel.convert.ConverterRule; +import org.apache.calcite.rel.core.RelFactories; import org.apache.calcite.rel.logical.LogicalProject; import org.apache.calcite.rel.rules.ProjectRemoveRule; -import org.apache.calcite.rex.RexInputRef; - -import com.google.common.collect.ImmutableList; +import org.apache.calcite.tools.RelBuilder; import org.junit.Ignore; import org.junit.Test; @@ -229,12 +227,12 @@ public class VolcanoPlannerTest { new PhysLeafRel( cluster, "a"); - RexInputRef inputRef = RexInputRef.of(0, leafRel.getRowType()); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(leafRel.getCluster(), null); RelNode projectRel = - RelOptUtil.createProject( - leafRel, - ImmutableList.of(inputRef), - ImmutableList.of("this")); + relBuilder.push(leafRel) + .project(relBuilder.alias(relBuilder.field(0), "this")) + .build(); NoneSingleRel singleRel = new NoneSingleRel( cluster, http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/test/java/org/apache/calcite/test/MutableRelTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/MutableRelTest.java b/core/src/test/java/org/apache/calcite/test/MutableRelTest.java index 4c94693..f99d8c1 100644 --- a/core/src/test/java/org/apache/calcite/test/MutableRelTest.java +++ b/core/src/test/java/org/apache/calcite/test/MutableRelTest.java @@ -22,6 +22,7 @@ import org.apache.calcite.plan.hep.HepPlanner; import org.apache.calcite.plan.hep.HepProgram; import org.apache.calcite.plan.hep.HepProgramBuilder; import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.RelFactories; import org.apache.calcite.rel.mutable.MutableRel; import org.apache.calcite.rel.mutable.MutableRels; import org.apache.calcite.rel.rules.FilterJoinRule; @@ -32,6 +33,7 @@ import org.apache.calcite.rel.rules.ProjectToWindowRule; import org.apache.calcite.rel.rules.SemiJoinRule; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.sql2rel.RelDecorrelator; +import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.util.Litmus; import com.google.common.collect.ImmutableList; @@ -187,7 +189,9 @@ public class MutableRelTest { }; RelNode origRel = test.createTester().convertSqlToRel(sql).rel; if (decorrelate) { - origRel = RelDecorrelator.decorrelateQuery(origRel); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(origRel.getCluster(), null); + origRel = RelDecorrelator.decorrelateQuery(origRel, relBuilder); } if (rules != null) { final HepProgram hepProgram = http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java b/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java index 114463f..70203ce 100644 --- a/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java +++ b/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java @@ -17,6 +17,7 @@ package org.apache.calcite.test; import org.apache.calcite.plan.Context; +import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelOptPlanner; import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.plan.RelOptUtil; @@ -25,12 +26,14 @@ import org.apache.calcite.plan.hep.HepProgram; import org.apache.calcite.plan.hep.HepProgramBuilder; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.RelRoot; +import org.apache.calcite.rel.core.RelFactories; import org.apache.calcite.rel.metadata.ChainedRelMetadataProvider; import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider; import org.apache.calcite.rel.metadata.RelMetadataProvider; import org.apache.calcite.runtime.FlatLists; import org.apache.calcite.runtime.Hook; import org.apache.calcite.sql2rel.RelDecorrelator; +import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.util.Closer; import com.google.common.base.Function; @@ -145,7 +148,8 @@ abstract class RelOptTestBase extends SqlToRelTestBase { planner.registerMetadataProviders(list); RelMetadataProvider plannerChain = ChainedRelMetadataProvider.of(list); - relInitial.getCluster().setMetadataProvider(plannerChain); + final RelOptCluster cluster = relInitial.getCluster(); + cluster.setMetadataProvider(plannerChain); RelNode relBefore; if (preProgram == null) { @@ -168,7 +172,9 @@ abstract class RelOptTestBase extends SqlToRelTestBase { final String planMid = NL + RelOptUtil.toString(r); diffRepos.assertEquals("planMid", "${planMid}", planMid); SqlToRelTestBase.assertValid(r); - r = RelDecorrelator.decorrelateQuery(r); + final RelBuilder relBuilder = + RelFactories.LOGICAL_BUILDER.create(cluster, null); + r = RelDecorrelator.decorrelateQuery(r, relBuilder); } final String planAfter = NL + RelOptUtil.toString(r); if (unchanged) { http://git-wip-us.apache.org/repos/asf/calcite/blob/03ec2cfd/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml ---------------------------------------------------------------------- diff --git a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml index f5d30af..089fd56 100644 --- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml @@ -880,7 +880,7 @@ LogicalProject(NAME=[$0]) </TestCase> <TestCase name="testOrder"> <Resource name="sql"> - <![CDATA[select empno from emp order by empno]]> + <![CDATA[select empno from emp order by empno, empno desc]]> </Resource> <Resource name="plan"> <![CDATA[ @@ -1093,7 +1093,7 @@ LogicalProject(EMPNO=[$0], EXPR$1=[$1]) <TestCase name="testOrderBySameExpr"> <Resource name="sql"> <![CDATA[select empno from emp, dept -order by sal + empno desc, sal * empno, sal + empno]]> +order by sal + empno desc, sal * empno, sal + empno desc]]> </Resource> <Resource name="plan"> <![CDATA[ @@ -2022,15 +2022,15 @@ from dept]]> <![CDATA[ LogicalProject(NAME=[$1], EXPR$1=[CASE(=($2, 0), false, IS NOT NULL($6), true, <($3, $2), null, false)]) LogicalJoin(condition=[=($4, $5)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$0]) + LogicalProject(DEPTNO=[$0], NAME=[$1], $f0=[$2], $f1=[$3], DEPTNO0=[$0]) LogicalJoin(condition=[true], joinType=[inner]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) LogicalAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(EXPR$0=[$0], $f1=[true]) LogicalProject(EXPR$0=[CAST($7):INTEGER]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(EXPR$0=[$0], $f1=[true]) LogicalProject(EXPR$0=[CAST($7):INTEGER]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> @@ -2046,15 +2046,15 @@ from emp]]> <![CDATA[ LogicalProject(EMPNO=[$0], EXPR$1=[NOT(CASE(=($9, 0), false, IS NOT NULL($13), true, IS NULL($11), null, <($10, $9), null, false))]) LogicalJoin(condition=[=($11, $12)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$4], $f5=[$5], $f6=[$6], $f7=[$7], $f8=[$8], $f9=[$9], $f10=[$10], $f11=[$7]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f0=[$9], $f1=[$10], DEPTNO0=[$7]) LogicalJoin(condition=[true], joinType=[inner]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(EXPR$0=[$0], $f1=[true]) LogicalProject(EXPR$0=[CAST($0):INTEGER]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(EXPR$0=[$0], $f1=[true]) LogicalProject(EXPR$0=[CAST($0):INTEGER]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) ]]> @@ -2069,10 +2069,10 @@ LogicalProject(EMPNO=[$0], EXPR$1=[NOT(CASE(=($9, 0), false, IS NOT NULL($13), t LogicalProject(EMPNO=[$0]) LogicalFilter(condition=[NOT(AND(IS TRUE($11), IS NOT NULL($9)))]) LogicalJoin(condition=[=($9, $10)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$4], $f5=[$5], $f6=[$6], $f7=[$7], $f8=[$8], $f9=[$7]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$7]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(DEPTNO=[$0], $f1=[true]) LogicalProject(DEPTNO=[$0]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) ]]> @@ -2088,10 +2088,10 @@ from emp]]> <![CDATA[ LogicalProject(EMPNO=[$0], EXPR$1=[IS NOT TRUE($11)]) LogicalJoin(condition=[=($9, $10)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$4], $f5=[$5], $f6=[$6], $f7=[$7], $f8=[$8], $f9=[$7]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$7]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(DEPTNO=[$0], $f1=[true]) LogicalProject(DEPTNO=[$0]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) ]]> @@ -2134,10 +2134,10 @@ from emp]]> <![CDATA[ LogicalProject(EMPNO=[$0], EXPR$1=[CAST(NOT(AND(IS TRUE($11), IS NOT NULL($9)))):BOOLEAN]) LogicalJoin(condition=[=($9, $10)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$4], $f5=[$5], $f6=[$6], $f7=[$7], $f8=[$8], $f9=[$7]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$7]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(MGR=[$0], $f1=[true]) LogicalProject(MGR=[$3]) LogicalFilter(condition=[>($3, 5)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) @@ -2154,10 +2154,10 @@ from emp]]> <![CDATA[ LogicalProject(EMPNO=[$0], EXPR$1=[CAST(NOT(AND(IS TRUE($11), IS NOT NULL($9)))):BOOLEAN]) LogicalJoin(condition=[=($9, $10)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$4], $f5=[$5], $f6=[$6], $f7=[$7], $f8=[$8], $f9=[$7]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$7]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(MGR=[$0], $f1=[true]) LogicalProject(MGR=[$3]) LogicalFilter(condition=[IS NOT NULL($3)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) @@ -2175,10 +2175,10 @@ from emp]]> <![CDATA[ LogicalProject(EMPNO=[$0], EXPR$1=[CAST(NOT(AND(IS TRUE($11), IS NOT NULL($9)))):BOOLEAN]) LogicalJoin(condition=[=($9, $10)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$4], $f5=[$5], $f6=[$6], $f7=[$7], $f8=[$8], $f9=[$7]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$7]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(MGR=[$0], $f1=[true]) LogicalProject(MGR=[$3]) LogicalJoin(condition=[=($3, $9)], joinType=[inner]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) @@ -2199,15 +2199,15 @@ from emp]]> <![CDATA[ LogicalProject(EMPNO=[$0], EXPR$1=[NOT(CASE(=($9, 0), false, IS NOT NULL($13), true, IS NULL($11), null, <($10, $9), null, false))]) LogicalJoin(condition=[=($11, $12)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$4], $f5=[$5], $f6=[$6], $f7=[$7], $f8=[$8], $f9=[$9], $f10=[$10], $f11=[$7]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f0=[$9], $f1=[$10], DEPTNO0=[$7]) LogicalJoin(condition=[true], joinType=[inner]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(MGR=[$0], $f1=[true]) LogicalProject(MGR=[$3]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(MGR=[$0], $f1=[true]) LogicalProject(MGR=[$3]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> @@ -2268,7 +2268,7 @@ LogicalSort(sort0=[$1], dir0=[ASC]) <TestCase name="testGroupingSetsWithRollup"> <Resource name="sql"> <![CDATA[select deptno, ename, sum(sal) from emp -group by grouping sets (rollup(deptno), (ename, deptno)) +group by grouping sets ( rollup(deptno), (ename, deptno)) order by 2]]> </Resource> <Resource name="plan"> @@ -2283,7 +2283,7 @@ LogicalSort(sort0=[$1], dir0=[ASC]) <TestCase name="testGroupingSetsWithCube"> <Resource name="sql"> <![CDATA[select deptno, ename, sum(sal) from emp -group by grouping sets ((deptno), cube(ename, deptno)) +group by grouping sets ( (deptno), CUBE(ename, deptno)) order by 2]]> </Resource> <Resource name="plan"> @@ -2298,7 +2298,7 @@ LogicalSort(sort0=[$1], dir0=[ASC]) <TestCase name="testGroupingSetsWithRollupCube"> <Resource name="sql"> <![CDATA[select deptno, ename, sum(sal) from emp -group by grouping sets (cube(deptno), rollup(ename, deptno)) +group by grouping sets ( CUBE(deptno), ROLLUP(ename, deptno)) order by 2]]> </Resource> <Resource name="plan"> @@ -2310,7 +2310,6 @@ LogicalSort(sort0=[$1], dir0=[ASC]) ]]> </Resource> </TestCase> - <TestCase name="testDuplicateGroupingSets"> <Resource name="sql"> <![CDATA[select sum(sal) from emp @@ -2994,10 +2993,10 @@ WHERE n_name NOT IN LogicalProject(**=[$1]) LogicalFilter(condition=[NOT(AND(IS TRUE($4), IS NOT NULL($2)))]) LogicalJoin(condition=[=($2, $3)], joinType=[left]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$0]) + LogicalProject(N_NAME=[$0], **=[$1], N_NAME0=[$0]) LogicalTableScan(table=[[CATALOG, SALES, NATION]]) LogicalAggregate(group=[{0}], agg#0=[MIN($1)]) - LogicalProject($f0=[$0], $f1=[true]) + LogicalProject(EXPR$0=[$0], $f1=[true]) LogicalProject(EXPR$0=['']) LogicalTableScan(table=[[CATALOG, SALES, NATION]]) ]]> @@ -5081,7 +5080,7 @@ LogicalProject(EMPNO=[$0]) <![CDATA[ LogicalProject(EMPNO=[$0]) LogicalJoin(condition=[=($9, $10)], joinType=[inner]) - LogicalProject($f0=[$0], $f1=[$1], $f2=[$2], $f3=[$3], $f4=[$4], $f5=[$5], $f6=[$6], $f7=[$7], $f8=[$8], $f9=[CAST($0):BIGINT NOT NULL]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], EMPNO0=[CAST($0):BIGINT NOT NULL]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0}]) LogicalValues(tuples=[[{ 130 }, { 131 }, { 132 }, { 133 }, { 134 }]])
