You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2015/06/19 02:43:25 UTC

incubator-kylin git commit: KYLIN-780 convert EnumerableRel then gen java code with clear debug info

Repository: incubator-kylin
Updated Branches:
  refs/heads/KYLIN-780 3e1ea920c -> 9ebb9bca0


KYLIN-780 convert EnumerableRel then gen java code with clear debug info


Project: http://git-wip-us.apache.org/repos/asf/incubator-kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-kylin/commit/9ebb9bca
Tree: http://git-wip-us.apache.org/repos/asf/incubator-kylin/tree/9ebb9bca
Diff: http://git-wip-us.apache.org/repos/asf/incubator-kylin/diff/9ebb9bca

Branch: refs/heads/KYLIN-780
Commit: 9ebb9bca0a40bf703023373edb95791a5cdee466
Parents: 3e1ea92
Author: Yang Li <li...@apache.org>
Authored: Fri Jun 19 08:43:03 2015 +0800
Committer: Yang Li <li...@apache.org>
Committed: Fri Jun 19 08:43:03 2015 +0800

----------------------------------------------------------------------
 .../kylin/query/relnode/OLAPAggregateRel.java   | 18 ++++------
 .../kylin/query/relnode/OLAPFilterRel.java      | 11 +++---
 .../apache/kylin/query/relnode/OLAPJoinRel.java | 26 +++++++++-----
 .../kylin/query/relnode/OLAPLimitRel.java       | 17 +++------
 .../kylin/query/relnode/OLAPProjectRel.java     | 29 +++++++--------
 .../org/apache/kylin/query/relnode/OLAPRel.java | 38 +++++++++++++++-----
 .../apache/kylin/query/relnode/OLAPSortRel.java | 21 ++++-------
 .../kylin/query/relnode/OLAPTableScan.java      | 19 +++++-----
 .../relnode/OLAPToEnumerableConverter.java      | 20 ++++++-----
 9 files changed, 101 insertions(+), 98 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java
index 2d22168..c75ad88 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java
@@ -27,7 +27,6 @@ import java.util.Set;
 import org.apache.calcite.adapter.enumerable.EnumerableAggregate;
 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.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
@@ -54,7 +53,6 @@ import org.apache.calcite.sql.type.SqlTypeFamily;
 import org.apache.calcite.sql.validate.SqlUserDefinedAggFunction;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.calcite.util.Util;
-import org.apache.kylin.common.util.ClassUtil;
 import org.apache.kylin.metadata.model.ColumnDesc;
 import org.apache.kylin.metadata.model.FunctionDesc;
 import org.apache.kylin.metadata.model.ParameterDesc;
@@ -66,7 +64,7 @@ import com.google.common.base.Preconditions;
 
 /**
  */
-public class OLAPAggregateRel extends Aggregate implements OLAPRel, EnumerableRel {
+public class OLAPAggregateRel extends Aggregate implements OLAPRel {
 
     private final static Map<String, String> AGGR_FUNC_MAP = new HashMap<String, String>();
 
@@ -282,8 +280,8 @@ public class OLAPAggregateRel extends Aggregate implements OLAPRel, EnumerableRe
         }
 
         // rebuild rowType & columnRowType
-        ClassUtil.updateFinalField(Aggregate.class, "aggCalls", this, rewriteAggCalls);
-        this.rowType = this.deriveRowType();
+        //ClassUtil.updateFinalField(Aggregate.class, "aggCalls", this, rewriteAggCalls);
+        this.rowType = this.deriveRowType(); // this does not work coz super.aggCalls is final
         this.columnRowType = this.buildColumnRowType();
 
     }
@@ -325,17 +323,13 @@ public class OLAPAggregateRel extends Aggregate implements OLAPRel, EnumerableRe
     }
 
     @Override
-    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
-
-        EnumerableAggregate enumAggRel;
+    public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
         try {
-            enumAggRel = new EnumerableAggregate(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), getInput(), false, this.groupSet, this.groupSets, rewriteAggCalls);
+            return new EnumerableAggregate(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
+                    sole(inputs), false, this.groupSet, this.groupSets, rewriteAggCalls);
         } catch (InvalidRelException e) {
             throw new IllegalStateException("Can't create EnumerableAggregate!", e);
         }
-
-        ((OLAPRel.JavaImplementor) implementor).putParentContextForTableScanChild(this, enumAggRel);
-        return enumAggRel.implement(implementor, pref);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
index 16f5772..48c1075 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
@@ -27,7 +27,6 @@ import java.util.Set;
 import org.apache.calcite.adapter.enumerable.EnumerableCalc;
 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.avatica.util.TimeUnitRange;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
@@ -68,7 +67,7 @@ import com.google.common.collect.Sets;
 
 /**
  */
-public class OLAPFilterRel extends Filter implements OLAPRel, EnumerableRel {
+public class OLAPFilterRel extends Filter implements OLAPRel {
 
     private static class TupleFilterVisitor extends RexVisitorImpl<TupleFilter> {
 
@@ -298,7 +297,7 @@ public class OLAPFilterRel extends Filter implements OLAPRel, EnumerableRel {
     }
 
     @Override
-    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+    public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
         // keep it for having clause
         RexBuilder rexBuilder = getCluster().getRexBuilder();
         RelDataType inputRowType = getInput().getRowType();
@@ -307,10 +306,8 @@ public class OLAPFilterRel extends Filter implements OLAPRel, EnumerableRel {
         programBuilder.addCondition(this.condition);
         RexProgram program = programBuilder.getProgram();
 
-        EnumerableCalc enumCalcRel = new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), getInput(), program, ImmutableList.<RelCollation> of());
-
-        ((OLAPRel.JavaImplementor) implementor).putParentContextForTableScanChild(this, enumCalcRel);
-        return enumCalcRel.implement(implementor, pref);
+        return new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
+                sole(inputs), program, ImmutableList.<RelCollation> of());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java
index 9a85f12..8de155c 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java
@@ -25,7 +25,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.calcite.adapter.enumerable.EnumerableConvention;
 import org.apache.calcite.adapter.enumerable.EnumerableJoin;
+import org.apache.calcite.adapter.enumerable.EnumerableRel;
 import org.apache.calcite.adapter.enumerable.EnumerableRelImplementor;
 import org.apache.calcite.adapter.enumerable.PhysType;
 import org.apache.calcite.adapter.enumerable.PhysTypeImpl;
@@ -225,19 +227,25 @@ public class OLAPJoinRel extends EnumerableJoin implements OLAPRel {
     }
 
     @Override
-    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
-        Result result = null;
+    public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
         if (this.hasSubQuery) {
-            ((OLAPRel.JavaImplementor) implementor).putParentContextForTableScanChild(this, this);
-            result = super.implement(implementor, pref);
+            try {
+                return new EnumerableJoin(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
+                        inputs.get(0), inputs.get(1), condition, leftKeys, rightKeys, joinType, variablesStopped);
+            } catch (InvalidRelException e) {
+                throw new IllegalStateException("Can't create EnumerableJoin!", e);
+            }
         } else {
-            PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), pref.preferArray());
-            RelOptTable factTable = context.firstTableScan.getTable();
-            MethodCallExpression exprCall = Expressions.call(factTable.getExpression(OLAPTable.class), "executeIndexQuery", implementor.getRootExpression(), Expressions.constant(context.id));
-            result = implementor.result(physType, Blocks.toBlock(exprCall));
+            return this;
         }
+    }
 
-        return result;
+    @Override
+    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+        PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), pref.preferArray());
+        RelOptTable factTable = context.firstTableScan.getTable();
+        MethodCallExpression exprCall = Expressions.call(factTable.getExpression(OLAPTable.class), "executeIndexQuery", implementor.getRootExpression(), Expressions.constant(context.id));
+        return implementor.result(physType, Blocks.toBlock(exprCall));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java
index b496054..a31cc21 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPLimitRel.java
@@ -23,7 +23,6 @@ import java.util.List;
 import org.apache.calcite.adapter.enumerable.EnumerableConvention;
 import org.apache.calcite.adapter.enumerable.EnumerableLimit;
 import org.apache.calcite.adapter.enumerable.EnumerableRel;
-import org.apache.calcite.adapter.enumerable.EnumerableRelImplementor;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
@@ -39,7 +38,7 @@ import com.google.common.base.Preconditions;
 
 /**
  */
-public class OLAPLimitRel extends SingleRel implements OLAPRel, EnumerableRel {
+public class OLAPLimitRel extends SingleRel implements OLAPRel {
 
     private final RexNode localOffset; // avoid same name in parent class
     private final RexNode localFetch; // avoid same name in parent class
@@ -96,17 +95,9 @@ public class OLAPLimitRel extends SingleRel implements OLAPRel, EnumerableRel {
     }
 
     @Override
-    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
-        OLAPRel childRel = (OLAPRel) getInput();
-        childRel.replaceTraitSet(EnumerableConvention.INSTANCE);
-
-        EnumerableLimit enumLimit = new EnumerableLimit(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), getInput(), localOffset, localFetch);
-        ((OLAPRel.JavaImplementor) implementor).putParentContextForTableScanChild(this, enumLimit);
-        Result res = enumLimit.implement(implementor, pref);
-
-        childRel.replaceTraitSet(CONVENTION);
-
-        return res;
+    public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
+        return new EnumerableLimit(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
+                sole(inputs), localOffset, localFetch);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
index b22d291..8f80962 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
@@ -28,7 +28,6 @@ import java.util.Set;
 import org.apache.calcite.adapter.enumerable.EnumerableCalc;
 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.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
@@ -58,7 +57,7 @@ import com.google.common.collect.ImmutableList;
 
 /**
  */
-public class OLAPProjectRel extends Project implements OLAPRel, EnumerableRel {
+public class OLAPProjectRel extends Project implements OLAPRel {
 
     private OLAPContext context;
     private List<RexNode> rewriteProjects;
@@ -208,25 +207,21 @@ public class OLAPProjectRel extends Project implements OLAPRel, EnumerableRel {
     }
 
     @Override
-    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
-        EnumerableCalc enumCalcRel;
-
-        RelNode child = getInput();
-        if (child instanceof OLAPFilterRel) {
+    public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
+        if (getInput() instanceof OLAPFilterRel) {
             // merge project & filter
             OLAPFilterRel filter = (OLAPFilterRel) getInput();
-            RexProgram program = RexProgram.create(filter.getInput().getRowType(), this.rewriteProjects, filter.getCondition(), this.rowType, getCluster().getRexBuilder());
-
-            enumCalcRel = new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), filter.getInput(), program, ImmutableList.<RelCollation> of());
+            RelNode inputOfFilter = inputs.get(0).getInput(0);
+            RexProgram program = RexProgram.create(inputOfFilter.getRowType(), this.rewriteProjects, filter.getCondition(), this.rowType, getCluster().getRexBuilder());
+            return new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
+                    inputOfFilter, program, ImmutableList.<RelCollation> of());
         } else {
-            // keep project for tablescan
-            RexProgram program = RexProgram.create(child.getRowType(), this.rewriteProjects, null, this.rowType, getCluster().getRexBuilder());
-
-            enumCalcRel = new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), child, program, ImmutableList.<RelCollation> of());
+            // keep project for table scan
+            EnumerableRel input = sole(inputs);
+            RexProgram program = RexProgram.create(input.getRowType(), this.rewriteProjects, null, this.rowType, getCluster().getRexBuilder());
+            return new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
+                    input, program, ImmutableList.<RelCollation> of());
         }
-
-        ((OLAPRel.JavaImplementor) implementor).putParentContextForTableScanChild(this, enumCalcRel);
-        return enumCalcRel.implement(implementor, pref);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPRel.java
index 974b95c..59179df 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPRel.java
@@ -18,8 +18,10 @@
 
 package org.apache.kylin.query.relnode;
 
+import java.util.ArrayList;
 import java.util.IdentityHashMap;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Stack;
 
 import org.apache.calcite.adapter.enumerable.EnumerableRel;
@@ -31,6 +33,7 @@ import org.apache.calcite.rel.RelNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
 /**
@@ -136,33 +139,52 @@ public interface OLAPRel extends RelNode {
      */
     public static class JavaImplementor extends EnumerableRelImplementor {
 
-        private IdentityHashMap<EnumerableRel, OLAPContext> parentContexts = Maps.newIdentityHashMap();
+        private IdentityHashMap<EnumerableRel, OLAPContext> relContexts = Maps.newIdentityHashMap();
         private boolean calciteDebug = System.getProperty("calcite.debug") != null;
 
         public JavaImplementor(EnumerableRelImplementor enumImplementor) {
             super(enumImplementor.getRexBuilder(), new LinkedHashMap<String, Object>());
         }
 
-        public void putParentContextForTableScanChild(OLAPRel olapParent, EnumerableRel enumParent) {
-            parentContexts.put(enumParent, olapParent.getContext());
+        public EnumerableRel createEnumerable(OLAPRel parent) {
+            ArrayList<EnumerableRel> enumInputs = null;
+            List<RelNode> children = parent.getInputs();
+            if (children != null) {
+                enumInputs = Lists.newArrayListWithCapacity(children.size());
+                for (RelNode child : children) {
+                    enumInputs.add(createEnumerable((OLAPRel) child));
+                }
+            }
+
+            EnumerableRel result = parent.implementEnumerable(enumInputs);
+            relContexts.put(result, parent.getContext());
+            return result;
         }
-        
+
         @Override
         public EnumerableRel.Result visitChild(EnumerableRel parent, int ordinal, EnumerableRel child, EnumerableRel.Prefer prefer) {
             // OLAPTableScan is shared instance when the same table appears multiple times in the tree.
             // Its context must be set (or corrected) right before visiting.
             if (child instanceof OLAPTableScan) {
-                OLAPContext parentContext = parentContexts.get(parent);
+                OLAPContext parentContext = relContexts.get(parent);
                 if (parentContext != null) {
                     ((OLAPTableScan) child).overrideContext(parentContext);
                 }
             }
-            if (calciteDebug && child instanceof OLAPRel) {
-                OLAPRel olapRel = (OLAPRel) child;
-                System.out.println(olapRel.getContext() + " - " + olapRel);
+
+            if (calciteDebug) {
+                OLAPContext context;
+                if (child instanceof OLAPRel)
+                    context = ((OLAPRel) child).getContext();
+                else
+                    context = relContexts.get(child);
+                System.out.println(context + " - " + child);
             }
+
             return super.visitChild(parent, ordinal, child, prefer);
         }
     }
 
+    public EnumerableRel implementEnumerable(List<EnumerableRel> inputs);
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPSortRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPSortRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPSortRel.java
index 5048ba2..fa5dc1d 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPSortRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPSortRel.java
@@ -18,11 +18,10 @@
 
 package org.apache.kylin.query.relnode;
 
-import com.google.common.base.Preconditions;
+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.EnumerableSort;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
@@ -38,9 +37,11 @@ import org.apache.kylin.metadata.model.MeasureDesc;
 import org.apache.kylin.metadata.model.TblColRef;
 import org.apache.kylin.storage.StorageContext;
 
+import com.google.common.base.Preconditions;
+
 /**
  */
-public class OLAPSortRel extends Sort implements EnumerableRel, OLAPRel {
+public class OLAPSortRel extends Sort implements OLAPRel {
 
     private ColumnRowType columnRowType;
     private OLAPContext context;
@@ -113,17 +114,9 @@ public class OLAPSortRel extends Sort implements EnumerableRel, OLAPRel {
     }
 
     @Override
-    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
-        OLAPRel childRel = (OLAPRel) getInput();
-        childRel.replaceTraitSet(EnumerableConvention.INSTANCE);
-
-        EnumerableSort enumSort = new EnumerableSort(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE, collation), getInput(), collation, offset, fetch);
-        ((OLAPRel.JavaImplementor) implementor).putParentContextForTableScanChild(this, enumSort);
-        Result res = enumSort.implement(implementor, pref);
-
-        childRel.replaceTraitSet(OLAPRel.CONVENTION);
-
-        return res;
+    public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
+        return new EnumerableSort(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE, collation), //
+                sole(inputs), collation, offset, fetch);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java
index afb4b60..fc1fdf5 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPTableScan.java
@@ -96,7 +96,7 @@ public class OLAPTableScan extends TableScan implements OLAPRel, EnumerableRel {
     public OLAPContext getContext() {
         return context;
     }
-    
+
     void overrideContext(OLAPContext context) {
         this.context = context;
     }
@@ -134,7 +134,7 @@ public class OLAPTableScan extends TableScan implements OLAPRel, EnumerableRel {
         planner.removeRule(FilterProjectTransposeRule.INSTANCE);
         // distinct count will be split into a separated query that is joined with the left query
         planner.removeRule(AggregateExpandDistinctAggregatesRule.INSTANCE);
-        
+
         // see Dec 26th email @ http://mail-archives.apache.org/mod_mbox/calcite-dev/201412.mbox/browser
         planner.removeRule(ExpandConversionRule.INSTANCE);
     }
@@ -191,17 +191,18 @@ public class OLAPTableScan extends TableScan implements OLAPRel, EnumerableRel {
     }
 
     @Override
-    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
-        if (!(implementor instanceof JavaImplementor))
-            throw new IllegalStateException("implementor is not JavaImplementor");
-        JavaImplementor javaImplementor = (JavaImplementor) implementor;
+    public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
+        return this;
+    }
 
-        PhysType physType = PhysTypeImpl.of(javaImplementor.getTypeFactory(), this.rowType, pref.preferArray());
+    @Override
+    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+        PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), this.rowType, pref.preferArray());
 
         String execFunction = genExecFunc();
 
-        MethodCallExpression exprCall = Expressions.call(table.getExpression(OLAPTable.class), execFunction, javaImplementor.getRootExpression(), Expressions.constant(context.id));
-        return javaImplementor.result(physType, Blocks.toBlock(exprCall));
+        MethodCallExpression exprCall = Expressions.call(table.getExpression(OLAPTable.class), execFunction, implementor.getRootExpression(), Expressions.constant(context.id));
+        return implementor.result(physType, Blocks.toBlock(exprCall));
     }
 
     private String genExecFunc() {

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/9ebb9bca/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java
index 57b8ee7..c86579d 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java
@@ -31,10 +31,12 @@ import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.convert.ConverterImpl;
 import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.kylin.metadata.realization.IRealization;
 import org.apache.kylin.query.routing.NoRealizationFoundException;
 import org.apache.kylin.query.routing.QueryRouter;
@@ -84,17 +86,17 @@ public class OLAPToEnumerableConverter extends ConverterImpl implements Enumerab
         OLAPRel.RewriteImplementor rewriteImplementor = new OLAPRel.RewriteImplementor();
         rewriteImplementor.visitChild(this, getInput());
 
-//        if (System.getProperty("calcite.debug") != null) {
-//            String dumpPlan = RelOptUtil.dumpPlan("", this, false, SqlExplainLevel.DIGEST_ATTRIBUTES);
-//            System.out.println("EXECUTION PLAN AFTER REWRITE");
-//            System.out.println(dumpPlan);
-//        }
+        // implement as EnumerableRel
+        OLAPRel.JavaImplementor impl = new OLAPRel.JavaImplementor(enumImplementor);
 
-        // build java implementation
-        EnumerableRel child = (EnumerableRel) getInput();
-        OLAPRel.JavaImplementor javaImplementor = new OLAPRel.JavaImplementor(enumImplementor);
-        return javaImplementor.visitChild(this, 0, child, pref);
+        EnumerableRel enumRel = impl.createEnumerable((OLAPRel) getInput());
+        if (System.getProperty("calcite.debug") != null) {
+            String dumpPlan = RelOptUtil.dumpPlan("", enumRel, false, SqlExplainLevel.DIGEST_ATTRIBUTES);
+            System.out.println("EXECUTION PLAN AFTER REWRITE");
+            System.out.println(dumpPlan);
+        }
 
+        return enumRel.implement(impl, pref);
     }
 
     private Result buildHiveResult(EnumerableRelImplementor enumImplementor, Prefer pref, OLAPContext context) {