You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2015/04/17 06:42:25 UTC

phoenix git commit: Replace public constructors with create() method and set proper collation trait

Repository: phoenix
Updated Branches:
  refs/heads/calcite 9309fff7e -> c967b7962


Replace public constructors with create() method and set proper collation trait


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

Branch: refs/heads/calcite
Commit: c967b796257a82f2a813bb326c974d6444c35247
Parents: 9309fff
Author: maryannxue <we...@intel.com>
Authored: Fri Apr 17 00:42:13 2015 -0400
Committer: maryannxue <we...@intel.com>
Committed: Fri Apr 17 00:42:13 2015 -0400

----------------------------------------------------------------------
 .../apache/phoenix/calcite/PhoenixTable.java    |  4 +-
 .../calcite/rel/PhoenixAbstractJoin.java        |  3 +-
 .../calcite/rel/PhoenixAbstractProject.java     |  2 +-
 .../calcite/rel/PhoenixAbstractSort.java        |  2 +-
 .../calcite/rel/PhoenixClientAggregate.java     | 11 ++-
 .../phoenix/calcite/rel/PhoenixClientJoin.java  |  9 ++-
 .../calcite/rel/PhoenixClientProject.java       | 21 ++++-
 .../phoenix/calcite/rel/PhoenixClientSort.java  | 12 ++-
 .../calcite/rel/PhoenixCompactClientSort.java   | 12 ++-
 .../phoenix/calcite/rel/PhoenixFilter.java      |  9 ++-
 .../apache/phoenix/calcite/rel/PhoenixJoin.java |  9 ++-
 .../phoenix/calcite/rel/PhoenixLimit.java       | 44 ++++++++---
 .../calcite/rel/PhoenixServerAggregate.java     | 11 ++-
 .../phoenix/calcite/rel/PhoenixServerJoin.java  |  9 ++-
 .../calcite/rel/PhoenixServerProject.java       | 21 ++++-
 .../phoenix/calcite/rel/PhoenixServerSort.java  | 12 ++-
 .../phoenix/calcite/rel/PhoenixTableScan.java   | 22 +++++-
 .../rel/PhoenixToEnumerableConverter.java       | 10 ++-
 .../phoenix/calcite/rel/PhoenixUnion.java       |  9 ++-
 .../phoenix/calcite/rel/PhoenixValues.java      |  8 +-
 .../calcite/rules/PhoenixAddScanLimitRule.java  |  5 +-
 .../calcite/rules/PhoenixClientJoinRule.java    | 18 ++---
 .../rules/PhoenixCompactClientSortRule.java     |  4 +-
 .../calcite/rules/PhoenixConverterRules.java    | 80 ++++++++++----------
 .../rules/PhoenixFilterScanMergeRule.java       |  5 +-
 .../rules/PhoenixServerAggregateRule.java       |  6 +-
 .../calcite/rules/PhoenixServerJoinRule.java    |  4 +-
 .../calcite/rules/PhoenixServerProjectRule.java |  4 +-
 .../calcite/rules/PhoenixServerSortRule.java    |  4 +-
 29 files changed, 272 insertions(+), 98 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
index e47521b..a70602e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
@@ -72,7 +72,9 @@ public class PhoenixTable extends AbstractTable implements TranslatableTable {
     @Override
     public RelNode toRel(RelOptTable.ToRelContext context, RelOptTable relOptTable) {
         final RelOptCluster cluster = context.getCluster();
-        return new PhoenixTableScan(cluster, cluster.traitSetOf(PhoenixRel.CONVENTION), relOptTable, null, null);
+        // TODO Is there a better place to do this?
+        cluster.setMetadataProvider(PhoenixRel.METADATA_PROVIDER);
+        return PhoenixTableScan.create(cluster, relOptTable, null, null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractJoin.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractJoin.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractJoin.java
index 86ad41f..de5f464 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractJoin.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractJoin.java
@@ -15,7 +15,8 @@ import org.apache.phoenix.parse.JoinTableNode.JoinType;
  * relational expression in Phoenix.
  */
 abstract public class PhoenixAbstractJoin extends Join implements PhoenixRel {
-    public PhoenixAbstractJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition, JoinRelType joinType, Set<String> variablesStopped) {
+
+    protected PhoenixAbstractJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition, JoinRelType joinType, Set<String> variablesStopped) {
         super( cluster, traits, left, right, condition, joinType, variablesStopped);
         assert getConvention() == PhoenixRel.CONVENTION;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractProject.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractProject.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractProject.java
index 2c77e9f..9950605 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractProject.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractProject.java
@@ -21,7 +21,7 @@ import com.google.common.collect.Lists;
  * relational expression in Phoenix.
  */
 abstract public class PhoenixAbstractProject extends Project implements PhoenixRel {
-    public PhoenixAbstractProject(RelOptCluster cluster, RelTraitSet traits, RelNode input, List<? extends RexNode> projects, RelDataType rowType) {
+    protected PhoenixAbstractProject(RelOptCluster cluster, RelTraitSet traits, RelNode input, List<? extends RexNode> projects, RelDataType rowType) {
         super(cluster, traits, input, projects, rowType);
         assert getConvention() == PhoenixRel.CONVENTION;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractSort.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractSort.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractSort.java
index 4598bf5..294defc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractSort.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractSort.java
@@ -35,7 +35,7 @@ abstract public class PhoenixAbstractSort extends Sort implements PhoenixRel {
     
     private final Integer statelessFetch;
     
-    public PhoenixAbstractSort(RelOptCluster cluster, RelTraitSet traits, RelNode child, RelCollation collation, RexNode offset, RexNode fetch) {
+    protected PhoenixAbstractSort(RelOptCluster cluster, RelTraitSet traits, RelNode child, RelCollation collation, RexNode offset, RexNode fetch) {
         super(cluster, traits, child, collation, offset, fetch);
         Object value = fetch == null ? null : CalciteUtils.evaluateStatelessExpression(fetch);
         this.statelessFetch = value == null ? null : ((Number) value).intValue();        

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientAggregate.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientAggregate.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientAggregate.java
index d66294b..27179b7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientAggregate.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientAggregate.java
@@ -24,8 +24,17 @@ import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.schema.TableRef;
 
 public class PhoenixClientAggregate extends PhoenixAbstractAggregate {
+    
+    public static PhoenixClientAggregate create(RelNode input, boolean indicator, 
+            ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets, 
+            List<AggregateCall> aggCalls) {
+        RelOptCluster cluster = input.getCluster();
+        RelTraitSet traits = cluster.traitSetOf(PhoenixRel.CONVENTION);
+        return new PhoenixClientAggregate(cluster, traits, input, indicator, 
+                groupSet, groupSets, aggCalls);
+    }
 
-    public PhoenixClientAggregate(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixClientAggregate(RelOptCluster cluster, RelTraitSet traits,
             RelNode child, boolean indicator, ImmutableBitSet groupSet,
             List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) {
         super(cluster, traits, child, indicator, groupSet, groupSets, aggCalls);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientJoin.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientJoin.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientJoin.java
index c77e66e..4426b73 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientJoin.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientJoin.java
@@ -13,8 +13,15 @@ import org.apache.calcite.rex.RexNode;
 import org.apache.phoenix.compile.QueryPlan;
 
 public class PhoenixClientJoin extends PhoenixAbstractJoin {
+    
+    public static PhoenixClientJoin create(RelNode left, RelNode right, 
+            RexNode condition, JoinRelType joinType, Set<String> variablesStopped) {
+        RelOptCluster cluster = left.getCluster();
+        RelTraitSet traits = cluster.traitSetOf(PhoenixRel.CONVENTION);
+        return new PhoenixClientJoin(cluster, traits, left, right, condition, joinType, variablesStopped);
+    }
 
-    public PhoenixClientJoin(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixClientJoin(RelOptCluster cluster, RelTraitSet traits,
             RelNode left, RelNode right, RexNode condition,
             JoinRelType joinType, Set<String> variablesStopped) {
         super(cluster, traits, left, right, condition, joinType,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java
index 2557b43..dd900e2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java
@@ -6,16 +6,35 @@ import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.metadata.RelMdCollation;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.execute.TupleProjectionPlan;
 import org.apache.phoenix.execute.TupleProjector;
 
+import com.google.common.base.Supplier;
+
 public class PhoenixClientProject extends PhoenixAbstractProject {
+    
+    public static PhoenixClientProject create(final RelNode input, 
+            final List<? extends RexNode> projects, RelDataType rowType) {
+        RelOptCluster cluster = input.getCluster();
+        final RelTraitSet traits =
+                cluster.traitSet().replace(PhoenixRel.CONVENTION)
+                .replaceIfs(RelCollationTraitDef.INSTANCE,
+                        new Supplier<List<RelCollation>>() {
+                    public List<RelCollation> get() {
+                        return RelMdCollation.project(input, projects);
+                    }
+                });
+        return new PhoenixClientProject(cluster, traits, input, projects, rowType);
+    }
 
-    public PhoenixClientProject(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixClientProject(RelOptCluster cluster, RelTraitSet traits,
             RelNode input, List<? extends RexNode> projects, RelDataType rowType) {
         super(cluster, traits, input, projects, rowType);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientSort.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientSort.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientSort.java
index a36d9d0..ed441ed 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientSort.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientSort.java
@@ -7,6 +7,7 @@ import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rex.RexNode;
 import org.apache.hadoop.hbase.client.Scan;
@@ -21,8 +22,17 @@ import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.schema.TableRef;
 
 public class PhoenixClientSort extends PhoenixAbstractSort {
+    
+    public static PhoenixClientSort create(RelNode input, RelCollation collation, 
+            RexNode offset, RexNode fetch) {
+        RelOptCluster cluster = input.getCluster();
+        collation = RelCollationTraitDef.INSTANCE.canonize(collation);
+        RelTraitSet traits =
+            input.getTraitSet().replace(PhoenixRel.CONVENTION).replace(collation);
+        return new PhoenixClientSort(cluster, traits, input, collation, offset, fetch);
+    }
 
-    public PhoenixClientSort(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixClientSort(RelOptCluster cluster, RelTraitSet traits,
             RelNode child, RelCollation collation, RexNode offset, RexNode fetch) {
         super(cluster, traits, child, collation, offset, fetch);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixCompactClientSort.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixCompactClientSort.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixCompactClientSort.java
index 6e93905..94d0cdb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixCompactClientSort.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixCompactClientSort.java
@@ -5,6 +5,7 @@ import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rex.RexNode;
 import org.apache.phoenix.compile.QueryPlan;
@@ -15,8 +16,17 @@ import org.apache.phoenix.execute.TupleProjectionPlan;
 import org.apache.phoenix.execute.TupleProjector;
 
 public class PhoenixCompactClientSort extends PhoenixAbstractSort {
+    
+    public static PhoenixCompactClientSort create(RelNode input, RelCollation collation, 
+            RexNode offset, RexNode fetch) {
+        RelOptCluster cluster = input.getCluster();
+        collation = RelCollationTraitDef.INSTANCE.canonize(collation);
+        RelTraitSet traits =
+            input.getTraitSet().replace(PhoenixRel.CONVENTION).replace(collation);
+        return new PhoenixCompactClientSort(cluster, traits, input, collation, offset, fetch);
+    }
 
-    public PhoenixCompactClientSort(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixCompactClientSort(RelOptCluster cluster, RelTraitSet traits,
             RelNode child, RelCollation collation, RexNode offset, RexNode fetch) {
         super(cluster, traits, child, collation, offset, fetch);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixFilter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixFilter.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixFilter.java
index 0827d74..2a58a42 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixFilter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixFilter.java
@@ -18,7 +18,14 @@ import org.apache.phoenix.expression.Expression;
  * relational expression in Phoenix.
  */
 public class PhoenixFilter extends Filter implements PhoenixRel {
-    public PhoenixFilter(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode condition) {
+    
+    public static PhoenixFilter create(RelNode input, RexNode condition) {
+        RelOptCluster cluster = input.getCluster();
+        RelTraitSet traits = input.getTraitSet().replace(PhoenixRel.CONVENTION);
+        return new PhoenixFilter(cluster, traits, input, condition);
+    }
+    
+    private PhoenixFilter(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode condition) {
         super(cluster, traits, input, condition);
         assert getConvention() == PhoenixRel.CONVENTION;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixJoin.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixJoin.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixJoin.java
index 142fb35..9f31612 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixJoin.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixJoin.java
@@ -15,8 +15,15 @@ import org.apache.phoenix.compile.QueryPlan;
 import com.google.common.collect.ImmutableSet;
 
 public class PhoenixJoin extends Join implements PhoenixRel {
+    
+    public static PhoenixJoin create(RelNode left, RelNode right, 
+            RexNode condition, JoinRelType joinType, Set<String> variablesStopped) {
+        RelOptCluster cluster = left.getCluster();
+        RelTraitSet traits = cluster.traitSetOf(PhoenixRel.CONVENTION);
+        return new PhoenixJoin(cluster, traits, left, right, condition, joinType, variablesStopped);
+    }
 
-    public PhoenixJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left,
+    private PhoenixJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left,
             RelNode right, RexNode condition, JoinRelType joinType,
             Set<String> variablesStopped) {
         super(cluster, traits, left, right, condition, joinType,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java
index 10f5518..02776a5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java
@@ -1,12 +1,14 @@
 package org.apache.phoenix.calcite.rel;
 
+import java.util.List;
+
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 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.Sort;
+import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.SingleRel;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
 import org.apache.calcite.rex.RexNode;
 import org.apache.phoenix.calcite.CalciteUtils;
@@ -15,21 +17,43 @@ import org.apache.phoenix.compile.RowProjector;
 import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
 import org.apache.phoenix.execute.ClientScanPlan;
 
-public class PhoenixLimit extends Sort implements PhoenixRel {
+public class PhoenixLimit extends SingleRel implements PhoenixRel {
+    public final RexNode offset;
+    public final RexNode fetch;
     public final Integer statelessFetch;
+    
+    public static PhoenixLimit create(RelNode input, RexNode offset, RexNode fetch) {
+        RelOptCluster cluster = input.getCluster();
+        RelTraitSet traits = input.getTraitSet().replace(PhoenixRel.CONVENTION);
+        return new PhoenixLimit(cluster, traits, input, offset, fetch);
+    }
 
-    public PhoenixLimit(RelOptCluster cluster, RelTraitSet traits, RelNode input, RelCollation collation, RexNode offset, RexNode fetch) {
-        super(cluster, traits, input, collation, offset, fetch);
+    private PhoenixLimit(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode offset, RexNode fetch) {
+        super(cluster, traits, input);
+        this.offset = offset;
+        this.fetch = fetch;
         Object value = fetch == null ? null : CalciteUtils.evaluateStatelessExpression(fetch);
         this.statelessFetch = value == null ? null : ((Number) value).intValue();        
         assert getConvention() == PhoenixRel.CONVENTION;
-        assert getCollation().getFieldCollations().isEmpty();
     }
-
+    
     @Override
-    public PhoenixLimit copy(RelTraitSet traitSet, RelNode newInput,
-            RelCollation newCollation, RexNode offset, RexNode fetch) {
-        return new PhoenixLimit(getCluster(), traitSet, newInput, newCollation, offset, fetch);
+    public PhoenixLimit copy(
+            RelTraitSet traitSet,
+            List<RelNode> newInputs) {
+        return new PhoenixLimit(
+                getCluster(),
+                traitSet,
+                sole(newInputs),
+                offset,
+                fetch);
+    }
+
+    @Override 
+    public RelWriter explainTerms(RelWriter pw) {
+        return super.explainTerms(pw)
+                .itemIf("offset", offset, offset != null)
+                .itemIf("fetch", fetch, fetch != null);
     }
 
     @Override 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerAggregate.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerAggregate.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerAggregate.java
index 3511699..8657a36 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerAggregate.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerAggregate.java
@@ -20,8 +20,17 @@ import org.apache.phoenix.execute.HashJoinPlan;
 import org.apache.phoenix.execute.ScanPlan;
 
 public class PhoenixServerAggregate extends PhoenixAbstractAggregate {
+    
+    public static PhoenixServerAggregate create(RelNode input, boolean indicator, 
+            ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets, 
+            List<AggregateCall> aggCalls) {
+        RelOptCluster cluster = input.getCluster();
+        RelTraitSet traits = cluster.traitSetOf(PhoenixRel.CONVENTION);
+        return new PhoenixServerAggregate(cluster, traits, input, indicator, 
+                groupSet, groupSets, aggCalls);
+    }
 
-    public PhoenixServerAggregate(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixServerAggregate(RelOptCluster cluster, RelTraitSet traits,
             RelNode child, boolean indicator, ImmutableBitSet groupSet,
             List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) {
         super(cluster, traits, child, indicator, groupSet, groupSets, aggCalls);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerJoin.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerJoin.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerJoin.java
index b937df9..fe84ce7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerJoin.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerJoin.java
@@ -31,8 +31,15 @@ import org.apache.phoenix.schema.TableRef;
 import com.google.common.collect.Lists;
 
 public class PhoenixServerJoin extends PhoenixAbstractJoin {
+    
+    public static PhoenixServerJoin create(RelNode left, RelNode right, 
+            RexNode condition, JoinRelType joinType, Set<String> variablesStopped) {
+        RelOptCluster cluster = left.getCluster();
+        RelTraitSet traits = left.getTraitSet().replace(PhoenixRel.CONVENTION);
+        return new PhoenixServerJoin(cluster, traits, left, right, condition, joinType, variablesStopped);
+    }
 
-    public PhoenixServerJoin(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixServerJoin(RelOptCluster cluster, RelTraitSet traits,
             RelNode left, RelNode right, RexNode condition,
             JoinRelType joinType, Set<String> variablesStopped) {
         super(cluster, traits, left, right, condition, joinType,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java
index f9de2ee..710712d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java
@@ -6,7 +6,10 @@ import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.metadata.RelMdCollation;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.phoenix.compile.QueryPlan;
@@ -14,9 +17,25 @@ import org.apache.phoenix.execute.HashJoinPlan;
 import org.apache.phoenix.execute.ScanPlan;
 import org.apache.phoenix.execute.TupleProjector;
 
+import com.google.common.base.Supplier;
+
 public class PhoenixServerProject extends PhoenixAbstractProject {
+    
+    public static PhoenixServerProject create(final RelNode input, 
+            final List<? extends RexNode> projects, RelDataType rowType) {
+        RelOptCluster cluster = input.getCluster();
+        final RelTraitSet traits =
+                cluster.traitSet().replace(PhoenixRel.CONVENTION)
+                .replaceIfs(RelCollationTraitDef.INSTANCE,
+                        new Supplier<List<RelCollation>>() {
+                    public List<RelCollation> get() {
+                        return RelMdCollation.project(input, projects);
+                    }
+                });
+        return new PhoenixServerProject(cluster, traits, input, projects, rowType);
+    }
 
-    public PhoenixServerProject(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixServerProject(RelOptCluster cluster, RelTraitSet traits,
             RelNode input, List<? extends RexNode> projects, RelDataType rowType) {
         super(cluster, traits, input, projects, rowType);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerSort.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerSort.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerSort.java
index eb4c315..950a730 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerSort.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerSort.java
@@ -7,6 +7,7 @@ import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rex.RexNode;
 import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
@@ -15,8 +16,17 @@ import org.apache.phoenix.execute.HashJoinPlan;
 import org.apache.phoenix.execute.ScanPlan;
 
 public class PhoenixServerSort extends PhoenixAbstractSort {
+    
+    public static PhoenixServerSort create(RelNode input, RelCollation collation, 
+            RexNode offset, RexNode fetch) {
+        RelOptCluster cluster = input.getCluster();
+        collation = RelCollationTraitDef.INSTANCE.canonize(collation);
+        RelTraitSet traits =
+            input.getTraitSet().replace(PhoenixRel.CONVENTION).replace(collation);
+        return new PhoenixServerSort(cluster, traits, input, collation, offset, fetch);
+    }
 
-    public PhoenixServerSort(RelOptCluster cluster, RelTraitSet traits,
+    private PhoenixServerSort(RelOptCluster cluster, RelTraitSet traits,
             RelNode child, RelCollation collation, RexNode offset, RexNode fetch) {
         super(cluster, traits, child, collation, offset, fetch);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
index b9bea64..c0ea42b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
@@ -9,6 +9,8 @@ import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.RelWriter;
 import org.apache.calcite.rel.core.TableScan;
@@ -49,6 +51,8 @@ import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.util.SchemaUtil;
 
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 /**
@@ -62,8 +66,24 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel {
      * estimate of the row count.
      */
     public final Integer statelessFetch;
+    
+    public static PhoenixTableScan create(RelOptCluster cluster, final RelOptTable table, 
+            RexNode filter, Integer statelessFetch) {
+        final RelTraitSet traits =
+                cluster.traitSetOf(PhoenixRel.CONVENTION)
+                .replaceIfs(RelCollationTraitDef.INSTANCE,
+                        new Supplier<List<RelCollation>>() {
+                    public List<RelCollation> get() {
+                        if (table != null) {
+                            return table.unwrap(PhoenixTable.class).getStatistic().getCollations();
+                        }
+                        return ImmutableList.of();
+                    }
+                });
+        return new PhoenixTableScan(cluster, traits, table, filter, statelessFetch);
+    }
 
-    public PhoenixTableScan(RelOptCluster cluster, RelTraitSet traits, RelOptTable table, RexNode filter, Integer statelessFetch) {
+    private PhoenixTableScan(RelOptCluster cluster, RelTraitSet traits, RelOptTable table, RexNode filter, Integer statelessFetch) {
         super(cluster, traits, table);
         this.filter = filter;
         this.statelessFetch = statelessFetch;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
index 3916102..dd6420e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java
@@ -3,6 +3,7 @@ package org.apache.phoenix.calcite.rel;
 import java.sql.SQLException;
 import java.util.List;
 
+import org.apache.calcite.adapter.enumerable.EnumerableConvention;
 import org.apache.calcite.adapter.enumerable.EnumerableRel;
 import org.apache.calcite.adapter.enumerable.EnumerableRelImplementor;
 import org.apache.calcite.adapter.enumerable.JavaRowFormat;
@@ -32,7 +33,14 @@ import org.apache.phoenix.iterate.ResultIterator;
  * Scan of a Phoenix table.
  */
 public class PhoenixToEnumerableConverter extends ConverterImpl implements EnumerableRel {
-    public PhoenixToEnumerableConverter(
+
+    public static PhoenixToEnumerableConverter create(RelNode input) {
+        RelOptCluster cluster = input.getCluster();
+        RelTraitSet traits = input.getTraitSet().replace(EnumerableConvention.INSTANCE);
+        return new PhoenixToEnumerableConverter(cluster, traits, input);
+    }
+
+    private PhoenixToEnumerableConverter(
         RelOptCluster cluster,
         RelTraitSet traits,
         RelNode input) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixUnion.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixUnion.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixUnion.java
index 787b2f1..2885ae5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixUnion.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixUnion.java
@@ -14,7 +14,14 @@ import org.apache.phoenix.compile.QueryPlan;
  * relational expression in Phoenix.
  */
 public class PhoenixUnion extends Union implements PhoenixRel {
-    public PhoenixUnion(RelOptCluster cluster, RelTraitSet traits, List<RelNode> inputs, boolean all) {
+    
+    public static PhoenixUnion create(List<RelNode> inputs, boolean all) {
+        RelOptCluster cluster = inputs.get(0).getCluster();
+        RelTraitSet traits = cluster.traitSetOf(PhoenixRel.CONVENTION);
+        return new PhoenixUnion(cluster, traits, inputs, all);
+    }
+    
+    private PhoenixUnion(RelOptCluster cluster, RelTraitSet traits, List<RelNode> inputs, boolean all) {
         super(cluster, traits, inputs, all);
         assert getConvention() == PhoenixRel.CONVENTION;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java
index f1a626b..41320f1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java
@@ -18,7 +18,13 @@ import com.google.common.collect.ImmutableList;
  * relational expression in Phoenix.
  */
 public class PhoenixValues extends Values implements PhoenixRel {
-    public PhoenixValues(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits) {
+    
+    public static PhoenixValues create(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples) {
+        RelTraitSet traits = cluster.traitSetOf(PhoenixRel.CONVENTION);
+        return new PhoenixValues(cluster, rowType, tuples, traits);
+    }
+    
+    private PhoenixValues(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits) {
         super(cluster, rowType, tuples, traits);
         assert getConvention() == PhoenixRel.CONVENTION;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java
index 5770f26..9abf3dc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java
@@ -60,9 +60,8 @@ public class PhoenixAddScanLimitRule extends RelOptRule {
         PhoenixTableScan scan = call.rel(relCount - 1);
         assert limit.statelessFetch != null : "predicate should have ensured fetch is stateless";
         assert scan.statelessFetch == null : "predicate should have ensured table scan has no stateless fetch";
-        PhoenixTableScan newScan = new PhoenixTableScan(
-                scan.getCluster(), scan.getTraitSet(), scan.getTable(),
-                scan.filter, limit.statelessFetch);
+        PhoenixTableScan newScan = PhoenixTableScan.create(
+                scan.getCluster(), scan.getTable(), scan.filter, limit.statelessFetch);
         PhoenixRel newInput = project == null ? 
                   newScan 
                 : project.copy(project.getTraitSet(), newScan, 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixClientJoinRule.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixClientJoinRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixClientJoinRule.java
index 9558209..83812d6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixClientJoinRule.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixClientJoinRule.java
@@ -5,9 +5,7 @@ import java.util.List;
 
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
-import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelCollations;
 import org.apache.calcite.rel.RelFieldCollation;
 import org.apache.calcite.rel.RelFieldCollation.Direction;
@@ -17,8 +15,6 @@ import org.apache.calcite.rel.core.JoinInfo;
 import org.apache.phoenix.calcite.rel.PhoenixClientJoin;
 import org.apache.phoenix.calcite.rel.PhoenixClientSort;
 import org.apache.phoenix.calcite.rel.PhoenixJoin;
-import org.apache.phoenix.calcite.rel.PhoenixRel;
-
 import com.google.common.collect.Lists;
 
 public class PhoenixClientJoinRule extends RelOptRule {
@@ -43,21 +39,19 @@ public class PhoenixClientJoinRule extends RelOptRule {
             for (Iterator<Integer> iter = joinInfo.leftKeys.iterator(); iter.hasNext();) {
                 leftFieldCollations.add(new RelFieldCollation(iter.next(), Direction.ASCENDING,NullDirection.FIRST));
             }
-            RelCollation leftCollation = RelCollationTraitDef.INSTANCE.canonize(RelCollations.of(leftFieldCollations));
-            RelTraitSet leftTraitSet = left.getTraitSet().replace(PhoenixRel.CONVENTION).replace(leftCollation);
-            newLeft = new PhoenixClientSort(left.getCluster(), leftTraitSet, left, leftCollation, null, null);
+            RelCollation leftCollation = RelCollations.of(leftFieldCollations);
+            newLeft = PhoenixClientSort.create(left, leftCollation, null, null);
 
             List<RelFieldCollation> rightFieldCollations = Lists.newArrayList();
             for (Iterator<Integer> iter = joinInfo.rightKeys.iterator(); iter.hasNext();) {
                 rightFieldCollations.add(new RelFieldCollation(iter.next(), Direction.ASCENDING,NullDirection.FIRST));
             }
-            RelCollation rightCollation = RelCollationTraitDef.INSTANCE.canonize(RelCollations.of(rightFieldCollations));
-            RelTraitSet rightTraitSet = right.getTraitSet().replace(PhoenixRel.CONVENTION).replace(rightCollation);
-            newRight = new PhoenixClientSort(right.getCluster(), rightTraitSet, right, rightCollation, null, null);
+            RelCollation rightCollation = RelCollations.of(rightFieldCollations);
+            newRight = PhoenixClientSort.create(right, rightCollation, null, null);
         }
 
-        call.transformTo(new PhoenixClientJoin(join.getCluster(),
-                join.getTraitSet(), newLeft, newRight, join.getCondition(), 
+        call.transformTo(PhoenixClientJoin.create(
+                newLeft, newRight, join.getCondition(), 
                 join.getJoinType(), join.getVariablesStopped()));
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixCompactClientSortRule.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixCompactClientSortRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixCompactClientSortRule.java
index d1f4ec7..7a840ba 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixCompactClientSortRule.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixCompactClientSortRule.java
@@ -23,8 +23,8 @@ public class PhoenixCompactClientSortRule extends RelOptRule {
     public void onMatch(RelOptRuleCall call) {
         PhoenixClientSort sort = call.rel(0);
         PhoenixRel input = call.rel(1);
-        call.transformTo(new PhoenixCompactClientSort(sort.getCluster(),
-                sort.getTraitSet(), input, sort.getCollation(), sort.offset, sort.fetch));
+        call.transformTo(PhoenixCompactClientSort.create(
+                input, sort.getCollation(), sort.offset, sort.fetch));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java
index 2b7b870..093966d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java
@@ -91,12 +91,13 @@ public class PhoenixConverterRules {
 
         public RelNode convert(RelNode rel) {
             final LogicalSort sort = (LogicalSort) rel;
-            final RelTraitSet traitSet =
-                sort.getTraitSet().replace(out)
-                    .replace(sort.getCollation());
-            return new PhoenixClientSort(rel.getCluster(), traitSet,
-                convert(sort.getInput(), sort.getInput().getTraitSet().replace(out)),
-                sort.getCollation(), sort.offset, sort.fetch);
+            return PhoenixClientSort.create(
+                convert(
+                        sort.getInput(), 
+                        sort.getInput().getTraitSet().replace(out)),
+                sort.getCollation(), 
+                sort.offset, 
+                sort.fetch);
         }
     }
 
@@ -121,11 +122,12 @@ public class PhoenixConverterRules {
 
         public RelNode convert(RelNode rel) {
             final LogicalSort sort = (LogicalSort) rel;
-            final RelTraitSet traitSet =
-                sort.getTraitSet().replace(out);
-            return new PhoenixLimit(rel.getCluster(), traitSet,
-                convert(sort.getInput(), sort.getInput().getTraitSet().replace(out)),
-                sort.getCollation(), sort.offset, sort.fetch);
+            return PhoenixLimit.create(
+                convert(
+                        sort.getInput(), 
+                        sort.getInput().getTraitSet().replace(out)),
+                sort.offset, 
+                sort.fetch);
         }
     }
 
@@ -143,11 +145,10 @@ public class PhoenixConverterRules {
 
         public RelNode convert(RelNode rel) {
             final LogicalFilter filter = (LogicalFilter) rel;
-            final RelTraitSet traitSet = filter.getTraitSet().replace(out);
-            return new PhoenixFilter(
-                rel.getCluster(),
-                traitSet,
-                convert(filter.getInput(), filter.getInput().getTraitSet().replace(out)),
+            return PhoenixFilter.create(
+                convert(
+                        filter.getInput(), 
+                        filter.getInput().getTraitSet().replace(out)),
                 filter.getCondition());
         }
     }
@@ -166,9 +167,11 @@ public class PhoenixConverterRules {
 
         public RelNode convert(RelNode rel) {
             final LogicalProject project = (LogicalProject) rel;
-            final RelTraitSet traitSet = project.getTraitSet().replace(out);
-            return new PhoenixClientProject(project.getCluster(), traitSet,
-                convert(project.getInput(), project.getInput().getTraitSet().replace(out)), project.getProjects(),
+            return PhoenixClientProject.create(
+                convert(
+                        project.getInput(), 
+                        project.getInput().getTraitSet().replace(out)), 
+                project.getProjects(),
                 project.getRowType());
         }
     }
@@ -187,12 +190,10 @@ public class PhoenixConverterRules {
 
         public RelNode convert(RelNode rel) {
             final LogicalAggregate agg = (LogicalAggregate) rel;
-            final RelTraitSet traitSet =
-                agg.getTraitSet().replace(out);
-            return new PhoenixClientAggregate(
-                    rel.getCluster(),
-                    traitSet,
-                    convert(agg.getInput(), agg.getInput().getTraitSet().replace(out)),
+            return PhoenixClientAggregate.create(
+                    convert(
+                            agg.getInput(), 
+                            agg.getInput().getTraitSet().replace(out)),
                     agg.indicator,
                     agg.getGroupSet(),
                     agg.getGroupSets(),
@@ -214,9 +215,9 @@ public class PhoenixConverterRules {
 
         public RelNode convert(RelNode rel) {
             final LogicalUnion union = (LogicalUnion) rel;
-            final RelTraitSet traitSet = union.getTraitSet().replace(out);
-            return new PhoenixUnion(rel.getCluster(), traitSet, convertList(union.getInputs(), out),
-                union.all);
+            return PhoenixUnion.create(
+                    convertList(union.getInputs(), out),
+                    union.all);
         }
     }
 
@@ -234,14 +235,16 @@ public class PhoenixConverterRules {
 
         public RelNode convert(RelNode rel) {
             final LogicalJoin join = (LogicalJoin) rel;
-            final RelTraitSet traitSet =
-                join.getTraitSet().replace(out);
-            return new PhoenixJoin(rel.getCluster(), traitSet,
-                convert(join.getLeft(), join.getLeft().getTraitSet().replace(out)),
-                convert(join.getRight(), join.getRight().getTraitSet().replace(out)),
-                join.getCondition(),
-                join.getJoinType(),
-                join.getVariablesStopped());
+            return PhoenixJoin.create(
+                    convert(
+                            join.getLeft(), 
+                            join.getLeft().getTraitSet().replace(out)),
+                    convert(
+                            join.getRight(), 
+                            join.getRight().getTraitSet().replace(out)),
+                    join.getCondition(),
+                    join.getJoinType(),
+                    join.getVariablesStopped());
         }
     }
 
@@ -403,10 +406,7 @@ public class PhoenixConverterRules {
         }
 
         @Override public RelNode convert(RelNode rel) {
-            RelTraitSet newTraitSet = rel.getTraitSet().replace(getOutConvention());
-            // TODO Is there a better place to do this?
-            rel.getCluster().setMetadataProvider(PhoenixRel.METADATA_PROVIDER);
-            return new PhoenixToEnumerableConverter(rel.getCluster(), newTraitSet, rel);
+            return PhoenixToEnumerableConverter.create(rel);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java
index 9a992b3..87335ef 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java
@@ -31,8 +31,7 @@ public class PhoenixFilterScanMergeRule extends RelOptRule {
         PhoenixFilter filter = call.rel(0);
         PhoenixTableScan scan = call.rel(1);
         assert scan.filter == null : "predicate should have ensured no filter";
-        call.transformTo(new PhoenixTableScan(scan.getCluster(),
-                scan.getTraitSet(), scan.getTable(),
-                filter.getCondition(), scan.statelessFetch));
+        call.transformTo(PhoenixTableScan.create(scan.getCluster(),
+                scan.getTable(), filter.getCondition(), scan.statelessFetch));
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerAggregateRule.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerAggregateRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerAggregateRule.java
index 27747b1..90ebce7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerAggregateRule.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerAggregateRule.java
@@ -31,9 +31,9 @@ public class PhoenixServerAggregateRule extends RelOptRule {
     public void onMatch(RelOptRuleCall call) {
         PhoenixClientAggregate aggregate = call.rel(0);
         PhoenixRel input = call.rel(1);
-        call.transformTo(new PhoenixServerAggregate(aggregate.getCluster(),
-                aggregate.getTraitSet(), input, aggregate.indicator, 
-                aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList()));
+        call.transformTo(PhoenixServerAggregate.create(input, aggregate.indicator, 
+                aggregate.getGroupSet(), aggregate.getGroupSets(), 
+                aggregate.getAggCallList()));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerJoinRule.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerJoinRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerJoinRule.java
index 2f30dad..45e0f12 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerJoinRule.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerJoinRule.java
@@ -46,8 +46,8 @@ public class PhoenixServerJoinRule extends RelOptRule {
         PhoenixJoin join = call.rel(0);
         PhoenixRel left = call.rel(1);
         PhoenixRel right = call.rel(call.getRelList().size() - 1);
-        call.transformTo(new PhoenixServerJoin(join.getCluster(),
-                join.getTraitSet(), left, right, join.getCondition(), 
+        call.transformTo(PhoenixServerJoin.create(
+                left, right, join.getCondition(), 
                 join.getJoinType(), join.getVariablesStopped()));
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerProjectRule.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerProjectRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerProjectRule.java
index 5fd3e0f..662acd3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerProjectRule.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerProjectRule.java
@@ -27,8 +27,8 @@ public class PhoenixServerProjectRule extends RelOptRule {
     public void onMatch(RelOptRuleCall call) {
         PhoenixClientProject project = call.rel(0);
         PhoenixRel input = call.rel(1);
-        call.transformTo(new PhoenixServerProject(project.getCluster(),
-                project.getTraitSet(), input, project.getProjects(), project.getRowType()));
+        call.transformTo(PhoenixServerProject.create(
+                input, project.getProjects(), project.getRowType()));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c967b796/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerSortRule.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerSortRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerSortRule.java
index 19354be..f09f53a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerSortRule.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixServerSortRule.java
@@ -31,8 +31,8 @@ public class PhoenixServerSortRule extends RelOptRule {
     public void onMatch(RelOptRuleCall call) {
         PhoenixClientSort sort = call.rel(0);
         PhoenixRel input = call.rel(1);
-        call.transformTo(new PhoenixServerSort(sort.getCluster(),
-                sort.getTraitSet(), input, sort.getCollation(), sort.offset, sort.fetch));
+        call.transformTo(PhoenixServerSort.create(
+                input, sort.getCollation(), sort.offset, sort.fetch));
     }
 
 }