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 }]])

Reply via email to