Repository: phoenix
Updated Branches:
  refs/heads/calcite ed39c7d53 -> 50e4406db


http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/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 9d83df5..84b4a60 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
@@ -44,16 +44,15 @@ import org.apache.phoenix.calcite.rel.PhoenixClientJoin;
 import org.apache.phoenix.calcite.rel.PhoenixClientProject;
 import org.apache.phoenix.calcite.rel.PhoenixClientSemiJoin;
 import org.apache.phoenix.calcite.rel.PhoenixClientSort;
+import org.apache.phoenix.calcite.rel.PhoenixConvention;
 import org.apache.phoenix.calcite.rel.PhoenixCorrelate;
 import org.apache.phoenix.calcite.rel.PhoenixFilter;
 import org.apache.phoenix.calcite.rel.PhoenixLimit;
-import org.apache.phoenix.calcite.rel.PhoenixRel;
 import org.apache.phoenix.calcite.rel.PhoenixServerAggregate;
 import org.apache.phoenix.calcite.rel.PhoenixServerJoin;
 import org.apache.phoenix.calcite.rel.PhoenixServerProject;
 import org.apache.phoenix.calcite.rel.PhoenixServerSemiJoin;
 import org.apache.phoenix.calcite.rel.PhoenixServerSort;
-import org.apache.phoenix.calcite.rel.PhoenixToClientConverter;
 import org.apache.phoenix.calcite.rel.PhoenixToEnumerableConverter;
 import org.apache.phoenix.calcite.rel.PhoenixUncollect;
 import org.apache.phoenix.calcite.rel.PhoenixUnion;
@@ -65,7 +64,7 @@ import com.google.common.collect.Lists;
 
 /**
  * Rules and relational operators for
- * {@link PhoenixRel#CONVENTION PHOENIX}
+ * {@link PhoenixConvention}
  * calling convention.
  */
 public class PhoenixConverterRules {
@@ -74,15 +73,16 @@ public class PhoenixConverterRules {
     protected static final Logger LOGGER = CalciteTrace.getPlannerTracer();
 
     public static final RelOptRule[] RULES = {
-        PhoenixToEnumerableConverterRule.INSTANCE,
-        PhoenixServerToClientConverterRule.INSTANCE,
-        PhoenixProjectableToClientConverterRule.INSTANCE,
+        PhoenixToEnumerableConverterRule.SERVER,
+        PhoenixToEnumerableConverterRule.SERVERJOIN,
+        PhoenixToEnumerableConverterRule.CLIENT,
         PhoenixClientSortRule.INSTANCE,
         PhoenixServerSortRule.SERVER,
         PhoenixServerSortRule.SERVERJOIN,
         PhoenixLimitRule.INSTANCE,
         PhoenixFilterRule.INSTANCE,
-        PhoenixClientProjectRule.INSTANCE,
+        PhoenixClientProjectRule.SERVERJOIN,
+        PhoenixClientProjectRule.CLIENT,
         PhoenixServerProjectRule.INSTANCE,
         PhoenixClientAggregateRule.INSTANCE,
         PhoenixServerAggregateRule.SERVER,
@@ -98,15 +98,16 @@ public class PhoenixConverterRules {
     };
 
     public static final RelOptRule[] CONVERTIBLE_RULES = {
-        PhoenixToEnumerableConverterRule.INSTANCE,
-        PhoenixServerToClientConverterRule.INSTANCE,
-        PhoenixProjectableToClientConverterRule.INSTANCE,
+        PhoenixToEnumerableConverterRule.SERVER,
+        PhoenixToEnumerableConverterRule.SERVERJOIN,
+        PhoenixToEnumerableConverterRule.CLIENT,
         PhoenixClientSortRule.INSTANCE,
         PhoenixServerSortRule.SERVER,
         PhoenixServerSortRule.SERVERJOIN,
         PhoenixLimitRule.INSTANCE,
         PhoenixFilterRule.CONVERTIBLE,
-        PhoenixClientProjectRule.CONVERTIBLE,
+        PhoenixClientProjectRule.CONVERTIBLE_SERVERJOIN,
+        PhoenixClientProjectRule.CONVERTIBLE_CLIENT,
         PhoenixServerProjectRule.CONVERTIBLE,
         PhoenixClientAggregateRule.CONVERTIBLE,
         PhoenixServerAggregateRule.CONVERTIBLE_SERVER,
@@ -165,7 +166,7 @@ public class PhoenixConverterRules {
         private PhoenixClientSortRule() {
             super(LogicalSort.class, 
                     SORT_ONLY, 
-                    Convention.NONE, PhoenixRel.CLIENT_CONVENTION, 
"PhoenixClientSortRule");
+                    Convention.NONE, PhoenixConvention.CLIENT, 
"PhoenixClientSortRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -173,7 +174,7 @@ public class PhoenixConverterRules {
             return PhoenixClientSort.create(
                 convert(
                         sort.getInput(), 
-                        
sort.getInput().getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)),
+                        
sort.getInput().getTraitSet().replace(PhoenixConvention.CLIENT)),
                 sort.getCollation());
         }
     }
@@ -193,15 +194,15 @@ public class PhoenixConverterRules {
             }            
         };
         
-        public static final PhoenixServerSortRule SERVER = new 
PhoenixServerSortRule(PhoenixRel.SERVER_CONVENTION);
-        public static final PhoenixServerSortRule SERVERJOIN = new 
PhoenixServerSortRule(PhoenixRel.SERVERJOIN_CONVENTION);
+        public static final PhoenixServerSortRule SERVER = new 
PhoenixServerSortRule(PhoenixConvention.SERVER);
+        public static final PhoenixServerSortRule SERVERJOIN = new 
PhoenixServerSortRule(PhoenixConvention.SERVERJOIN);
 
         private final Convention inputConvention;
 
         private PhoenixServerSortRule(Convention inputConvention) {
             super(LogicalSort.class, 
                     SORT_ONLY, 
-                    Convention.NONE, PhoenixRel.CLIENT_CONVENTION, 
"PhoenixServerSortRule:" + inputConvention.getName());
+                    Convention.NONE, PhoenixConvention.CLIENT, 
"PhoenixServerSortRule:" + inputConvention.getName());
             this.inputConvention = inputConvention;
         }
 
@@ -234,7 +235,7 @@ public class PhoenixConverterRules {
         private PhoenixLimitRule() {
             super(LogicalSort.class, 
                     HAS_FETCH, 
-                    Convention.NONE, PhoenixRel.CLIENT_CONVENTION, 
"PhoenixLimitRule");
+                    Convention.NONE, PhoenixConvention.CLIENT, 
"PhoenixLimitRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -250,7 +251,7 @@ public class PhoenixConverterRules {
             return PhoenixLimit.create(
                 convert(
                         input, 
-                        input.getTraitSet().replace(out)),
+                        
input.getTraitSet().replace(PhoenixConvention.GENERIC)),
                 sort.offset, 
                 sort.fetch);
         }
@@ -274,7 +275,7 @@ public class PhoenixConverterRules {
 
         private PhoenixFilterRule(Predicate<LogicalFilter> predicate) {
             super(LogicalFilter.class, predicate, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, "PhoenixFilterRule");
+                    PhoenixConvention.CLIENT, "PhoenixFilterRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -282,7 +283,7 @@ public class PhoenixConverterRules {
             return PhoenixFilter.create(
                 convert(
                         filter.getInput(), 
-                        filter.getInput().getTraitSet().replace(out)),
+                        
filter.getInput().getTraitSet().replace(PhoenixConvention.GENERIC)),
                 filter.getCondition());
         }
     }
@@ -300,13 +301,30 @@ public class PhoenixConverterRules {
             }            
         };
         
-        private static final PhoenixClientProjectRule INSTANCE = new 
PhoenixClientProjectRule(Predicates.<LogicalProject>alwaysTrue());
-
-        private static final PhoenixClientProjectRule CONVERTIBLE = new 
PhoenixClientProjectRule(IS_CONVERTIBLE);
+        private static final PhoenixClientProjectRule SERVERJOIN =
+                new PhoenixClientProjectRule(
+                        Predicates.<LogicalProject>alwaysTrue(),
+                        PhoenixConvention.SERVERJOIN);
+        private static final PhoenixClientProjectRule CLIENT =
+                new PhoenixClientProjectRule(
+                        Predicates.<LogicalProject>alwaysTrue(),
+                        PhoenixConvention.CLIENT);
+        private static final PhoenixClientProjectRule CONVERTIBLE_SERVERJOIN =
+                new PhoenixClientProjectRule(
+                        IS_CONVERTIBLE,
+                        PhoenixConvention.SERVERJOIN);
+        private static final PhoenixClientProjectRule CONVERTIBLE_CLIENT =
+                new PhoenixClientProjectRule(
+                        IS_CONVERTIBLE,
+                        PhoenixConvention.CLIENT);
+        
+        private final Convention inputConvention;
 
-        private PhoenixClientProjectRule(Predicate<LogicalProject> predicate) {
+        private PhoenixClientProjectRule(Predicate<LogicalProject> predicate, 
Convention inputConvention) {
             super(LogicalProject.class, predicate, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, "PhoenixClientProjectRule");
+                    PhoenixConvention.CLIENT,
+                    "PhoenixClientProjectRule:" + inputConvention);
+            this.inputConvention = inputConvention;
         }
 
         public RelNode convert(RelNode rel) {
@@ -314,7 +332,7 @@ public class PhoenixConverterRules {
             return PhoenixClientProject.create(
                 convert(
                         project.getInput(), 
-                        
project.getInput().getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)), 
+                        
project.getInput().getTraitSet().replace(inputConvention)), 
                 project.getProjects(),
                 project.getRowType());
         }
@@ -339,7 +357,7 @@ public class PhoenixConverterRules {
 
         private PhoenixServerProjectRule(Predicate<LogicalProject> predicate) {
             super(LogicalProject.class, predicate, Convention.NONE, 
-                    PhoenixRel.SERVER_CONVENTION, "PhoenixServerProjectRule");
+                    PhoenixConvention.SERVER, "PhoenixServerProjectRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -347,7 +365,7 @@ public class PhoenixConverterRules {
             return PhoenixServerProject.create(
                 convert(
                         project.getInput(), 
-                        
project.getInput().getTraitSet().replace(PhoenixRel.SERVER_CONVENTION)), 
+                        
project.getInput().getTraitSet().replace(PhoenixConvention.SERVER)), 
                 project.getProjects(),
                 project.getRowType());
         }
@@ -372,7 +390,7 @@ public class PhoenixConverterRules {
 
         private PhoenixClientAggregateRule(Predicate<LogicalAggregate> 
predicate) {
             super(LogicalAggregate.class, predicate, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, 
"PhoenixClientAggregateRule");
+                    PhoenixConvention.CLIENT, "PhoenixClientAggregateRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -380,7 +398,7 @@ public class PhoenixConverterRules {
             return PhoenixClientAggregate.create(
                     convert(
                             agg.getInput(), 
-                            
agg.getInput().getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)),
+                            
agg.getInput().getTraitSet().replace(PhoenixConvention.CLIENT)),
                     agg.indicator,
                     agg.getGroupSet(),
                     agg.getGroupSets(),
@@ -401,17 +419,17 @@ public class PhoenixConverterRules {
             }            
         };
         
-        public static final RelOptRule SERVER = new 
PhoenixServerAggregateRule(Predicates.<LogicalAggregate>alwaysTrue(), 
PhoenixRel.SERVER_CONVENTION);
-        public static final RelOptRule SERVERJOIN = new 
PhoenixServerAggregateRule(Predicates.<LogicalAggregate>alwaysTrue(), 
PhoenixRel.SERVERJOIN_CONVENTION);
+        public static final RelOptRule SERVER = new 
PhoenixServerAggregateRule(Predicates.<LogicalAggregate>alwaysTrue(), 
PhoenixConvention.SERVER);
+        public static final RelOptRule SERVERJOIN = new 
PhoenixServerAggregateRule(Predicates.<LogicalAggregate>alwaysTrue(), 
PhoenixConvention.SERVERJOIN);
 
-        public static final RelOptRule CONVERTIBLE_SERVER = new 
PhoenixServerAggregateRule(IS_CONVERTIBLE, PhoenixRel.SERVER_CONVENTION);
-        public static final RelOptRule CONVERTIBLE_SERVERJOIN = new 
PhoenixServerAggregateRule(IS_CONVERTIBLE, PhoenixRel.SERVERJOIN_CONVENTION);
+        public static final RelOptRule CONVERTIBLE_SERVER = new 
PhoenixServerAggregateRule(IS_CONVERTIBLE, PhoenixConvention.SERVER);
+        public static final RelOptRule CONVERTIBLE_SERVERJOIN = new 
PhoenixServerAggregateRule(IS_CONVERTIBLE, PhoenixConvention.SERVERJOIN);
         
         private final Convention inputConvention;
 
         private PhoenixServerAggregateRule(Predicate<LogicalAggregate> 
predicate, Convention inputConvention) {
             super(LogicalAggregate.class, predicate, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, 
"PhoenixServerAggregateRule:" + inputConvention.getName());
+                    PhoenixConvention.CLIENT, "PhoenixServerAggregateRule:" + 
inputConvention.getName());
             this.inputConvention = inputConvention;
         }
 
@@ -446,13 +464,13 @@ public class PhoenixConverterRules {
 
         private PhoenixUnionRule(Predicate<LogicalUnion> predicate) {
             super(LogicalUnion.class, predicate, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, "PhoenixUnionRule");
+                    PhoenixConvention.CLIENT, "PhoenixUnionRule");
         }
 
         public RelNode convert(RelNode rel) {
             final LogicalUnion union = (LogicalUnion) rel;
             return PhoenixUnion.create(
-                    convertList(union.getInputs(), out),
+                    convertList(union.getInputs(), PhoenixConvention.GENERIC),
                     union.all);
         }
     }
@@ -483,7 +501,7 @@ public class PhoenixConverterRules {
 
         private PhoenixClientJoinRule(Predicate<LogicalJoin> predicate) {
             super(LogicalJoin.class, predicate, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, "PhoenixClientJoinRule");
+                    PhoenixConvention.CLIENT, "PhoenixClientJoinRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -511,10 +529,10 @@ public class PhoenixConverterRules {
             return PhoenixClientJoin.create(
                     convert(
                             left, 
-                            
left.getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)),
+                            
left.getTraitSet().replace(PhoenixConvention.GENERIC)),
                     convert(
                             right, 
-                            
right.getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)),
+                            
right.getTraitSet().replace(PhoenixConvention.GENERIC)),
                     join.getCondition(),
                     join.getJoinType(),
                     join.getVariablesStopped(),
@@ -548,7 +566,7 @@ public class PhoenixConverterRules {
 
         private PhoenixServerJoinRule(Predicate<LogicalJoin> predicate) {
             super(LogicalJoin.class, predicate, Convention.NONE, 
-                    PhoenixRel.SERVERJOIN_CONVENTION, "PhoenixServerJoinRule");
+                    PhoenixConvention.SERVERJOIN, "PhoenixServerJoinRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -556,10 +574,10 @@ public class PhoenixConverterRules {
             return PhoenixServerJoin.create(
                     convert(
                             join.getLeft(), 
-                            
join.getLeft().getTraitSet().replace(PhoenixRel.SERVER_CONVENTION)),
+                            
join.getLeft().getTraitSet().replace(PhoenixConvention.SERVER)),
                     convert(
                             join.getRight(), 
-                            
join.getRight().getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)),
+                            
join.getRight().getTraitSet().replace(PhoenixConvention.GENERIC)),
                     join.getCondition(),
                     join.getJoinType(),
                     join.getVariablesStopped(),
@@ -577,7 +595,7 @@ public class PhoenixConverterRules {
 
         private PhoenixClientSemiJoinRule() {
             super(SemiJoin.class, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, "PhoenixClientSemiJoinRule");
+                    PhoenixConvention.CLIENT, "PhoenixClientSemiJoinRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -605,10 +623,10 @@ public class PhoenixConverterRules {
             return PhoenixClientSemiJoin.create(
                     convert(
                             left, 
-                            
left.getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)),
+                            
left.getTraitSet().replace(PhoenixConvention.GENERIC)),
                     convert(
                             right, 
-                            
right.getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)),
+                            
right.getTraitSet().replace(PhoenixConvention.GENERIC)),
                     join.getCondition());
         }
     }
@@ -623,7 +641,7 @@ public class PhoenixConverterRules {
 
         private PhoenixServerSemiJoinRule() {
             super(SemiJoin.class, Convention.NONE, 
-                    PhoenixRel.SERVERJOIN_CONVENTION, 
"PhoenixServerSemiJoinRule");
+                    PhoenixConvention.SERVERJOIN, "PhoenixServerSemiJoinRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -631,10 +649,10 @@ public class PhoenixConverterRules {
             return PhoenixServerSemiJoin.create(
                     convert(
                             join.getLeft(), 
-                            
join.getLeft().getTraitSet().replace(PhoenixRel.SERVER_CONVENTION)),
+                            
join.getLeft().getTraitSet().replace(PhoenixConvention.SERVER)),
                     convert(
                             join.getRight(), 
-                            
join.getRight().getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)),
+                            
join.getRight().getTraitSet().replace(PhoenixConvention.GENERIC)),
                     join.getCondition());
         }
     }
@@ -647,7 +665,7 @@ public class PhoenixConverterRules {
         public static PhoenixValuesRule INSTANCE = new PhoenixValuesRule();
         
         private PhoenixValuesRule() {
-            super(LogicalValues.class, Convention.NONE, 
PhoenixRel.CLIENT_CONVENTION, "PhoenixValuesRule");
+            super(LogicalValues.class, Convention.NONE, 
PhoenixConvention.CLIENT, "PhoenixValuesRule");
         }
 
         @Override public RelNode convert(RelNode rel) {
@@ -669,7 +687,7 @@ public class PhoenixConverterRules {
 
         private PhoenixUncollectRule() {
             super(Uncollect.class, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, "PhoenixUncollectRule");
+                    PhoenixConvention.CLIENT, "PhoenixUncollectRule");
         }
 
         public RelNode convert(RelNode rel) {
@@ -677,7 +695,7 @@ public class PhoenixConverterRules {
             return PhoenixUncollect.create(
                 convert(
                         uncollect.getInput(), 
-                        uncollect.getInput().getTraitSet().replace(out)));
+                        
uncollect.getInput().getTraitSet().replace(PhoenixConvention.GENERIC)));
         }
     }
 
@@ -691,16 +709,16 @@ public class PhoenixConverterRules {
 
         private PhoenixCorrelateRule() {
             super(LogicalCorrelate.class, Convention.NONE, 
-                    PhoenixRel.CLIENT_CONVENTION, "PhoenixCorrelateRule");
+                    PhoenixConvention.CLIENT, "PhoenixCorrelateRule");
         }
 
         public RelNode convert(RelNode rel) {
             final Correlate correlate = (Correlate) rel;
             return PhoenixCorrelate.create(
                 convert(correlate.getLeft(), 
-                        correlate.getLeft().getTraitSet().replace(out)),
+                        
correlate.getLeft().getTraitSet().replace(PhoenixConvention.GENERIC)),
                 convert(correlate.getRight(), 
-                        correlate.getRight().getTraitSet().replace(out)),
+                        
correlate.getRight().getTraitSet().replace(PhoenixConvention.GENERIC)),
                 correlate.getCorrelationId(),
                 correlate.getRequiredColumns(),
                 correlate.getJoinType());
@@ -809,57 +827,24 @@ public class PhoenixConverterRules {
      }
      }
      */
+    
 
     /**
      * Rule to convert a relational expression from
-     * {@link org.apache.phoenix.calcite.rel.PhoenixRel#SERVER_CONVENTION} to
-     * {@link org.apache.phoenix.calcite.rel.PhoenixRel#CLIENT_CONVENTION}.
-     */
-    public static class PhoenixServerToClientConverterRule extends 
ConverterRule {
-        public static final ConverterRule INSTANCE =
-            new PhoenixServerToClientConverterRule();
-
-        private PhoenixServerToClientConverterRule() {
-            super(RelNode.class, PhoenixRel.SERVER_CONVENTION, 
PhoenixRel.CLIENT_CONVENTION,
-                "PhoenixServerToClientConverterRule");
-        }
-
-        @Override public RelNode convert(RelNode rel) {
-            return PhoenixToClientConverter.create(rel);
-        }
-    }
-
-    /**
-     * Rule to convert a relational expression from
-     * {@link org.apache.phoenix.calcite.rel.PhoenixRel#SERVERJOIN_CONVENTION} 
to
-     * {@link org.apache.phoenix.calcite.rel.PhoenixRel#CLIENT_CONVENTION}.
-     */
-    public static class PhoenixProjectableToClientConverterRule extends 
ConverterRule {
-        public static final ConverterRule INSTANCE =
-            new PhoenixProjectableToClientConverterRule();
-
-        private PhoenixProjectableToClientConverterRule() {
-            super(RelNode.class, PhoenixRel.SERVERJOIN_CONVENTION, 
PhoenixRel.CLIENT_CONVENTION,
-                "PhoenixProjectableToClientConverterRule");
-        }
-
-        @Override public RelNode convert(RelNode rel) {
-            return PhoenixToClientConverter.create(rel);
-        }
-    }
-
-    /**
-     * Rule to convert a relational expression from
-     * {@link org.apache.phoenix.calcite.rel.PhoenixRel#CONVENTION} to
+     * {@link org.apache.phoenix.calcite.rel.PhoenixConvention} to
      * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention}.
      */
     public static class PhoenixToEnumerableConverterRule extends ConverterRule 
{
-        public static final ConverterRule INSTANCE =
-            new PhoenixToEnumerableConverterRule();
-
-        private PhoenixToEnumerableConverterRule() {
-            super(RelNode.class, PhoenixRel.CLIENT_CONVENTION, 
EnumerableConvention.INSTANCE,
-                "PhoenixToEnumerableConverterRule");
+        public static final ConverterRule SERVER =
+                new PhoenixToEnumerableConverterRule(PhoenixConvention.SERVER);
+        public static final ConverterRule SERVERJOIN =
+                new 
PhoenixToEnumerableConverterRule(PhoenixConvention.SERVERJOIN);
+        public static final ConverterRule CLIENT =
+                new PhoenixToEnumerableConverterRule(PhoenixConvention.CLIENT);
+
+        private PhoenixToEnumerableConverterRule(Convention inputConvention) {
+            super(RelNode.class, inputConvention, 
EnumerableConvention.INSTANCE,
+                "PhoenixToEnumerableConverterRule:" + inputConvention);
         }
 
         @Override public RelNode convert(RelNode rel) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/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 ba303a6..a6f3a59 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
@@ -5,16 +5,19 @@ import com.google.common.base.Predicate;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.logical.LogicalFilter;
 import org.apache.phoenix.calcite.rel.PhoenixTableScan;
+import org.apache.phoenix.calcite.rel.PhoenixTableScan.ScanOrder;
 
 public class PhoenixFilterScanMergeRule extends RelOptRule {
 
-    /** Predicate that returns true if a table scan has no filter. */
-    private static final Predicate<PhoenixTableScan> NO_FILTER =
+    /** Predicate that returns true if a table scan has no filter and is not 
reverse scan. */
+    private static final Predicate<PhoenixTableScan> APPLICABLE_TABLE_SCAN =
             new Predicate<PhoenixTableScan>() {
         @Override
         public boolean apply(PhoenixTableScan phoenixTableScan) {
-            return phoenixTableScan.filter == null;
+            return phoenixTableScan.filter == null
+                    && phoenixTableScan.scanOrder != ScanOrder.REVERSE;
         }
     };
 
@@ -31,16 +34,16 @@ public class PhoenixFilterScanMergeRule extends RelOptRule {
 
     private PhoenixFilterScanMergeRule() {
         super(
-            operand(Filter.class, null, IS_CONVERTIBLE,
-                operand(PhoenixTableScan.class, null, NO_FILTER, any())));
+            operand(LogicalFilter.class, null, IS_CONVERTIBLE,
+                operand(PhoenixTableScan.class, null, APPLICABLE_TABLE_SCAN, 
any())));
     }
 
     @Override
     public void onMatch(RelOptRuleCall call) {
-        Filter filter = call.rel(0);
+        LogicalFilter filter = call.rel(0);
         PhoenixTableScan scan = call.rel(1);
         assert scan.filter == null : "predicate should have ensured no filter";
         call.transformTo(PhoenixTableScan.create(
-                scan.getCluster(), scan.getTable(), filter.getCondition()));
+                scan.getCluster(), scan.getTable(), filter.getCondition(), 
scan.scanOrder));
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixForwardTableScanRule.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixForwardTableScanRule.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixForwardTableScanRule.java
new file mode 100644
index 0000000..b38324c
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixForwardTableScanRule.java
@@ -0,0 +1,58 @@
+package org.apache.phoenix.calcite.rules;
+
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Sort;
+import org.apache.phoenix.calcite.rel.PhoenixTableScan;
+import org.apache.phoenix.calcite.rel.PhoenixTableScan.ScanOrder;
+
+import com.google.common.base.Predicate;
+
+public class PhoenixForwardTableScanRule extends RelOptRule {
+    private static final Predicate<Sort> NON_EMPTY_COLLATION =
+            new Predicate<Sort>() {
+        @Override
+        public boolean apply(Sort input) {
+            return !input.getCollation().getFieldCollations().isEmpty();
+        }
+    };
+    
+    private static final Predicate<PhoenixTableScan> APPLICABLE_TABLE_SCAN =
+            new Predicate<PhoenixTableScan>() {
+        @Override
+        public boolean apply(PhoenixTableScan input) {
+            return input.scanOrder == ScanOrder.NONE;
+        }
+    };
+
+    public PhoenixForwardTableScanRule(Class<? extends Sort> sortClass) {
+        super(operand(sortClass, null, NON_EMPTY_COLLATION,
+                operand(PhoenixTableScan.class, null, APPLICABLE_TABLE_SCAN, 
any())),
+            PhoenixForwardTableScanRule.class.getName() + ":" + 
sortClass.getName());
+    }
+
+    @Override
+    public void onMatch(RelOptRuleCall call) {
+        final Sort sort = call.rel(0);
+        final PhoenixTableScan scan = call.rel(1);
+        final RelCollation collation = sort.getCollation();
+        assert !collation.getFieldCollations().isEmpty();
+        for (RelCollation candidate : scan.getTable().getCollationList()) {
+            if (candidate.satisfies(collation)) {
+                RelNode newRel = PhoenixTableScan.create(
+                        scan.getCluster(), scan.getTable(), scan.filter, 
ScanOrder.FORWARD);
+                if (sort.offset != null || sort.fetch != null) {
+                    newRel = sort.copy(
+                            sort.getTraitSet().replace(RelCollations.EMPTY),
+                            newRel, RelCollations.EMPTY, sort.offset, 
sort.fetch);
+                }
+                call.transformTo(newRel);
+                break;
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixJoinSingleValueAggregateMergeRule.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixJoinSingleValueAggregateMergeRule.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixJoinSingleValueAggregateMergeRule.java
index a3a1d63..bf010ce 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixJoinSingleValueAggregateMergeRule.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixJoinSingleValueAggregateMergeRule.java
@@ -6,6 +6,7 @@ import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.phoenix.calcite.rel.PhoenixAbstractAggregate;
 import org.apache.phoenix.calcite.rel.PhoenixAbstractJoin;
+import org.apache.phoenix.calcite.rel.PhoenixConvention;
 import org.apache.phoenix.calcite.rel.PhoenixRel;
 
 import com.google.common.base.Predicate;
@@ -60,7 +61,7 @@ public class PhoenixJoinSingleValueAggregateMergeRule extends 
RelOptRule {
         }
         
         call.transformTo(join.copy(join.getTraitSet(), join.getCondition(), 
-                left, convert(right.getInput(), 
right.getInput().getTraitSet().replace(PhoenixRel.CLIENT_CONVENTION)), 
join.getJoinType(), false, true));
+                left, convert(right.getInput(), 
right.getInput().getTraitSet().replace(PhoenixConvention.GENERIC)), 
join.getJoinType(), false, true));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixOrderedAggregateRule.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixOrderedAggregateRule.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixOrderedAggregateRule.java
index 286d58d..25d7138 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixOrderedAggregateRule.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixOrderedAggregateRule.java
@@ -5,25 +5,24 @@ import java.util.List;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
 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.RelNode;
+import org.apache.calcite.rel.logical.LogicalSort;
 import org.apache.phoenix.calcite.rel.PhoenixAbstractAggregate;
-import org.apache.phoenix.calcite.rel.PhoenixRel;
 
 import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
 
 /**
  * Phoenix rule that transforms an unordered Aggregate into an ordered 
Aggregate.
  * 
- * The Aggregate's child could have a collation that matches the groupSet and 
thus
- * makes the Aggregate ordered, but the Aggregate wouldn't know this matching 
- * collation if its child resides in a RelSubset with an empty collation.
- * An option would be to use conversion rules that create a subset of a 
specific
- * collation. But since there are so many potential collations that can match 
the
- * groupSet and most of them are meaningless for the actual child expression, 
we
- * do not want to make this rule a ConvertRule.
- * Instead, we surface the matching child expression by using RelOptRule and
- * reconstruct a new Aggregate with this child.
+ * An Aggregate can turn into an ordered Aggregate (stream Aggregate) if its 
child
+ * is ordered on the fields of the groupSet, and the collation fields can come 
in
+ * as an arbitrary permutation of the groupSet fields with either ascending or
+ * descending direction. That said, there could be many possible collations of 
a
+ * child that will qualify an ordered Aggregate, but in order to keep the 
search
+ * space reasonable, we will pick the most promising one(s) in this rule.
  */
 public class PhoenixOrderedAggregateRule extends RelOptRule {
     
@@ -35,43 +34,24 @@ public class PhoenixOrderedAggregateRule extends RelOptRule 
{
                 }
     };
     
-    private static Predicate<PhoenixRel> NON_EMPTY_COLLATION =
-            new Predicate<PhoenixRel>() {
-                @Override
-                public boolean apply(PhoenixRel input) {
-                    if (input.getConvention() != PhoenixRel.SERVER_CONVENTION
-                            && input.getConvention() != 
PhoenixRel.SERVERJOIN_CONVENTION)
-                        return false;
-                    
-                    List<RelCollation> collations = 
input.getTraitSet().getTraits(RelCollationTraitDef.INSTANCE);
-                    for (RelCollation collation : collations) {
-                        if (!collation.getFieldCollations().isEmpty()) {
-                            return true;
-                        }
-                    }
-                    return false;
-                }
-    };
-    
     public static final PhoenixOrderedAggregateRule INSTANCE = new 
PhoenixOrderedAggregateRule();
     
     public PhoenixOrderedAggregateRule() {
-        super(operand(PhoenixAbstractAggregate.class, null, UNORDERED_GROUPBY,
-                operand(PhoenixRel.class, null, NON_EMPTY_COLLATION, any())));
-    }
-    
-    @Override
-    public boolean matches(RelOptRuleCall call) {
-        PhoenixAbstractAggregate agg = call.rel(0);
-        RelNode child = call.rel(1);
-        return PhoenixAbstractAggregate.isOrderedGroupSet(agg.getGroupSet(), 
child);
+        super(operand(PhoenixAbstractAggregate.class, null, UNORDERED_GROUPBY, 
any()));
     }
 
     @Override
     public void onMatch(RelOptRuleCall call) {
         PhoenixAbstractAggregate agg = call.rel(0);
-        RelNode child = call.rel(1);
-        call.transformTo(agg.copy(agg.getTraitSet(), child, agg.indicator, 
agg.getGroupSet(), agg.groupSets, agg.getAggCallList()));
+        List<RelFieldCollation> fieldCollations = Lists.newArrayList();
+        for (Integer ordinal : agg.getGroupSet().asList()) {
+            fieldCollations.add(new RelFieldCollation(ordinal));
+        }
+        RelCollation collation = RelCollations.of(fieldCollations);
+        RelNode newInput = convert(
+                LogicalSort.create(agg.getInput(), collation, null, null),
+                agg.getInput().getConvention());
+        call.transformTo(agg.copy(agg.getTraitSet(), newInput, agg.indicator, 
agg.getGroupSet(), agg.groupSets, agg.getAggCallList()));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixReverseTableScanRule.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixReverseTableScanRule.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixReverseTableScanRule.java
new file mode 100644
index 0000000..0a6f000
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixReverseTableScanRule.java
@@ -0,0 +1,62 @@
+package org.apache.phoenix.calcite.rules;
+
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Sort;
+import org.apache.phoenix.calcite.CalciteUtils;
+import org.apache.phoenix.calcite.rel.PhoenixTableScan;
+import org.apache.phoenix.calcite.rel.PhoenixTableScan.ScanOrder;
+
+import com.google.common.base.Predicate;
+
+public class PhoenixReverseTableScanRule extends RelOptRule {    
+    private static final Predicate<Sort> NON_EMPTY_COLLATION =
+            new Predicate<Sort>() {
+        @Override
+        public boolean apply(Sort input) {
+            return !input.getCollation().getFieldCollations().isEmpty();
+        }
+    };
+    
+    private static final Predicate<PhoenixTableScan> APPLICABLE_TABLE_SCAN =
+            new Predicate<PhoenixTableScan>() {
+        @Override
+        public boolean apply(PhoenixTableScan input) {
+            return input.scanOrder != ScanOrder.REVERSE
+                    && input.isReverseScanEnabled()
+                    && (input.scanRanges == null
+                        || !input.scanRanges.useSkipScanFilter());
+        }
+    };
+
+    public PhoenixReverseTableScanRule(Class<? extends Sort> sortClass) {
+        super(operand(sortClass, null, NON_EMPTY_COLLATION,
+                operand(PhoenixTableScan.class, null, APPLICABLE_TABLE_SCAN, 
any())),
+            PhoenixReverseTableScanRule.class.getName() + ":" + 
sortClass.getName());
+    }
+
+    @Override
+    public void onMatch(RelOptRuleCall call) {
+        final Sort sort = call.rel(0);
+        final PhoenixTableScan scan = call.rel(1);
+        final RelCollation collation = sort.getCollation();
+        assert !collation.getFieldCollations().isEmpty();
+        for (RelCollation candidate : scan.getTable().getCollationList()) {
+            if (CalciteUtils.reverseCollation(candidate).satisfies(collation)) 
{
+                RelNode newRel = PhoenixTableScan.create(
+                        scan.getCluster(), scan.getTable(), scan.filter, 
ScanOrder.REVERSE);
+                if (sort.offset != null || sort.fetch != null) {
+                    newRel = sort.copy(
+                            sort.getTraitSet().replace(RelCollations.EMPTY),
+                            newRel, RelCollations.EMPTY, sort.offset, 
sort.fetch);
+                }
+                call.transformTo(newRel);
+                break;
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixSortServerJoinTransposeRule.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixSortServerJoinTransposeRule.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixSortServerJoinTransposeRule.java
new file mode 100644
index 0000000..cd34a3e
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixSortServerJoinTransposeRule.java
@@ -0,0 +1,65 @@
+package org.apache.phoenix.calcite.rules;
+
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.metadata.RelMdUtil;
+import org.apache.phoenix.calcite.rel.PhoenixConvention;
+import org.apache.phoenix.calcite.rel.PhoenixServerJoin;
+import org.apache.phoenix.calcite.rel.PhoenixServerSort;
+import org.apache.phoenix.calcite.rel.PhoenixTemporarySort;
+
+import com.google.common.base.Predicate;
+
+public class PhoenixSortServerJoinTransposeRule extends RelOptRule {
+    private static final Predicate<Join> INNER_OR_LEFT = new Predicate<Join>() 
{
+        @Override
+        public boolean apply(Join input) {
+            return input.getJoinType() == JoinRelType.INNER
+                    || input.getJoinType() == JoinRelType.LEFT;
+        }        
+    };
+    
+    public static final PhoenixSortServerJoinTransposeRule INSTANCE =
+            new PhoenixSortServerJoinTransposeRule();
+
+    public PhoenixSortServerJoinTransposeRule() {
+        super(operand(PhoenixServerSort.class,
+                operand(PhoenixServerJoin.class, null, INNER_OR_LEFT, any())));
+    }
+
+    @Override public boolean matches(RelOptRuleCall call) {
+        final PhoenixServerSort sort = call.rel(0);
+        final PhoenixServerJoin join = call.rel(1);
+        if 
(!join.getLeft().getConvention().satisfies(PhoenixConvention.SERVER)) {
+            return false;
+        }
+        for (RelFieldCollation relFieldCollation
+                : sort.getCollation().getFieldCollations()) {
+            if (relFieldCollation.getFieldIndex()
+                    >= join.getLeft().getRowType().getFieldCount()) {
+                return false;
+            }
+        }
+        if (RelMdUtil.checkInputForCollationAndLimit(
+                join.getLeft(), sort.getCollation(), null, null)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override public void onMatch(RelOptRuleCall call) {
+      final PhoenixServerSort sort = call.rel(0);
+      final PhoenixServerJoin join = call.rel(1);
+      final RelNode newLeftInput = PhoenixTemporarySort.create(
+              join.getLeft(), sort.getCollation());
+      final RelNode newRel = join.copy(join.getTraitSet(), join.getCondition(),
+              newLeftInput, join.getRight(), join.getJoinType(), 
join.isSemiJoinDone());
+
+      call.transformTo(newRel);
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java 
b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
index c80d9c5..7b76a2b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
@@ -84,8 +84,6 @@ public class ScanUtil {
         Arrays.fill(MAX_FILL_LENGTH_FOR_PREVIOUS_KEY, (byte)-1);
     }
     private static final byte[] ZERO_BYTE_ARRAY = new byte[1024];
-    
-    private static final String FORCE_ROW_KEY_ORDER = "_ForceRowKeyOrder";
 
     private ScanUtil() {
     }
@@ -736,14 +734,9 @@ public class ScanUtil {
         return fetchSize > 1 && !shouldRowsBeInRowKeyOrder(orderBy, context) 
&& orderBy.getOrderByExpressions().isEmpty();
     }
     
-    public static void setForceRowKeyOrder(Scan scan) {
-        scan.setAttribute(FORCE_ROW_KEY_ORDER, 
Bytes.toBytes(Boolean.TRUE.toString()));
-    }
-    
     public static boolean forceRowKeyOrder(StatementContext context) {
-        return context.getScan().getAttribute(FORCE_ROW_KEY_ORDER) != null
-                && context.getConnection().getQueryServices().getProps()
-                    .getBoolean(QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB, 
QueryServicesOptions.DEFAULT_FORCE_ROW_KEY_ORDER);
+        return context.getConnection().getQueryServices().getProps()
+                .getBoolean(QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB, 
QueryServicesOptions.DEFAULT_FORCE_ROW_KEY_ORDER);
     }
     
     public static boolean shouldRowsBeInRowKeyOrder(OrderBy orderBy, 
StatementContext context) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/phoenix-core/src/test/java/org/apache/phoenix/calcite/ToExpressionTest.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/calcite/ToExpressionTest.java 
b/phoenix-core/src/test/java/org/apache/phoenix/calcite/ToExpressionTest.java
index bd239bd..3734b4c 100644
--- 
a/phoenix-core/src/test/java/org/apache/phoenix/calcite/ToExpressionTest.java
+++ 
b/phoenix-core/src/test/java/org/apache/phoenix/calcite/ToExpressionTest.java
@@ -165,7 +165,7 @@ public class ToExpressionTest extends 
BaseConnectionlessQueryTest {
                 return null;
             
             PTable table = rootTables.get(name);
-            return new PhoenixTable(pc, table, true);
+            return new PhoenixTable(pc, table);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/50e4406d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 38acce1..079c6c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -109,7 +109,7 @@
     <collections.version>3.2.1</collections.version>
     <jodatime.version>2.7</jodatime.version>
     <joni.version>2.1.2</joni.version>
-    <calcite.version>1.5.0-incubating-SNAPSHOT</calcite.version>
+    <calcite.version>1.6.0-SNAPSHOT</calcite.version>
 
     <!-- Test Dependencies -->
     <mockito-all.version>1.8.5</mockito-all.version>

Reply via email to