calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jh...@apache.org
Subject [5/9] incubator-calcite git commit: [CALCITE-88] Add collation as a trait and a kind of RelNode metadata
Date Sun, 08 Feb 2015 17:25:04 GMT
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
index e4e02f6..c21720f 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
@@ -52,20 +52,26 @@ public class LogicalTableFunctionScan extends TableFunctionScan {
    */
   public LogicalTableFunctionScan(
       RelOptCluster cluster,
+      RelTraitSet traitSet,
       List<RelNode> inputs,
       RexNode rexCall,
       Type elementType, RelDataType rowType,
       Set<RelColumnMapping> columnMappings) {
-    super(
-        cluster,
-        cluster.traitSetOf(Convention.NONE),
-        inputs,
-        rexCall,
-        elementType,
-        rowType,
+    super(cluster, traitSet, inputs, rexCall, elementType, rowType,
         columnMappings);
   }
 
+  @Deprecated // to be removed before 2.0
+  public LogicalTableFunctionScan(
+      RelOptCluster cluster,
+      List<RelNode> inputs,
+      RexNode rexCall,
+      Type elementType, RelDataType rowType,
+      Set<RelColumnMapping> columnMappings) {
+    this(cluster, cluster.traitSetOf(Convention.NONE), inputs, rexCall,
+        elementType, rowType, columnMappings);
+  }
+
   /**
    * Creates a LogicalTableFunctionScan by parsing serialized output.
    */
@@ -73,6 +79,18 @@ public class LogicalTableFunctionScan extends TableFunctionScan {
     super(input);
   }
 
+  /** Creates a LogicalTableFunctionScan. */
+  public static LogicalTableFunctionScan create(
+      RelOptCluster cluster,
+      List<RelNode> inputs,
+      RexNode rexCall,
+      Type elementType, RelDataType rowType,
+      Set<RelColumnMapping> columnMappings) {
+    final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE);
+    return new LogicalTableFunctionScan(cluster, traitSet, inputs, rexCall,
+        elementType, rowType, columnMappings);
+  }
+
   //~ Methods ----------------------------------------------------------------
 
   @Override public LogicalTableFunctionScan copy(

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableModify.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableModify.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableModify.java
index c1835ff..f8c76ab 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableModify.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableModify.java
@@ -33,38 +33,49 @@ import java.util.List;
 public final class LogicalTableModify extends TableModify {
   //~ Constructors -----------------------------------------------------------
 
-  public LogicalTableModify(
-      RelOptCluster cluster,
-      RelOptTable table,
-      Prepare.CatalogReader schema,
-      RelNode child,
-      Operation operation,
-      List<String> updateColumnList,
-      boolean flattened) {
-    super(
-        cluster,
+  /**
+   * Creates a LogicalTableModify.
+   *
+   * <p>Use {@link #create} unless you know what you're doing.
+   */
+  public LogicalTableModify(RelOptCluster cluster, RelTraitSet traitSet,
+      RelOptTable table, Prepare.CatalogReader schema, RelNode input,
+      Operation operation, List<String> updateColumnList, boolean flattened) {
+    super(cluster, traitSet, table, schema, input, operation, updateColumnList,
+        flattened);
+  }
+
+  @Deprecated // to be removed before 2.0
+  public LogicalTableModify(RelOptCluster cluster, RelOptTable table,
+      Prepare.CatalogReader schema, RelNode input, Operation operation,
+      List<String> updateColumnList, boolean flattened) {
+    this(cluster,
         cluster.traitSetOf(Convention.NONE),
         table,
         schema,
-        child,
+        input,
         operation,
         updateColumnList,
         flattened);
   }
 
+  /** Creates a LogicalTableModify. */
+  public static LogicalTableModify create(RelOptTable table,
+      Prepare.CatalogReader schema, RelNode input,
+      Operation operation, List<String> updateColumnList, boolean flattened) {
+    final RelOptCluster cluster = input.getCluster();
+    final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE);
+    return new LogicalTableModify(cluster, traitSet, table, schema, input,
+        operation, updateColumnList, flattened);
+  }
+
   //~ Methods ----------------------------------------------------------------
 
   @Override public LogicalTableModify copy(RelTraitSet traitSet,
       List<RelNode> inputs) {
     assert traitSet.containsIfApplicable(Convention.NONE);
-    return new LogicalTableModify(
-        getCluster(),
-        table,
-        catalogReader,
-        sole(inputs),
-        getOperation(),
-        getUpdateColumnList(),
-        isFlattened());
+    return new LogicalTableModify(getCluster(), traitSet, table, catalogReader,
+        sole(inputs), getOperation(), getUpdateColumnList(), isFlattened());
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java
index 5340fd0..10b777c 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableScan.java
@@ -58,16 +58,16 @@ public final class LogicalTableScan extends TableScan {
   /**
    * Creates a LogicalTableScan.
    *
-   * @param cluster Cluster
-   * @param table   Table
+   * <p>Use {@link #create} unless you know what you're doing.
    */
-  public LogicalTableScan(
-      RelOptCluster cluster,
+  public LogicalTableScan(RelOptCluster cluster, RelTraitSet traitSet,
       RelOptTable table) {
-    super(
-        cluster,
-        cluster.traitSetOf(Convention.NONE),
-        table);
+    super(cluster, traitSet, table);
+  }
+
+  @Deprecated // to be removed before 2.0
+  public LogicalTableScan(RelOptCluster cluster, RelOptTable table) {
+    this(cluster, cluster.traitSetOf(Convention.NONE), table);
   }
 
   /**
@@ -82,6 +82,13 @@ public final class LogicalTableScan extends TableScan {
     assert inputs.isEmpty();
     return this;
   }
+
+  /** Creates a LogicalTableScan. */
+  public static LogicalTableScan create(RelOptCluster cluster,
+      RelOptTable table) {
+    final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE);
+    return new LogicalTableScan(cluster, traitSet, table);
+  }
 }
 
 // End LogicalTableScan.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/logical/LogicalUnion.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalUnion.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalUnion.java
index 49dde4d..ab7f3bf 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalUnion.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalUnion.java
@@ -33,15 +33,22 @@ import java.util.List;
 public final class LogicalUnion extends Union {
   //~ Constructors -----------------------------------------------------------
 
-  public LogicalUnion(
-      RelOptCluster cluster,
+  /**
+   * Creates a LogicalUnion.
+   *
+   * <p>Use {@link #create} unless you know what you're doing.
+   */
+  public LogicalUnion(RelOptCluster cluster,
+      RelTraitSet traitSet,
       List<RelNode> inputs,
       boolean all) {
-    super(
-        cluster,
-        cluster.traitSetOf(Convention.NONE),
-        inputs,
-        all);
+    super(cluster, traitSet, inputs, all);
+  }
+
+  @Deprecated // to be removed before 2.0
+  public LogicalUnion(RelOptCluster cluster, List<RelNode> inputs,
+      boolean all) {
+    this(cluster, cluster.traitSetOf(Convention.NONE), inputs, all);
   }
 
   /**
@@ -51,15 +58,19 @@ public final class LogicalUnion extends Union {
     super(input);
   }
 
+  /** Creates a LogicalUnion. */
+  public static LogicalUnion create(List<RelNode> inputs, boolean all) {
+    final RelOptCluster cluster = inputs.get(0).getCluster();
+    final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE);
+    return new LogicalUnion(cluster, traitSet, inputs, all);
+  }
+
   //~ Methods ----------------------------------------------------------------
 
   public LogicalUnion copy(
       RelTraitSet traitSet, List<RelNode> inputs, boolean all) {
     assert traitSet.containsIfApplicable(Convention.NONE);
-    return new LogicalUnion(
-        getCluster(),
-        inputs,
-        all);
+    return new LogicalUnion(getCluster(), traitSet, inputs, all);
   }
 
   @Override public RelNode accept(RelShuttle shuttle) {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/logical/LogicalValues.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalValues.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalValues.java
index 5d80851..02ca053 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalValues.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalValues.java
@@ -19,14 +19,18 @@ package org.apache.calcite.rel.logical;
 import org.apache.calcite.plan.Convention;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelInput;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.RelShuttle;
 import org.apache.calcite.rel.core.Values;
+import org.apache.calcite.rel.metadata.RelMdCollation;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.sql.type.SqlTypeName;
 
+import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableList;
 
 import java.math.BigDecimal;
@@ -40,11 +44,9 @@ public class LogicalValues extends Values {
   //~ Constructors -----------------------------------------------------------
 
   /**
-   * Creates a new LogicalValues.
+   * Creates a LogicalValues.
    *
-   * <p>Note that tuples passed in become owned by this
-   * rel (without a deep copy), so caller must not modify them after this
-   * call, otherwise bad things will happen.
+   * <p>Use {@link #create} unless you know what you're doing.
    *
    * @param cluster Cluster that this relational expression belongs to
    * @param rowType Row type for tuples produced by this rel
@@ -54,9 +56,18 @@ public class LogicalValues extends Values {
    */
   public LogicalValues(
       RelOptCluster cluster,
+      RelTraitSet traitSet,
       RelDataType rowType,
       ImmutableList<ImmutableList<RexLiteral>> tuples) {
-    super(cluster, rowType, tuples, cluster.traitSetOf(Convention.NONE));
+    super(cluster, rowType, tuples, traitSet);
+  }
+
+  @Deprecated // to be removed before 2.0
+  public LogicalValues(
+      RelOptCluster cluster,
+      RelDataType rowType,
+      ImmutableList<ImmutableList<RexLiteral>> tuples) {
+    this(cluster, cluster.traitSetOf(Convention.NONE), rowType, tuples);
   }
 
   /**
@@ -66,19 +77,30 @@ public class LogicalValues extends Values {
     super(input);
   }
 
+  /** Creates a LogicalValues. */
+  public static LogicalValues create(RelOptCluster cluster,
+      final RelDataType rowType,
+      final ImmutableList<ImmutableList<RexLiteral>> tuples) {
+    final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE)
+        .replaceIf(RelCollationTraitDef.INSTANCE,
+            new Supplier<List<RelCollation>>() {
+              public List<RelCollation> get() {
+                return RelMdCollation.values(rowType, tuples);
+              }
+            });
+    return new LogicalValues(cluster, traitSet, rowType, tuples);
+  }
+
   @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
     assert traitSet.containsIfApplicable(Convention.NONE);
     assert inputs.isEmpty();
-    return new LogicalValues(
-        getCluster(),
-        rowType,
-        tuples);
+    return new LogicalValues(getCluster(), traitSet, rowType, tuples);
   }
 
   /** Creates a LogicalValues that outputs no rows of a given row type. */
   public static LogicalValues createEmpty(RelOptCluster cluster,
       RelDataType rowType) {
-    return new LogicalValues(cluster, rowType,
+    return create(cluster, rowType,
         ImmutableList.<ImmutableList<RexLiteral>>of());
   }
 
@@ -93,7 +115,7 @@ public class LogicalValues extends Values {
             ImmutableList.of(
                 cluster.getRexBuilder().makeExactLiteral(BigDecimal.ZERO,
                     rowType.getFieldList().get(0).getType())));
-    return new LogicalValues(cluster, rowType, tuples);
+    return create(cluster, rowType, tuples);
   }
 
   @Override public RelNode accept(RelShuttle shuttle) {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/metadata/BuiltInMetadata.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/BuiltInMetadata.java b/core/src/main/java/org/apache/calcite/rel/metadata/BuiltInMetadata.java
index 5aa668f..1ab70e1 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/BuiltInMetadata.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/BuiltInMetadata.java
@@ -18,11 +18,14 @@ package org.apache.calcite.rel.metadata;
 
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPredicateList;
+import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.util.ImmutableBitSet;
 
+import com.google.common.collect.ImmutableList;
+
 import java.util.Set;
 
 /**
@@ -85,6 +88,12 @@ public abstract class BuiltInMetadata {
     Boolean areColumnsUnique(ImmutableBitSet columns, boolean ignoreNulls);
   }
 
+  /** Metadata about which columns are sorted. */
+  public interface Collation extends Metadata {
+    /** Determines which columns are sorted. */
+    ImmutableList<RelCollation> collations();
+  }
+
   /** Metadata about the number of rows returned by a relational expression. */
   public interface RowCount extends Metadata {
     /**

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/metadata/DefaultRelMetadataProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/DefaultRelMetadataProvider.java b/core/src/main/java/org/apache/calcite/rel/metadata/DefaultRelMetadataProvider.java
index 33ad92f..8078af2 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/DefaultRelMetadataProvider.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/DefaultRelMetadataProvider.java
@@ -44,7 +44,8 @@ public class DefaultRelMetadataProvider extends ChainedRelMetadataProvider {
             RelMdDistinctRowCount.SOURCE,
             RelMdSelectivity.SOURCE,
             RelMdExplainVisibility.SOURCE,
-            RelMdPredicates.SOURCE));
+            RelMdPredicates.SOURCE,
+            RelMdCollation.SOURCE));
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
new file mode 100644
index 0000000..16168ca
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.rel.metadata;
+
+import org.apache.calcite.adapter.enumerable.EnumerableMergeJoin;
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.plan.hep.HepRelVertex;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.core.TableScan;
+import org.apache.calcite.rel.core.Values;
+import org.apache.calcite.rel.core.Window;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.ImmutableIntList;
+import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.Util;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * RelMdCollation supplies a default implementation of
+ * {@link org.apache.calcite.rel.metadata.RelMetadataQuery#collations}
+ * for the standard logical algebra.
+ */
+public class RelMdCollation {
+  public static final RelMetadataProvider SOURCE =
+      ReflectiveRelMetadataProvider.reflectiveSource(
+          BuiltInMethod.COLLATIONS.method, new RelMdCollation());
+
+  //~ Constructors -----------------------------------------------------------
+
+  private RelMdCollation() {}
+
+  //~ Methods ----------------------------------------------------------------
+
+  /** Fallback method to deduce collations for any relational expression not
+   * handled by a more specific method.
+   *
+   * <p>{@link org.apache.calcite.rel.core.Union},
+   * {@link org.apache.calcite.rel.core.Intersect},
+   * {@link org.apache.calcite.rel.core.Minus},
+   * {@link org.apache.calcite.rel.core.Join},
+   * {@link org.apache.calcite.rel.core.SemiJoin},
+   * {@link org.apache.calcite.rel.core.Correlate}
+   * do not in general return sorted results
+   * (but implementations using particular algorithms may).
+   *
+   * @param rel Relational expression
+   * @return Relational expression's collations
+   */
+  public ImmutableList<RelCollation> collations(RelNode rel) {
+    return ImmutableList.of();
+  }
+
+  public ImmutableList<RelCollation> collations(Window rel) {
+    return ImmutableList.copyOf(window(rel.getInput(), rel.groups));
+  }
+
+  public ImmutableList<RelCollation> collations(Filter rel) {
+    return RelMetadataQuery.collations(rel.getInput());
+  }
+
+  public ImmutableList<RelCollation> collations(TableScan scan) {
+    return ImmutableList.copyOf(table(scan.getTable()));
+  }
+
+  public ImmutableList<RelCollation> collations(EnumerableMergeJoin join) {
+    // In general a join is not sorted. But a merge join preserves the sort
+    // order of the left and right sides.
+    return ImmutableList.copyOf(
+        RelMdCollation.mergeJoin(join.getLeft(),
+            join.getRight(),
+            join.getLeftKeys(),
+            join.getRightKeys()));
+  }
+
+  public ImmutableList<RelCollation> collations(Sort sort) {
+    return ImmutableList.copyOf(
+        RelMdCollation.sort(sort.getCollation()));
+  }
+
+  public ImmutableList<RelCollation> collations(Project project) {
+    return ImmutableList.copyOf(
+        project(project.getInput(), project.getProjects()));
+  }
+
+  public ImmutableList<RelCollation> collations(Values values) {
+    return ImmutableList.copyOf(
+        values(values.getRowType(), values.getTuples()));
+  }
+
+  public ImmutableList<RelCollation> collations(HepRelVertex rel) {
+    return RelMetadataQuery.collations(rel.getCurrentRel());
+  }
+
+  // Helper methods
+
+  /** Helper method to determine a
+   * {@link org.apache.calcite.rel.core.TableScan}'s collation. */
+  public static List<RelCollation> table(RelOptTable table) {
+    return table.getCollationList();
+  }
+
+  /** Helper method to determine a
+   * {@link org.apache.calcite.rel.core.Sort}'s collation. */
+  public static List<RelCollation> sort(RelCollation collation) {
+    return ImmutableList.of(collation);
+  }
+
+  /** Helper method to determine a
+   * {@link org.apache.calcite.rel.core.Filter}'s collation. */
+  public static List<RelCollation> filter(RelNode input) {
+    return RelMetadataQuery.collations(input);
+  }
+
+  /** Helper method to determine a
+   * {@link org.apache.calcite.rel.core.Calc}'s collation. */
+  public static List<RelCollation> calc(RelNode input,
+      RexProgram program) {
+    return program.getCollations(RelMetadataQuery.collations(input));
+  }
+
+  /** Helper method to determine a {@link Project}'s collation. */
+  public static List<RelCollation> project(RelNode input,
+      List<? extends RexNode> projects) {
+    // TODO: also monotonic expressions
+    final SortedSet<RelCollation> collations = Sets.newTreeSet();
+    final List<RelCollation> inputCollations =
+        RelMetadataQuery.collations(input);
+    if (inputCollations == null || inputCollations.isEmpty()) {
+      return ImmutableList.of();
+    }
+    final Multimap<Integer, Integer> targets = LinkedListMultimap.create();
+    for (Ord<RexNode> project : Ord.zip(projects)) {
+      if (project.e instanceof RexInputRef) {
+        targets.put(((RexInputRef) project.e).getIndex(), project.i);
+      }
+    }
+    final List<RelFieldCollation> fieldCollations = Lists.newArrayList();
+  loop:
+    for (RelCollation ic : inputCollations) {
+      if (ic.getFieldCollations().isEmpty()) {
+        continue;
+      }
+      fieldCollations.clear();
+      for (RelFieldCollation ifc : ic.getFieldCollations()) {
+        final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
+        if (integers.isEmpty()) {
+          continue loop; // cannot do this collation
+        }
+        fieldCollations.add(ifc.copy(integers.iterator().next()));
+      }
+      assert !fieldCollations.isEmpty();
+      collations.add(RelCollations.of(fieldCollations));
+    }
+    return ImmutableList.copyOf(collations);
+  }
+
+  /** Helper method to determine a
+   * {@link org.apache.calcite.rel.core.Window}'s collation.
+   *
+   * <p>A Window projects the fields of its input first, followed by the output
+   * from each of its windows. Assuming (quite reasonably) that the
+   * implementation does not re-order its input rows, then any collations of its
+   * input are preserved. */
+  public static List<RelCollation> window(RelNode input,
+      ImmutableList<Window.Group> groups) {
+    return RelMetadataQuery.collations(input);
+  }
+
+  /** Helper method to determine a
+   * {@link org.apache.calcite.rel.core.Values}'s collation.
+   *
+   * <p>We actually under-report the collations. A Values with 0 or 1 rows - an
+   * edge case, but legitimate and very common - is ordered by every permutation
+   * of every subset of the columns.
+   *
+   * <p>So, our algorithm aims to:<ul>
+   *   <li>produce at most N collations (where N is the number of columns);
+   *   <li>make each collation as long as possible;
+   *   <li>do not repeat combinations already emitted -
+   *       if we've emitted {@code (a, b)} do not later emit {@code (b, a)};
+   *   <li>probe the actual values and make sure that each collation is
+   *      consistent with the data
+   * </ul>
+   *
+   * <p>So, for an empty Values with 4 columns, we would emit
+   * {@code (a, b, c, d), (b, c, d), (c, d), (d)}. */
+  public static List<RelCollation> values(RelDataType rowType,
+      ImmutableList<ImmutableList<RexLiteral>> tuples) {
+    final List<RelCollation> list = Lists.newArrayList();
+    final int n = rowType.getFieldCount();
+    final List<Pair<RelFieldCollation, Ordering<List<RexLiteral>>>> pairs =
+        Lists.newArrayList();
+  outer:
+    for (int i = 0; i < n; i++) {
+      pairs.clear();
+      for (int j = i; j < n; j++) {
+        final RelFieldCollation fieldCollation = new RelFieldCollation(j);
+        Ordering<List<RexLiteral>> comparator = comparator(fieldCollation);
+        Ordering<List<RexLiteral>> ordering;
+        if (pairs.isEmpty()) {
+          ordering = comparator;
+        } else {
+          ordering = Util.last(pairs).right.compound(comparator);
+        }
+        pairs.add(Pair.of(fieldCollation, ordering));
+        if (!ordering.isOrdered(tuples)) {
+          if (j == i) {
+            continue outer;
+          }
+          pairs.remove(pairs.size() - 1);
+        }
+      }
+      if (!pairs.isEmpty()) {
+        list.add(RelCollations.of(Pair.left(pairs)));
+      }
+    }
+    return list;
+  }
+
+  private static Ordering<List<RexLiteral>> comparator(
+      RelFieldCollation fieldCollation) {
+    final int nullComparison = fieldCollation.nullDirection.nullComparison;
+    final int x = fieldCollation.getFieldIndex();
+    switch (fieldCollation.direction) {
+    case ASCENDING:
+      return new Ordering<List<RexLiteral>>() {
+        public int compare(List<RexLiteral> o1, List<RexLiteral> o2) {
+          final Comparable c1 = o1.get(x).getValue();
+          final Comparable c2 = o2.get(x).getValue();
+          return RelFieldCollation.compare(c1, c2, nullComparison);
+        }
+      };
+    default:
+      return new Ordering<List<RexLiteral>>() {
+        public int compare(List<RexLiteral> o1, List<RexLiteral> o2) {
+          final Comparable c1 = o1.get(x).getValue();
+          final Comparable c2 = o2.get(x).getValue();
+          return RelFieldCollation.compare(c2, c1, -nullComparison);
+        }
+      };
+    }
+  }
+
+  /** Helper method to determine a {@link Join}'s collation assuming that it
+   * uses a merge-join algorithm.
+   *
+   * <p>If the inputs are sorted on other keys <em>in addition to</em> the join
+   * key, the result preserves those collations too. */
+  public static List<RelCollation> mergeJoin(RelNode left, RelNode right,
+      ImmutableIntList leftKeys, ImmutableIntList rightKeys) {
+    final ImmutableList.Builder<RelCollation> builder = ImmutableList.builder();
+
+    final ImmutableList<RelCollation> leftCollations =
+        RelMetadataQuery.collations(left);
+    assert RelCollations.contains(leftCollations, leftKeys)
+        : "cannot merge join: left input is not sorted on left keys";
+    builder.addAll(leftCollations);
+
+    final ImmutableList<RelCollation> rightCollations =
+        RelMetadataQuery.collations(right);
+    assert RelCollations.contains(rightCollations, rightKeys)
+        : "cannot merge join: right input is not sorted on right keys";
+    final int leftFieldCount = left.getRowType().getFieldCount();
+    for (RelCollation collation : rightCollations) {
+      builder.add(RelCollations.shift(collation, leftFieldCount));
+    }
+    return builder.build();
+  }
+}
+
+// End RelMdCollation.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
index c537ef1..b17864d 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
@@ -19,11 +19,13 @@ package org.apache.calcite.rel.metadata;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPredicateList;
 import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.util.ImmutableBitSet;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
 import java.util.Set;
@@ -277,6 +279,21 @@ public abstract class RelMetadataQuery {
 
   /**
    * Returns the
+   * {@link org.apache.calcite.rel.metadata.BuiltInMetadata.Collation#collations()}
+   * statistic.
+   *
+   * @param rel         the relational expression
+   * @return List of sorted column combinations, or
+   * null if not enough information is available to make that determination
+   */
+  public static ImmutableList<RelCollation> collations(RelNode rel) {
+    final BuiltInMetadata.Collation metadata =
+        rel.metadata(BuiltInMetadata.Collation.class);
+    return metadata.collations();
+  }
+
+  /**
+   * Returns the
    * {@link BuiltInMetadata.PopulationSize#getPopulationSize(org.apache.calcite.util.ImmutableBitSet)}
    * statistic.
    *
@@ -285,6 +302,7 @@ public abstract class RelMetadataQuery {
    *                 the row count will be determined
    * @return distinct row count for the given groupKey, or null if no reliable
    * estimate can be determined
+   *
    */
   public static Double getPopulationSize(RelNode rel,
       ImmutableBitSet groupKey) {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java
index d661727..3afe7cc 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java
@@ -154,9 +154,8 @@ public final class AggregateExpandDistinctAggregatesRule extends RelOptRule {
       rel = null;
     } else {
       rel =
-          new LogicalAggregate(aggregate.getCluster(), aggregate.getInput(),
-              aggregate.indicator, groupSet, aggregate.getGroupSets(),
-              newAggCallList);
+          LogicalAggregate.create(aggregate.getInput(), aggregate.indicator,
+              groupSet, aggregate.getGroupSets(), newAggCallList);
     }
 
     // For each set of operands, find and rewrite all calls which have that

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectPullUpConstantsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectPullUpConstantsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectPullUpConstantsRule.java
index 9ad2f2f..c7667a6 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectPullUpConstantsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectPullUpConstantsRule.java
@@ -82,7 +82,7 @@ public class AggregateProjectPullUpConstantsRule extends RelOptRule {
   // implement RelOptRule
   public void onMatch(RelOptRuleCall call) {
     LogicalAggregate aggregate = call.rel(0);
-    LogicalProject child = call.rel(1);
+    LogicalProject input = call.rel(1);
 
     final int groupCount = aggregate.getGroupCount();
     if (groupCount == 1) {
@@ -92,11 +92,13 @@ public class AggregateProjectPullUpConstantsRule extends RelOptRule {
     }
 
     final RexProgram program =
-      RexProgram.create(child.getInput().getRowType(),
-        child.getProjects(), null, child.getRowType(),
-        child.getCluster().getRexBuilder());
+      RexProgram.create(input.getInput().getRowType(),
+          input.getProjects(),
+          null,
+          input.getRowType(),
+          input.getCluster().getRexBuilder());
 
-    final RelDataType childRowType = child.getRowType();
+    final RelDataType childRowType = input.getRowType();
     IntList constantList = new IntList();
     Map<Integer, RexNode> constants = new HashMap<Integer, RexNode>();
     for (int i : aggregate.getGroupSet()) {
@@ -134,11 +136,11 @@ public class AggregateProjectPullUpConstantsRule extends RelOptRule {
           new ArrayList<AggregateCall>();
       for (AggregateCall aggCall : aggregate.getAggCallList()) {
         newAggCalls.add(
-            aggCall.adaptTo(child, aggCall.getArgList(), groupCount,
+            aggCall.adaptTo(input, aggCall.getArgList(), groupCount,
                 newGroupCount));
       }
       newAggregate =
-          new LogicalAggregate(aggregate.getCluster(), child, false,
+          LogicalAggregate.create(input, false,
               ImmutableBitSet.range(newGroupCount), null, newAggCalls);
     } else {
       // Create the mapping from old field positions to new field
@@ -162,7 +164,7 @@ public class AggregateProjectPullUpConstantsRule extends RelOptRule {
       }
 
       // Create a projection to permute fields into these positions.
-      final RelNode project = createProjection(mapping, child);
+      final RelNode project = createProjection(mapping, input);
 
       // Adjust aggregate calls for new field positions.
       final List<AggregateCall> newAggCalls =
@@ -180,7 +182,7 @@ public class AggregateProjectPullUpConstantsRule extends RelOptRule {
 
       // Aggregate on projection.
       newAggregate =
-          new LogicalAggregate(aggregate.getCluster(), project, false,
+          LogicalAggregate.create(project, false,
               ImmutableBitSet.range(newGroupCount), null, newAggCalls);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java
index 6af92cc..ead7cd5 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java
@@ -543,17 +543,17 @@ public class AggregateReduceFunctionsRule extends RelOptRule {
    * into Aggregate and subclasses - but it's only needed for some
    * subclasses.
    *
-   * @param oldAggRel LogicalAggregate to clone.
-   * @param inputRel  Input relational expression
+   * @param oldAggregate LogicalAggregate to clone.
+   * @param input  Input relational expression
    * @param newCalls  New list of AggregateCalls
    * @return shallow clone with new list of AggregateCalls.
    */
   protected Aggregate newAggregateRel(
-      Aggregate oldAggRel,
-      RelNode inputRel,
+      Aggregate oldAggregate,
+      RelNode input,
       List<AggregateCall> newCalls) {
-    return new LogicalAggregate(oldAggRel.getCluster(), inputRel,
-        oldAggRel.indicator, oldAggRel.getGroupSet(), oldAggRel.getGroupSets(),
+    return LogicalAggregate.create(input, oldAggregate.indicator,
+        oldAggregate.getGroupSet(), oldAggregate.getGroupSets(),
         newCalls);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java
index 1005f8a..c1b5a28 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java
@@ -95,14 +95,10 @@ public class AggregateUnionAggregateRule extends RelOptRule {
       return;
     }
 
-    LogicalUnion newUnion =
-        new LogicalUnion(
-            union.getCluster(),
-            unionInputs,
-            true);
+    LogicalUnion newUnion = LogicalUnion.create(unionInputs, true);
 
     LogicalAggregate newAggRel =
-        new LogicalAggregate(topAggRel.getCluster(), newUnion, false,
+        LogicalAggregate.create(newUnion, false,
             topAggRel.getGroupSet(), null, topAggRel.getAggCallList());
 
     call.transformTo(newAggRel);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java
index dfb0932..eb72876 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java
@@ -116,23 +116,23 @@ public class AggregateUnionTransposeRule extends RelOptRule {
       } else {
         anyTransformed = true;
         newUnionInputs.add(
-            new LogicalAggregate(cluster, input, false, aggRel.getGroupSet(),
+            LogicalAggregate.create(input, false, aggRel.getGroupSet(),
                 null, aggRel.getAggCallList()));
       }
     }
 
     if (!anyTransformed) {
-      // none of the children could benefit from the pushdown,
+      // none of the children could benefit from the push-down,
       // so bail out (preventing the infinite loop to which most
       // planners would succumb)
       return;
     }
 
-    // create a new union whose children are the aggs created above
-    LogicalUnion newUnion = new LogicalUnion(cluster, newUnionInputs, true);
+    // create a new union whose children are the aggregates created above
+    LogicalUnion newUnion = LogicalUnion.create(newUnionInputs, true);
 
     LogicalAggregate newTopAggRel =
-        new LogicalAggregate(cluster, newUnion, aggRel.indicator,
+        LogicalAggregate.create(newUnion, aggRel.indicator,
             aggRel.getGroupSet(), aggRel.getGroupSets(), transformedAggCalls);
 
     call.transformTo(newTopAggRel);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java b/core/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java
index 989e1fc..a8810d8 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/CalcRelSplitter.java
@@ -19,7 +19,6 @@ package org.apache.calcite.rel.rules;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.Calc;
 import org.apache.calcite.rel.logical.LogicalCalc;
@@ -774,12 +773,7 @@ public abstract class CalcRelSplitter {
         RelTraitSet traits,
         RelNode child,
         RexProgram program) {
-      return new LogicalCalc(
-          cluster,
-          traits,
-          child,
-          program,
-          Collections.<RelCollation>emptyList());
+      return LogicalCalc.create(child, program);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/FilterCalcMergeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/FilterCalcMergeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/FilterCalcMergeRule.java
index fdc8415..7f5191b 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/FilterCalcMergeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterCalcMergeRule.java
@@ -18,7 +18,6 @@ package org.apache.calcite.rel.rules;
 
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
-import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.core.Filter;
 import org.apache.calcite.rel.logical.LogicalCalc;
 import org.apache.calcite.rel.logical.LogicalFilter;
@@ -26,8 +25,6 @@ import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexProgram;
 import org.apache.calcite.rex.RexProgramBuilder;
 
-import java.util.Collections;
-
 /**
  * Planner rule that merges a
  * {@link org.apache.calcite.rel.logical.LogicalFilter} and a
@@ -83,12 +80,7 @@ public class FilterCalcMergeRule extends RelOptRule {
             bottomProgram,
             rexBuilder);
     final LogicalCalc newCalc =
-        new LogicalCalc(
-            calc.getCluster(),
-            calc.getTraitSet(),
-            calc.getInput(),
-            mergedProgram,
-            Collections.<RelCollation>emptyList());
+        LogicalCalc.create(calc.getInput(), mergedProgram);
     call.transformTo(newCalc);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java b/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
index bb0b8cc..fdfb359 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
@@ -16,7 +16,6 @@
  */
 package org.apache.calcite.rel.rules;
 
-import org.apache.calcite.plan.Convention;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.plan.RelOptRuleOperand;
@@ -228,7 +227,7 @@ public abstract class FilterJoinRule extends RelOptRule {
 
     RelNode newJoinRel =
         join.copy(
-            join.getCluster().traitSetOf(Convention.NONE),
+            join.getTraitSet(),
             joinFilter,
             leftRel,
             rightRel,

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/FilterTableFunctionTransposeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/FilterTableFunctionTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/FilterTableFunctionTransposeRule.java
index 24f6a04..3f517ab 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/FilterTableFunctionTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterTableFunctionTransposeRule.java
@@ -104,16 +104,13 @@ public class FilterTableFunctionTransposeRule extends RelOptRule {
                   funcInput.getRowType().getFieldList(),
                   adjustments));
       newFuncInputs.add(
-          new LogicalFilter(cluster, funcInput, newCondition));
+          LogicalFilter.create(funcInput, newCondition));
     }
 
     // create a new UDX whose children are the filters created above
     LogicalTableFunctionScan newFuncRel =
-        new LogicalTableFunctionScan(
-            cluster,
-            newFuncInputs,
-            funcRel.getCall(),
-            funcRel.getElementType(), funcRel.getRowType(),
+        LogicalTableFunctionScan.create(cluster, newFuncInputs,
+            funcRel.getCall(), funcRel.getElementType(), funcRel.getRowType(),
             columnMappings);
     call.transformTo(newFuncRel);
   }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/FilterToCalcRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/FilterToCalcRule.java b/core/src/main/java/org/apache/calcite/rel/rules/FilterToCalcRule.java
index 68044bf..2e7feaf 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/FilterToCalcRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterToCalcRule.java
@@ -18,7 +18,6 @@ package org.apache.calcite.rel.rules;
 
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
-import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.logical.LogicalCalc;
 import org.apache.calcite.rel.logical.LogicalFilter;
@@ -27,10 +26,8 @@ import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexProgram;
 import org.apache.calcite.rex.RexProgramBuilder;
 
-import com.google.common.collect.ImmutableList;
-
 /**
- * Planner rule which converts a
+ * Planner rule that converts a
  * {@link org.apache.calcite.rel.logical.LogicalFilter} to a
  * {@link org.apache.calcite.rel.logical.LogicalCalc}.
  *
@@ -69,13 +66,7 @@ public class FilterToCalcRule extends RelOptRule {
     programBuilder.addCondition(filter.getCondition());
     final RexProgram program = programBuilder.getProgram();
 
-    final LogicalCalc calc =
-        new LogicalCalc(
-            filter.getCluster(),
-            filter.getTraitSet(),
-            rel,
-            program,
-            ImmutableList.<RelCollation>of());
+    final LogicalCalc calc = LogicalCalc.create(rel, program);
     call.transformTo(calc);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/JoinToCorrelateRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/JoinToCorrelateRule.java b/core/src/main/java/org/apache/calcite/rel/rules/JoinToCorrelateRule.java
index e520f9d..5e71048 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/JoinToCorrelateRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/JoinToCorrelateRule.java
@@ -123,9 +123,7 @@ public class JoinToCorrelateRule extends RelOptRule {
     final RelNode filteredRight =
         RelOptUtil.createFilter(right, joinCondition, filterFactory);
     RelNode newRel =
-        new LogicalCorrelate(
-            join.getCluster(),
-            left,
+        LogicalCorrelate.create(left,
             filteredRight,
             correlationId,
             requiredColumns.build(),

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/ProjectCalcMergeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ProjectCalcMergeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ProjectCalcMergeRule.java
index f2c832a..9ecd044 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectCalcMergeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectCalcMergeRule.java
@@ -19,7 +19,6 @@ package org.apache.calcite.rel.rules;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
-import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.logical.LogicalCalc;
 import org.apache.calcite.rel.logical.LogicalProject;
 import org.apache.calcite.rex.RexBuilder;
@@ -29,8 +28,6 @@ import org.apache.calcite.rex.RexProgram;
 import org.apache.calcite.rex.RexProgramBuilder;
 import org.apache.calcite.util.Pair;
 
-import java.util.Collections;
-
 /**
  * Planner rule which merges a
  * {@link org.apache.calcite.rel.logical.LogicalProject} and a
@@ -78,13 +75,7 @@ public class ProjectCalcMergeRule extends RelOptRule {
             project.getRowType(),
             cluster.getRexBuilder());
     if (RexOver.containsOver(program)) {
-      LogicalCalc projectAsCalc =
-          new LogicalCalc(
-              cluster,
-              project.getTraitSet(),
-              calc,
-              program,
-              Collections.<RelCollation>emptyList());
+      LogicalCalc projectAsCalc = LogicalCalc.create(calc, program);
       call.transformTo(projectAsCalc);
       return;
     }
@@ -108,12 +99,7 @@ public class ProjectCalcMergeRule extends RelOptRule {
             bottomProgram,
             rexBuilder);
     final LogicalCalc newCalc =
-        new LogicalCalc(
-            cluster,
-            project.getTraitSet(),
-            calc.getInput(),
-            mergedProgram,
-            Collections.<RelCollation>emptyList());
+        LogicalCalc.create(calc.getInput(), mergedProgram);
     call.transformTo(newCalc);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java
index 2bc5d59..3631c31 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectRemoveRule.java
@@ -59,8 +59,7 @@ public class ProjectRemoveRule extends RelOptRule {
 
   public static final ProjectRemoveRule INSTANCE = new ProjectRemoveRule(false);
 
-  /** @deprecated Remove before
-   * {@link org.apache.calcite.util.Bug#upgrade Calcite-1.1}. */
+  @Deprecated // to be removed before 1.1
   public static final ProjectRemoveRule NAME_CALC_INSTANCE =
       new ProjectRemoveRule(true);
 
@@ -110,10 +109,8 @@ public class ProjectRemoveRule extends RelOptRule {
   /**
    * Returns the child of a project if the project is trivial
    * otherwise the project itself. If useNamesInIdentityProjCalc is true
-   * then trivial comparison uses both names and types.
-   *
-   * @deprecated Remove before
-   * {@link org.apache.calcite.util.Bug#upgrade Calcite-1.1}. */
+   * then trivial comparison uses both names and types. */
+  @Deprecated // to be removed before 1.1
   public static RelNode strip(Project project,
       boolean useNamesInIdentityProjCalc) {
     return isTrivial(project, useNamesInIdentityProjCalc)
@@ -124,8 +121,7 @@ public class ProjectRemoveRule extends RelOptRule {
     return isTrivial(project, false);
   }
 
-  /** @deprecated Remove before
-   * {@link org.apache.calcite.util.Bug#upgrade Calcite-1.1}. */
+  @Deprecated // to be removed before 1.1
   public static boolean isTrivial(Project project,
     boolean useNamesInIdentityProjCalc) {
     RelNode child = project.getInput();
@@ -144,8 +140,7 @@ public class ProjectRemoveRule extends RelOptRule {
         && RexUtil.containIdentity(exps, childRowType, false);
   }
 
-  /** @deprecated Remove before
-   * {@link org.apache.calcite.util.Bug#upgrade Calcite-1.1}. */
+  @Deprecated // to be removed before 1.1
   public static boolean isIdentity(List<? extends RexNode> exps,
       RelDataType rowType, RelDataType childRowType) {
     return childRowType.getFieldCount() == exps.size()

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/ProjectToCalcRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ProjectToCalcRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ProjectToCalcRule.java
index 6233fc1..b6f05c9 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectToCalcRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectToCalcRule.java
@@ -18,14 +18,11 @@ package org.apache.calcite.rel.rules;
 
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
-import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.logical.LogicalCalc;
 import org.apache.calcite.rel.logical.LogicalProject;
 import org.apache.calcite.rex.RexProgram;
 
-import com.google.common.collect.ImmutableList;
-
 /**
  * Rule to convert a
  * {@link org.apache.calcite.rel.logical.LogicalProject} to a
@@ -55,21 +52,15 @@ public class ProjectToCalcRule extends RelOptRule {
 
   public void onMatch(RelOptRuleCall call) {
     final LogicalProject project = call.rel(0);
-    final RelNode child = project.getInput();
+    final RelNode input = project.getInput();
     final RexProgram program =
         RexProgram.create(
-            child.getRowType(),
+            input.getRowType(),
             project.getProjects(),
             null,
             project.getRowType(),
             project.getCluster().getRexBuilder());
-    final LogicalCalc calc =
-        new LogicalCalc(
-            project.getCluster(),
-            project.getTraitSet(),
-            child,
-            program,
-            ImmutableList.<RelCollation>of());
+    final LogicalCalc calc = LogicalCalc.create(input, program);
     call.transformTo(calc);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java
index 685b925..3719253 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java
@@ -22,7 +22,6 @@ import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.plan.RelOptRuleOperand;
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.plan.RelTraitSet;
-import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.Calc;
 import org.apache.calcite.rel.core.Project;
@@ -42,7 +41,6 @@ import org.apache.calcite.util.Util;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 import java.util.Collections;
@@ -112,22 +110,16 @@ public abstract class ProjectToWindowRule extends RelOptRule {
         @Override public void onMatch(RelOptRuleCall call) {
           Project project = call.rel(0);
           assert RexOver.containsOver(project.getProjects(), null);
-          final RelNode child = project.getInput();
+          final RelNode input = project.getInput();
           final RexProgram program =
               RexProgram.create(
-                  child.getRowType(),
+                  input.getRowType(),
                   project.getProjects(),
                   null,
                   project.getRowType(),
                   project.getCluster().getRexBuilder());
           // temporary LogicalCalc, never registered
-          final LogicalCalc calc =
-              new LogicalCalc(
-                  project.getCluster(),
-                  project.getTraitSet(),
-                  child,
-                  program,
-                  ImmutableList.<RelCollation>of());
+          final LogicalCalc calc = LogicalCalc.create(input, program);
           CalcRelSplitter transform = new WindowedAggRelSplitter(calc) {
             @Override protected RelNode handle(RelNode rel) {
               if (rel instanceof LogicalCalc) {
@@ -135,9 +127,7 @@ public abstract class ProjectToWindowRule extends RelOptRule {
                 final RexProgram program = calc.getProgram();
                 rel = calc.getInput();
                 if (program.getCondition() != null) {
-                  rel = new LogicalFilter(
-                      calc.getCluster(),
-                      rel,
+                  rel = LogicalFilter.create(rel,
                       program.expandLocalRef(
                           program.getCondition()));
                 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java b/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java
index 008f9aa..2f4cada 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java
@@ -93,11 +93,7 @@ public abstract class PruneEmptyRules {
                     true);
             break;
           default:
-            newRel =
-                new LogicalUnion(
-                    union.getCluster(),
-                    newChildRels,
-                    union.all);
+            newRel = LogicalUnion.create(newChildRels, union.all);
             break;
           }
           call.transformTo(newRel);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java
index a3ecf19..143620d 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java
@@ -20,7 +20,6 @@ import org.apache.calcite.linq4j.Ord;
 import org.apache.calcite.plan.Convention;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
-import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.logical.LogicalCalc;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeSystem;
@@ -44,7 +43,6 @@ import com.google.common.collect.ImmutableList;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -110,13 +108,7 @@ public class ReduceDecimalsRule extends RelOptRule {
             true);
 
     final RexProgram newProgram = programBuilder.getProgram();
-    LogicalCalc newCalc =
-        new LogicalCalc(
-            calc.getCluster(),
-            calc.getTraitSet(),
-            calc.getInput(),
-            newProgram,
-            Collections.<RelCollation>emptyList());
+    LogicalCalc newCalc = LogicalCalc.create(calc.getInput(), newProgram);
     call.transformTo(newCalc);
   }
 
@@ -1218,10 +1210,9 @@ public class ReduceDecimalsRule extends RelOptRule {
     public abstract RelDataType getArgType(RexCall call, int ordinal);
 
     public RexNode expand(RexCall call) {
-      List<RexNode> operands = call.operands;
       ImmutableList.Builder<RexNode> opBuilder = ImmutableList.builder();
 
-      for (Ord<RexNode> operand : Ord.zip(operands)) {
+      for (Ord<RexNode> operand : Ord.zip(call.operands)) {
         RelDataType targetType = getArgType(call, operand.i);
         if (SqlTypeUtil.isDecimal(operand.e.getType())) {
           opBuilder.add(ensureType(targetType, operand.e, true));

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
index d1bcaf2..7e54253 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
@@ -195,11 +195,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
               Lists.newArrayList(project.getProjects());
           if (reduceExpressions(project, expList, predicates)) {
             call.transformTo(
-                new LogicalProject(
-                    project.getCluster(),
-                    project.getTraitSet(),
-                    project.getInput(),
-                    expList,
+                LogicalProject.create(project.getInput(), expList,
                     project.getRowType()));
 
             // New plan is absolutely better than old plan.
@@ -303,12 +299,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
                   program.getOutputRowType().getFieldNames().get(k++));
             }
             call.transformTo(
-                new LogicalCalc(
-                    calc.getCluster(),
-                    calc.getTraitSet(),
-                    calc.getInput(),
-                    builder.getProgram(),
-                    calc.getCollationList()));
+                LogicalCalc.create(calc.getInput(), builder.getProgram()));
 
             // New plan is absolutely better than old plan.
             call.getPlanner().setImportance(calc, 0.0);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/SortProjectTransposeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/SortProjectTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/SortProjectTransposeRule.java
index 60cfc53..2240c38 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/SortProjectTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/SortProjectTransposeRule.java
@@ -21,6 +21,7 @@ import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelFieldCollation;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.Sort;
@@ -79,7 +80,7 @@ public class SortProjectTransposeRule extends RelOptRule {
       }
     }
     final RelCollation newCollation =
-        cluster.traitSetOf().canonize(
+        cluster.traitSet().canonize(
             RexUtil.apply(map, sort.getCollation()));
     final Sort newSort =
         sort.copy(
@@ -95,10 +96,15 @@ public class SortProjectTransposeRule extends RelOptRule {
     // Not only is newProject equivalent to sort;
     // newSort is equivalent to project's input
     // (but only if the sort is not also applying an offset/limit).
-    Map<RelNode, RelNode> equiv =
-        sort.offset == null && sort.fetch == null
-            ? ImmutableMap.<RelNode, RelNode>of(newSort, project.getInput())
-            : ImmutableMap.<RelNode, RelNode>of();
+    Map<RelNode, RelNode> equiv;
+    if (sort.offset == null
+        && sort.fetch == null
+        && cluster.getPlanner().getRelTraitDefs()
+            .contains(RelCollationTraitDef.INSTANCE)) {
+      equiv = ImmutableMap.of((RelNode) newSort, project.getInput());
+    } else {
+      equiv = ImmutableMap.of();
+    }
     call.transformTo(newProject, equiv);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java
index f772777..bda281c 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java
@@ -87,12 +87,7 @@ public class UnionMergeRule extends RelOptRule {
         == bottomUnion.getInputs().size()
         + topUnion.getInputs().size()
         - 1;
-    LogicalUnion newUnion =
-        new LogicalUnion(
-            topUnion.getCluster(),
-            unionInputs,
-            true);
-
+    LogicalUnion newUnion = LogicalUnion.create(unionInputs, true);
     call.transformTo(newUnion);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/UnionToDistinctRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/UnionToDistinctRule.java b/core/src/main/java/org/apache/calcite/rel/rules/UnionToDistinctRule.java
index 39a6d92..c688170 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/UnionToDistinctRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/UnionToDistinctRule.java
@@ -49,11 +49,7 @@ public class UnionToDistinctRule extends RelOptRule {
     if (union.all) {
       return; // nothing to do
     }
-    LogicalUnion unionAll =
-        new LogicalUnion(
-            union.getCluster(),
-            union.getInputs(),
-            true);
+    LogicalUnion unionAll = LogicalUnion.create(union.getInputs(), true);
     call.transformTo(RelOptUtil.createDistinctRel(unionAll));
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rel/rules/ValuesReduceRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ValuesReduceRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ValuesReduceRule.java
index 18e0f92..d1f205d 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ValuesReduceRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ValuesReduceRule.java
@@ -221,7 +221,7 @@ public abstract class ValuesReduceRule extends RelOptRule {
         rowType = values.getRowType();
       }
       final RelNode newRel =
-          new LogicalValues(values.getCluster(), rowType,
+          LogicalValues.create(values.getCluster(), rowType,
               tuplesBuilder.build());
       call.transformTo(newRel);
     } else {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rex/RexNode.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexNode.java b/core/src/main/java/org/apache/calcite/rex/RexNode.java
index 897c06c..0922116 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexNode.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexNode.java
@@ -86,7 +86,7 @@ public abstract class RexNode {
    * Accepts a visitor, dispatching to the right overloaded
    * {@link RexVisitor#visitInputRef visitXxx} method.
    *
-   * <p>Also see {@link RexProgram#apply(RexVisitor, java.util.List, RexNode)},
+   * <p>Also see {@link RexUtil#apply(RexVisitor, java.util.List, RexNode)},
    * which applies a visitor to several expressions simultaneously.
    */
   public abstract <R> R accept(RexVisitor<R> visitor);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rex/RexOver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexOver.java b/core/src/main/java/org/apache/calcite/rex/RexOver.java
index babfacc..3b45f36 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexOver.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexOver.java
@@ -107,7 +107,7 @@ public class RexOver extends RexCall {
    */
   public static boolean containsOver(RexProgram program) {
     try {
-      RexProgram.apply(FINDER, program.getExprList(), null);
+      RexUtil.apply(FINDER, program.getExprList(), null);
       return false;
     } catch (OverFound e) {
       Util.swallow(e, null);
@@ -120,7 +120,7 @@ public class RexOver extends RexCall {
    */
   public static boolean containsOver(List<RexNode> exprs, RexNode condition) {
     try {
-      RexProgram.apply(FINDER, exprs, condition);
+      RexUtil.apply(FINDER, exprs, condition);
       return false;
     } catch (OverFound e) {
       Util.swallow(e, null);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rex/RexProgram.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexProgram.java b/core/src/main/java/org/apache/calcite/rex/RexProgram.java
index 03f7540..caef1de 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexProgram.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexProgram.java
@@ -18,7 +18,7 @@ package org.apache.calcite.rex;
 
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationImpl;
+import org.apache.calcite.rel.RelCollations;
 import org.apache.calcite.rel.RelFieldCollation;
 import org.apache.calcite.rel.RelWriter;
 import org.apache.calcite.rel.externalize.RelWriterImpl;
@@ -596,7 +596,7 @@ public class RexProgram {
 
       // Success -- all of the source fields of this key are mapped
       // to the output.
-      outputCollations.add(RelCollationImpl.of(fieldCollations));
+      outputCollations.add(RelCollations.of(fieldCollations));
     }
   }
 
@@ -670,7 +670,7 @@ public class RexProgram {
     }
     refCounts = new int[exprs.size()];
     ReferenceCounter refCounter = new ReferenceCounter();
-    apply(refCounter, exprs, null);
+    RexUtil.apply(refCounter, exprs, null);
     if (condition != null) {
       refCounter.visitLocalRef(condition);
     }
@@ -681,26 +681,6 @@ public class RexProgram {
   }
 
   /**
-   * Applies a visitor to an array of expressions and, if specified, a single
-   * expression.
-   *
-   * @param visitor Visitor
-   * @param exprs   Array of expressions
-   * @param expr    Single expression, may be null
-   */
-  public static void apply(
-      RexVisitor<Void> visitor,
-      List<RexNode> exprs,
-      RexNode expr) {
-    for (RexNode expr0 : exprs) {
-      expr0.accept(visitor);
-    }
-    if (expr != null) {
-      expr.accept(visitor);
-    }
-  }
-
-  /**
    * Returns whether an expression is constant.
    */
   public boolean isConstant(RexNode ref) {
@@ -777,7 +757,7 @@ public class RexProgram {
    */
   public HashSet<String> getCorrelVariableNames() {
     final HashSet<String> paramIdSet = new HashSet<String>();
-    apply(
+    RexUtil.apply(
         new RexVisitorImpl<Void>(true) {
           public Void visitCorrelVariable(
               RexCorrelVariable correlVariable) {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/rex/RexUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
index f7712e1..c02861d 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -19,7 +19,7 @@ package org.apache.calcite.rex;
 import org.apache.calcite.linq4j.function.Predicate1;
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationImpl;
+import org.apache.calcite.rel.RelCollations;
 import org.apache.calcite.rel.RelFieldCollation;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
@@ -616,10 +616,8 @@ public class RexUtil {
   /**
    * Returns whether the leading edge of a given array of expressions is
    * wholly {@link RexInputRef} objects with types and names corresponding
-   * to the underlying row type.
-   *
-   * @deprecated Remove before
-   * {@link org.apache.calcite.util.Bug#upgrade Calcite-1.1}. */
+   * to the underlying row type. */
+  @Deprecated // to be removed before 1.1
   public static boolean containIdentity(List<? extends RexNode> exps,
       RelDataType rowType, RelDataType childRowType) {
     List<RelDataTypeField> fields = rowType.getFieldList();
@@ -767,7 +765,7 @@ public class RexUtil {
     final List<RelCollation> newCollationList =
         new ArrayList<RelCollation>();
     for (RelCollation collation : collationList) {
-      if (collation == RelCollationImpl.PRESERVE) {
+      if (collation == RelCollations.PRESERVE) {
         newCollationList.add(collation);
         continue;
       }
@@ -789,7 +787,7 @@ public class RexUtil {
       // and duplicate collations. Ignore these.
       if (!newFieldCollationList.isEmpty()) {
         final RelCollation newCollation =
-            RelCollationImpl.of(newFieldCollationList);
+            RelCollations.of(newFieldCollationList);
         if (!newCollationList.contains(newCollation)) {
           newCollationList.add(newCollation);
         }
@@ -817,7 +815,7 @@ public class RexUtil {
         applyFields(mapping, collation.getFieldCollations());
     return fieldCollations.equals(collation.getFieldCollations())
         ? collation
-        : RelCollationImpl.of(fieldCollations);
+        : RelCollations.of(fieldCollations);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/schema/Statistic.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/schema/Statistic.java b/core/src/main/java/org/apache/calcite/schema/Statistic.java
index b725d4b..4a4bce9 100644
--- a/core/src/main/java/org/apache/calcite/schema/Statistic.java
+++ b/core/src/main/java/org/apache/calcite/schema/Statistic.java
@@ -16,8 +16,11 @@
  */
 package org.apache.calcite.schema;
 
+import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.util.ImmutableBitSet;
 
+import java.util.List;
+
 /**
  * Statistics about a {@link Table}.
  *
@@ -33,6 +36,9 @@ public interface Statistic {
    * of a unique key, of the table.
    */
   boolean isKey(ImmutableBitSet columns);
+
+  /** Returns the collections of columns on which this table is sorted. */
+  List<RelCollation> getCollations();
 }
 
 // End Statistic.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/schema/Statistics.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/schema/Statistics.java b/core/src/main/java/org/apache/calcite/schema/Statistics.java
index 4b2611a..8e58c4d 100644
--- a/core/src/main/java/org/apache/calcite/schema/Statistics.java
+++ b/core/src/main/java/org/apache/calcite/schema/Statistics.java
@@ -16,8 +16,11 @@
  */
 package org.apache.calcite.schema;
 
+import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.util.ImmutableBitSet;
 
+import com.google.common.collect.ImmutableList;
+
 import java.util.List;
 
 /**
@@ -37,11 +40,21 @@ public class Statistics {
         public boolean isKey(ImmutableBitSet columns) {
           return false;
         }
+
+        public List<RelCollation> getCollations() {
+          return ImmutableList.of();
+        }
       };
 
   /** Returns a statistic with a given row count and set of unique keys. */
   public static Statistic of(final double rowCount,
       final List<ImmutableBitSet> keys) {
+    return of(rowCount, keys, ImmutableList.<RelCollation>of());
+  }
+
+  /** Returns a statistic with a given row count and set of unique keys. */
+  public static Statistic of(final double rowCount,
+      final List<ImmutableBitSet> keys, final List<RelCollation> collations) {
     return new Statistic() {
       public Double getRowCount() {
         return rowCount;
@@ -55,6 +68,10 @@ public class Statistics {
         }
         return false;
       }
+
+      public List<RelCollation> getCollations() {
+        return collations;
+      }
     };
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/sql/SqlWindow.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWindow.java b/core/src/main/java/org/apache/calcite/sql/SqlWindow.java
index be9d9fc..afc6b45 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlWindow.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlWindow.java
@@ -836,8 +836,7 @@ public class SqlWindow extends SqlCall {
         boolean onlyExpressions,
         SqlBasicVisitor.ArgHandler<R> argHandler) {
       if (onlyExpressions) {
-        final List<SqlNode> operandList = call.getOperandList();
-        for (Ord<SqlNode> operand : Ord.zip(operandList)) {
+        for (Ord<SqlNode> operand : Ord.zip(call.getOperandList())) {
           // if the second param is an Identifier then it's supposed to
           // be a name from a window clause and isn't part of the
           // group by check

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java b/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java
index 06d10c0..e6690a5 100644
--- a/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java
+++ b/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java
@@ -422,7 +422,7 @@ public class SqlAdvisor {
    * <p>To use a different parser (recognizing a different dialect of SQL),
    * derived class should override.
    *
-   * @return a {@link SqlAbstractParserImpl.Metadata} instance.
+   * @return metadata
    */
   protected SqlAbstractParserImpl.Metadata getParserMetadata() {
     SqlParser parser = SqlParser.create("");

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/sql/fun/SqlLiteralChainOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlLiteralChainOperator.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlLiteralChainOperator.java
index a3d6f24..c0e891c 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLiteralChainOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLiteralChainOperator.java
@@ -159,8 +159,7 @@ public class SqlLiteralChainOperator extends SqlSpecialOperator {
       int rightPrec) {
     final SqlWriter.Frame frame = writer.startList("", "");
     SqlCollation collation = null;
-    final List<SqlNode> rands = call.getOperandList();
-    for (Ord<SqlNode> operand : Ord.zip(rands)) {
+    for (Ord<SqlNode> operand : Ord.zip(call.getOperandList())) {
       SqlLiteral rand = (SqlLiteral) operand.e;
       if (operand.i > 0) {
         // SQL:2003 says there must be a newline between string

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/sql/util/SqlShuttle.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/util/SqlShuttle.java b/core/src/main/java/org/apache/calcite/sql/util/SqlShuttle.java
index c530c5c..c4e6f67 100644
--- a/core/src/main/java/org/apache/calcite/sql/util/SqlShuttle.java
+++ b/core/src/main/java/org/apache/calcite/sql/util/SqlShuttle.java
@@ -94,8 +94,9 @@ public class SqlShuttle extends SqlBasicVisitor<SqlNode> {
   //~ Inner Classes ----------------------------------------------------------
 
   /**
-   * Implementation of {@link ArgHandler} which deep-copies {@link SqlCall}s
-   * and their operands.
+   * Implementation of
+   * {@link org.apache.calcite.sql.util.SqlBasicVisitor.ArgHandler}
+   * that deep-copies {@link SqlCall}s and their operands.
    */
   protected class CallCopyingArgHandler implements ArgHandler<SqlNode> {
     boolean update;

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/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 8521ce2..7313f5e 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
@@ -575,8 +575,11 @@ public class RelDecorrelator implements ReflectiveVisitor {
     }
 
     LogicalAggregate newAggregate =
-        new LogicalAggregate(rel.getCluster(), newProjectRel, false,
-            ImmutableBitSet.range(newGroupKeyCount), null, newAggCalls);
+        LogicalAggregate.create(newProjectRel,
+            false,
+            ImmutableBitSet.range(newGroupKeyCount),
+            null,
+            newAggCalls);
 
     mapOldToNewRel.put(rel, newAggregate);
 
@@ -767,13 +770,9 @@ public class RelDecorrelator implements ReflectiveVisitor {
           resultRel = distinctRel;
         } else {
           resultRel =
-              new LogicalJoin(
-                  cluster,
-                  resultRel,
-                  distinctRel,
+              LogicalJoin.create(resultRel, distinctRel,
                   cluster.getRexBuilder().makeLiteral(true),
-                  JoinRelType.INNER,
-                  Collections.<String>emptySet());
+                  JoinRelType.INNER, ImmutableSet.<String>of());
         }
       }
     }
@@ -848,13 +847,8 @@ public class RelDecorrelator implements ReflectiveVisitor {
 
     final Set<String> variablesStopped = Collections.emptySet();
     RelNode joinRel =
-        new LogicalJoin(
-            rel.getCluster(),
-            newLeftChildRel,
-            valueGenRel,
-            rexBuilder.makeLiteral(true),
-            JoinRelType.INNER,
-            variablesStopped);
+        LogicalJoin.create(newLeftChildRel, valueGenRel,
+            rexBuilder.makeLiteral(true), JoinRelType.INNER, variablesStopped);
 
     mapOldToNewRel.put(oldChildRel, joinRel);
     mapNewRelToMapCorVarToOutputPos.put(joinRel, mapCorVarToOutputPos);
@@ -1063,13 +1057,8 @@ public class RelDecorrelator implements ReflectiveVisitor {
 
     final Set<String> variablesStopped = Collections.emptySet();
     RelNode newRel =
-        new LogicalJoin(
-            rel.getCluster(),
-            newLeftRel,
-            newRightRel,
-            condition,
-            rel.getJoinType().toJoinType(),
-            variablesStopped);
+        LogicalJoin.create(newLeftRel, newRightRel, condition,
+            rel.getJoinType().toJoinType(), variablesStopped);
 
     mapOldToNewRel.put(rel, newRel);
     mapNewRelToMapOldToNewOutputPos.put(newRel, mapOldToNewOutputPos);
@@ -1115,12 +1104,8 @@ public class RelDecorrelator implements ReflectiveVisitor {
 
     final Set<String> variablesStopped = Collections.emptySet();
     RelNode newRel =
-        new LogicalJoin(
-            rel.getCluster(),
-            newLeftRel,
-            newRightRel,
-            decorrelateExpr(rel.getCondition()),
-            rel.getJoinType(),
+        LogicalJoin.create(newLeftRel, newRightRel,
+            decorrelateExpr(rel.getCondition()), rel.getJoinType(),
             variablesStopped);
 
     // Create the mapping between the output of the old correlation rel
@@ -1981,12 +1966,7 @@ public class RelDecorrelator implements ReflectiveVisitor {
 
       // make the new join rel
       LogicalJoin join =
-          new LogicalJoin(
-              corRel.getCluster(),
-              leftInputRel,
-              rightInputRel,
-              joinCond,
-              joinType,
+          LogicalJoin.create(leftInputRel, rightInputRel, joinCond, joinType,
               ImmutableSet.<String>of());
 
       RelNode newProjRel =
@@ -2266,12 +2246,7 @@ public class RelDecorrelator implements ReflectiveVisitor {
                       "nullIndicator")));
 
       LogicalJoin join =
-          new LogicalJoin(
-              cluster,
-              leftInputRel,
-              rightInputRel,
-              joinCond,
-              joinType,
+          LogicalJoin.create(leftInputRel, rightInputRel, joinCond, joinType,
               ImmutableSet.<String>of());
 
       // To the consumer of joinOutputProjRel, nullIndicator is located
@@ -2345,8 +2320,11 @@ public class RelDecorrelator implements ReflectiveVisitor {
       ImmutableBitSet groupSet =
           ImmutableBitSet.range(groupCount);
       LogicalAggregate newAggRel =
-          new LogicalAggregate(cluster, joinOutputProjRel, false, groupSet,
-              null, newAggCalls);
+          LogicalAggregate.create(joinOutputProjRel,
+              false,
+              groupSet,
+              null,
+              newAggCalls);
 
       List<RexNode> newAggOutputProjExprList = Lists.newArrayList();
       for (int i : groupSet) {
@@ -2493,12 +2471,8 @@ public class RelDecorrelator implements ReflectiveVisitor {
       //     LogicalAggregate (groupby (0), agg0(), agg1()...)
       //
       LogicalCorrelate newCorRel =
-          new LogicalCorrelate(
-              cluster,
-              leftInputRel,
-              aggRel,
-              corRel.getCorrelationId(),
-              corRel.getRequiredColumns(),
+          LogicalCorrelate.create(leftInputRel, aggRel,
+              corRel.getCorrelationId(), corRel.getRequiredColumns(),
               corRel.getJoinType());
 
       // remember this rel so we don't fire rule on it again


Mime
View raw message