You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2014/11/14 22:32:54 UTC

[46/58] [abbrv] [partial] incubator-calcite git commit: [CALCITE-306] Standardize code style for "import package.*; "

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java
new file mode 100644
index 0000000..de0ddd1
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java
@@ -0,0 +1,952 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.adapter.enumerable.impl.WinAggAddContextImpl;
+import org.apache.calcite.adapter.enumerable.impl.WinAggResetContextImpl;
+import org.apache.calcite.adapter.enumerable.impl.WinAggResultContextImpl;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.linq4j.tree.BinaryExpression;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.BlockStatement;
+import org.apache.calcite.linq4j.tree.DeclarationStatement;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.linq4j.tree.Primitive;
+import org.apache.calcite.linq4j.tree.Statement;
+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.prepare.CalcitePrepareImpl;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.AggregateCall;
+import org.apache.calcite.rel.core.Window;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexWindowBound;
+import org.apache.calcite.runtime.SortedMultiMap;
+import org.apache.calcite.util.BitSets;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.Util;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/** Implementation of {@link org.apache.calcite.rel.core.Window} in
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableWindow extends Window implements EnumerableRel {
+  /** Creates an EnumerableWindowRel. */
+  EnumerableWindow(RelOptCluster cluster, RelTraitSet traits, RelNode child,
+      List<RexLiteral> constants, RelDataType rowType, List<Group> groups) {
+    super(cluster, traits, child, constants, rowType, groups);
+  }
+
+  @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    return new EnumerableWindow(getCluster(), traitSet, sole(inputs),
+        constants, rowType, groups);
+  }
+
+  public RelOptCost computeSelfCost(RelOptPlanner planner) {
+    // Cost is proportional to the number of rows and the number of
+    // components (groups and aggregate functions). There is
+    // no I/O cost.
+    //
+    // TODO #1. Add memory cost.
+    // TODO #2. MIN and MAX have higher CPU cost than SUM and COUNT.
+    final double rowsIn = RelMetadataQuery.getRowCount(getInput());
+    int count = groups.size();
+    for (Group group : groups) {
+      count += group.aggCalls.size();
+    }
+    return planner.getCostFactory().makeCost(rowsIn, rowsIn * count, 0);
+  }
+
+  /** Implementation of {@link RexToLixTranslator.InputGetter}
+   * suitable for generating implementations of windowed aggregate
+   * functions. */
+  private static class WindowRelInputGetter
+      implements RexToLixTranslator.InputGetter {
+    private final Expression row;
+    private final PhysType rowPhysType;
+    private final int actualInputFieldCount;
+    private final List<Expression> constants;
+
+    private WindowRelInputGetter(Expression row,
+        PhysType rowPhysType, int actualInputFieldCount,
+        List<Expression> constants) {
+      this.row = row;
+      this.rowPhysType = rowPhysType;
+      this.actualInputFieldCount = actualInputFieldCount;
+      this.constants = constants;
+    }
+
+    public Expression field(BlockBuilder list, int index, Type storageType) {
+      if (index < actualInputFieldCount) {
+        Expression current = list.append("current", row);
+        return rowPhysType.fieldReference(current, index, storageType);
+      }
+      return constants.get(index - actualInputFieldCount);
+    }
+  }
+
+  private void sampleOfTheGeneratedWindowedAggregate() {
+    // Here's overview of the generated code
+    // For each list of rows that have the same partitioning key, evaluate
+    // all of the windowed aggregate functions.
+
+    // builder
+    Iterator<Integer[]> iterator = null;
+
+    // builder3
+    Integer[] rows = iterator.next();
+
+    int prevStart = -1;
+    int prevEnd = -1;
+
+    for (int i = 0; i < rows.length; i++) {
+      // builder4
+      Integer row = rows[i];
+
+      int start = 0;
+      int end = 100;
+      if (start != prevStart || end != prevEnd) {
+        // builder5
+        int actualStart = 0;
+        if (start != prevStart || end < prevEnd) {
+          // builder6
+          // recompute
+          actualStart = start;
+          // implementReset
+        } else { // must be start == prevStart && end > prevEnd
+          actualStart = prevEnd + 1;
+        }
+        prevStart = start;
+        prevEnd = end;
+
+        if (start != -1) {
+          for (int j = actualStart; j <= end; j++) {
+            // builder7
+            // implementAdd
+          }
+        }
+        // implementResult
+        // list.add(new Xxx(row.deptno, row.empid, sum, count));
+      }
+    }
+    // multiMap.clear(); // allows gc
+    // source = Linq4j.asEnumerable(list);
+  }
+
+  public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+    final JavaTypeFactory typeFactory = implementor.getTypeFactory();
+    final EnumerableRel child = (EnumerableRel) getInput();
+    final BlockBuilder builder = new BlockBuilder();
+    final Result result = implementor.visitChild(this, 0, child, pref);
+    Expression source_ = builder.append("source", result.block);
+
+    final List<Expression> translatedConstants =
+        new ArrayList<Expression>(constants.size());
+    for (RexLiteral constant : constants) {
+      translatedConstants.add(RexToLixTranslator.translateLiteral(
+          constant, constant.getType(),
+          typeFactory,
+          RexImpTable.NullAs.NULL));
+    }
+
+    PhysType inputPhysType = result.physType;
+
+    ParameterExpression prevStart =
+        Expressions.parameter(int.class, builder.newName("prevStart"));
+    ParameterExpression prevEnd =
+        Expressions.parameter(int.class, builder.newName("prevEnd"));
+
+    builder.add(Expressions.declare(0, prevStart, null));
+    builder.add(Expressions.declare(0, prevEnd, null));
+
+    for (int windowIdx = 0; windowIdx < groups.size(); windowIdx++) {
+      Group group = groups.get(windowIdx);
+      // Comparator:
+      // final Comparator<JdbcTest.Employee> comparator =
+      //    new Comparator<JdbcTest.Employee>() {
+      //      public int compare(JdbcTest.Employee o1,
+      //          JdbcTest.Employee o2) {
+      //        return Integer.compare(o1.empid, o2.empid);
+      //      }
+      //    };
+      final Expression comparator_ =
+          builder.append(
+              "comparator",
+              inputPhysType.generateComparator(
+                  group.collation()));
+
+      Pair<Expression, Expression> partitionIterator =
+          getPartitionIterator(builder, source_, inputPhysType, group,
+              comparator_);
+      final Expression collectionExpr = partitionIterator.left;
+      final Expression iterator_ = partitionIterator.right;
+
+      List<AggImpState> aggs = new ArrayList<AggImpState>();
+      List<AggregateCall> aggregateCalls = group.getAggregateCalls(this);
+      for (int aggIdx = 0; aggIdx < aggregateCalls.size(); aggIdx++) {
+        AggregateCall call = aggregateCalls.get(aggIdx);
+        aggs.add(new AggImpState(aggIdx, call, true));
+      }
+
+      // The output from this stage is the input plus the aggregate functions.
+      final RelDataTypeFactory.FieldInfoBuilder typeBuilder =
+          typeFactory.builder();
+      typeBuilder.addAll(inputPhysType.getRowType().getFieldList());
+      for (AggImpState agg : aggs) {
+        typeBuilder.add(agg.call.name, agg.call.type);
+      }
+      RelDataType outputRowType = typeBuilder.build();
+      final PhysType outputPhysType =
+          PhysTypeImpl.of(
+              typeFactory, outputRowType, pref.prefer(result.format));
+
+      final Expression list_ =
+          builder.append(
+              "list",
+              Expressions.new_(
+                  ArrayList.class,
+                  Expressions.call(
+                      collectionExpr, BuiltInMethod.COLLECTION_SIZE.method)),
+              false);
+
+      Pair<Expression, Expression> collationKey =
+          getRowCollationKey(builder, inputPhysType, group, windowIdx);
+      Expression keySelector = collationKey.left;
+      Expression keyComparator = collationKey.right;
+      final BlockBuilder builder3 = new BlockBuilder();
+      final Expression rows_ =
+          builder3.append(
+              "rows",
+              Expressions.convert_(
+                  Expressions.call(
+                      iterator_, BuiltInMethod.ITERATOR_NEXT.method),
+                  Object[].class),
+              false);
+
+      builder3.add(Expressions.statement(
+          Expressions.assign(prevStart, Expressions.constant(-1))));
+      builder3.add(Expressions.statement(
+          Expressions.assign(prevEnd,
+              Expressions.constant(Integer.MAX_VALUE))));
+
+      final BlockBuilder builder4 = new BlockBuilder();
+
+      final ParameterExpression i_ =
+          Expressions.parameter(int.class, builder4.newName("i"));
+
+      final Expression row_ =
+          builder4.append(
+              "row",
+              RexToLixTranslator.convert(
+                  Expressions.arrayIndex(rows_, i_),
+                  inputPhysType.getJavaRowType()));
+
+      final RexToLixTranslator.InputGetter inputGetter =
+          new WindowRelInputGetter(row_, inputPhysType,
+              result.physType.getRowType().getFieldCount(),
+              translatedConstants);
+
+      final RexToLixTranslator translator =
+          RexToLixTranslator.forAggregation(typeFactory, builder4,
+              inputGetter);
+
+      final List<Expression> outputRow = new ArrayList<Expression>();
+      int fieldCountWithAggResults =
+        inputPhysType.getRowType().getFieldCount();
+      for (int i = 0; i < fieldCountWithAggResults; i++) {
+        outputRow.add(
+            inputPhysType.fieldReference(
+                row_, i,
+                outputPhysType.getJavaFieldType(i)));
+      }
+
+      declareAndResetState(typeFactory, builder, result, windowIdx, aggs,
+          outputPhysType, outputRow);
+
+      // There are assumptions that minX==0. If ever change this, look for
+      // frameRowCount, bounds checking, etc
+      final Expression minX = Expressions.constant(0);
+      final Expression partitionRowCount =
+          builder3.append("partRows", Expressions.field(rows_, "length"));
+      final Expression maxX = builder3.append("maxX",
+          Expressions.subtract(
+              partitionRowCount, Expressions.constant(1)));
+
+      final Expression startUnchecked = builder4.append("start",
+          translateBound(translator, i_, row_, minX, maxX, rows_,
+              group, true,
+              inputPhysType, comparator_, keySelector, keyComparator));
+      final Expression endUnchecked = builder4.append("end",
+          translateBound(translator, i_, row_, minX, maxX, rows_,
+              group, false,
+              inputPhysType, comparator_, keySelector, keyComparator));
+
+      final Expression startX;
+      final Expression endX;
+      final Expression hasRows;
+      if (group.isAlwaysNonEmpty()) {
+        startX = startUnchecked;
+        endX = endUnchecked;
+        hasRows = Expressions.constant(true);
+      } else {
+        Expression startTmp =
+            group.lowerBound.isUnbounded() || startUnchecked == i_
+                ? startUnchecked
+                : builder4.append("startTmp",
+                    Expressions.call(null, BuiltInMethod.MATH_MAX.method,
+                        startUnchecked, minX));
+        Expression endTmp =
+            group.upperBound.isUnbounded() || endUnchecked == i_
+                ? endUnchecked
+                : builder4.append("endTmp",
+                    Expressions.call(null, BuiltInMethod.MATH_MIN.method,
+                        endUnchecked, maxX));
+
+        ParameterExpression startPe = Expressions.parameter(0, int.class,
+            builder4.newName("startChecked"));
+        ParameterExpression endPe = Expressions.parameter(0, int.class,
+            builder4.newName("endChecked"));
+        builder4.add(Expressions.declare(Modifier.FINAL, startPe, null));
+        builder4.add(Expressions.declare(Modifier.FINAL, endPe, null));
+
+        hasRows = builder4.append("hasRows",
+            Expressions.lessThanOrEqual(startTmp, endTmp));
+        builder4.add(Expressions.ifThenElse(
+            hasRows,
+            Expressions.block(
+                Expressions.statement(
+                    Expressions.assign(startPe, startTmp)),
+                Expressions.statement(
+                  Expressions.assign(endPe, endTmp))
+          ),
+            Expressions.block(
+                Expressions.statement(
+                    Expressions.assign(startPe, Expressions.constant(-1))),
+                Expressions.statement(
+                    Expressions.assign(endPe, Expressions.constant(-1))))));
+        startX = startPe;
+        endX = endPe;
+      }
+
+      final BlockBuilder builder5 = new BlockBuilder(true, builder4);
+
+      BinaryExpression rowCountWhenNonEmpty = Expressions.add(
+          startX == minX ? endX : Expressions.subtract(endX, startX),
+          Expressions.constant(1));
+
+      final Expression frameRowCount;
+
+      if (hasRows.equals(Expressions.constant(true))) {
+        frameRowCount =
+            builder4.append("totalRows", rowCountWhenNonEmpty);
+      } else {
+        frameRowCount =
+            builder4.append("totalRows", Expressions.condition(hasRows,
+                rowCountWhenNonEmpty, Expressions.constant(0)));
+      }
+
+      ParameterExpression actualStart = Expressions.parameter(
+          0, int.class, builder5.newName("actualStart"));
+
+      final BlockBuilder builder6 = new BlockBuilder(true, builder5);
+      builder6.add(Expressions.statement(
+          Expressions.assign(actualStart, startX)));
+
+      for (final AggImpState agg : aggs) {
+        agg.implementor.implementReset(agg.context,
+            new WinAggResetContextImpl(builder6, agg.state, i_, startX, endX,
+                hasRows, partitionRowCount, frameRowCount));
+      }
+
+      Expression lowerBoundCanChange =
+          group.lowerBound.isUnbounded() && group.lowerBound.isPreceding()
+          ? Expressions.constant(false)
+          : Expressions.notEqual(startX, prevStart);
+      Expression needRecomputeWindow = Expressions.orElse(
+          lowerBoundCanChange,
+          Expressions.lessThan(endX, prevEnd));
+
+      BlockStatement resetWindowState = builder6.toBlock();
+      if (resetWindowState.statements.size() == 1) {
+        builder5.add(Expressions.declare(0, actualStart,
+            Expressions.condition(needRecomputeWindow,
+                startX, Expressions.add(prevEnd, Expressions.constant(1)))));
+      } else {
+        builder5.add(Expressions.declare(0, actualStart,
+            null));
+        builder5.add(Expressions.ifThenElse(needRecomputeWindow,
+            resetWindowState,
+            Expressions.statement(Expressions.assign(actualStart,
+                Expressions.add(prevEnd, Expressions.constant(1))))));
+      }
+
+      if (lowerBoundCanChange instanceof BinaryExpression) {
+        builder5.add(Expressions.statement(
+            Expressions.assign(prevStart, startX)));
+      }
+      builder5.add(Expressions.statement(
+          Expressions.assign(prevEnd, endX)));
+
+      final BlockBuilder builder7 = new BlockBuilder(true, builder5);
+      final DeclarationStatement jDecl =
+          Expressions.declare(0, "j", actualStart);
+
+      final PhysType inputPhysTypeFinal = inputPhysType;
+      final Function<BlockBuilder, WinAggFrameResultContext>
+          resultContextBuilder =
+          getBlockBuilderWinAggFrameResultContextFunction(typeFactory, result,
+              translatedConstants, comparator_, rows_, i_, startX, endX,
+              minX, maxX,
+              hasRows, frameRowCount, partitionRowCount,
+              jDecl, inputPhysTypeFinal);
+
+      final Function<AggImpState, List<RexNode>> rexArguments =
+          new Function<AggImpState, List<RexNode>>() {
+            public List<RexNode> apply(AggImpState agg) {
+              List<Integer> argList = agg.call.getArgList();
+              List<RelDataType> inputTypes =
+                  EnumUtils.fieldRowTypes(
+                      result.physType.getRowType(),
+                      constants,
+                      argList);
+              List<RexNode> args = new ArrayList<RexNode>(
+                  inputTypes.size());
+              for (int i = 0; i < argList.size(); i++) {
+                Integer idx = argList.get(i);
+                args.add(new RexInputRef(idx, inputTypes.get(i)));
+              }
+              return args;
+            }
+          };
+
+      implementAdd(aggs, builder7, resultContextBuilder, rexArguments, jDecl);
+
+      BlockStatement forBlock = builder7.toBlock();
+      if (!forBlock.statements.isEmpty()) {
+        // For instance, row_number does not use for loop to compute the value
+        Statement forAggLoop = Expressions.for_(
+            Arrays.asList(jDecl),
+            Expressions.lessThanOrEqual(jDecl.parameter, endX),
+            Expressions.preIncrementAssign(jDecl.parameter),
+            forBlock);
+        if (!hasRows.equals(Expressions.constant(true))) {
+          forAggLoop = Expressions.ifThen(hasRows, forAggLoop);
+        }
+        builder5.add(forAggLoop);
+      }
+
+      if (implementResult(aggs, builder5, resultContextBuilder, rexArguments,
+              true)) {
+        builder4.add(Expressions.ifThen(Expressions.orElse(
+            lowerBoundCanChange,
+            Expressions.notEqual(endX, prevEnd)), builder5.toBlock()));
+      }
+
+      implementResult(aggs, builder4, resultContextBuilder, rexArguments,
+          false);
+
+      builder4.add(
+          Expressions.statement(
+              Expressions.call(
+                  list_,
+                  BuiltInMethod.COLLECTION_ADD.method,
+                  outputPhysType.record(outputRow))));
+
+      builder3.add(
+          Expressions.for_(
+              Expressions.declare(0, i_, Expressions.constant(0)),
+              Expressions.lessThan(
+                  i_,
+                  Expressions.field(rows_, "length")),
+              Expressions.preIncrementAssign(i_),
+              builder4.toBlock()));
+
+      builder.add(
+          Expressions.while_(
+              Expressions.call(
+                  iterator_,
+                  BuiltInMethod.ITERATOR_HAS_NEXT.method),
+              builder3.toBlock()));
+      builder.add(
+          Expressions.statement(
+              Expressions.call(
+                  collectionExpr,
+                  BuiltInMethod.MAP_CLEAR.method)));
+
+      // We're not assigning to "source". For each group, create a new
+      // final variable called "source" or "sourceN".
+      source_ =
+          builder.append(
+              "source",
+              Expressions.call(
+                  BuiltInMethod.AS_ENUMERABLE.method, list_));
+
+      inputPhysType = outputPhysType;
+    }
+
+    //   return Linq4j.asEnumerable(list);
+    builder.add(
+        Expressions.return_(null, source_));
+    return implementor.result(inputPhysType, builder.toBlock());
+  }
+
+  private Function<BlockBuilder, WinAggFrameResultContext>
+  getBlockBuilderWinAggFrameResultContextFunction(
+      final JavaTypeFactory typeFactory, final Result result,
+      final List<Expression> translatedConstants,
+      final Expression comparator_,
+      final Expression rows_, final ParameterExpression i_,
+      final Expression startX, final Expression endX,
+      final Expression minX, final Expression maxX,
+      final Expression hasRows, final Expression frameRowCount,
+      final Expression partitionRowCount,
+      final DeclarationStatement jDecl,
+      final PhysType inputPhysType) {
+    return new Function<BlockBuilder,
+        WinAggFrameResultContext>() {
+      public WinAggFrameResultContext apply(
+          final BlockBuilder block) {
+        return new WinAggFrameResultContext() {
+          public RexToLixTranslator rowTranslator(Expression rowIndex) {
+            Expression row =
+                getRow(rowIndex);
+            final RexToLixTranslator.InputGetter inputGetter =
+                new WindowRelInputGetter(row, inputPhysType,
+                    result.physType.getRowType().getFieldCount(),
+                    translatedConstants);
+
+            return RexToLixTranslator.forAggregation(typeFactory,
+                block, inputGetter);
+          }
+
+          public Expression computeIndex(Expression offset,
+              WinAggImplementor.SeekType seekType) {
+            Expression index;
+            if (seekType == WinAggImplementor.SeekType.AGG_INDEX) {
+              index = jDecl.parameter;
+            } else if (seekType == WinAggImplementor.SeekType.SET) {
+              index = i_;
+            } else if (seekType == WinAggImplementor.SeekType.START) {
+              index = startX;
+            } else if (seekType == WinAggImplementor.SeekType.END) {
+              index = endX;
+            } else {
+              throw new IllegalArgumentException("SeekSet " + seekType
+                  + " is not supported");
+            }
+            if (!Expressions.constant(0).equals(offset)) {
+              index = block.append("idx", Expressions.add(index, offset));
+            }
+            return index;
+          }
+
+          private Expression checkBounds(Expression rowIndex,
+              Expression minIndex, Expression maxIndex) {
+            if (rowIndex == i_ || rowIndex == startX || rowIndex == endX) {
+              // No additional bounds check required
+              return hasRows;
+            }
+
+            //noinspection UnnecessaryLocalVariable
+            Expression res = block.append("rowInFrame", Expressions.foldAnd(
+                ImmutableList.of(hasRows,
+                    Expressions.greaterThanOrEqual(rowIndex, minIndex),
+                    Expressions.lessThanOrEqual(rowIndex, maxIndex))));
+
+            return res;
+          }
+
+          public Expression rowInFrame(Expression rowIndex) {
+            return checkBounds(rowIndex, startX, endX);
+          }
+
+          public Expression rowInPartition(Expression rowIndex) {
+            return checkBounds(rowIndex, minX, maxX);
+          }
+
+          public Expression compareRows(Expression a, Expression b) {
+            return Expressions.call(comparator_,
+                BuiltInMethod.COMPARATOR_COMPARE.method,
+                getRow(a), getRow(b));
+          }
+
+          public Expression getRow(Expression rowIndex) {
+            return block.append(
+                "jRow",
+                RexToLixTranslator.convert(
+                    Expressions.arrayIndex(rows_, rowIndex),
+                    inputPhysType.getJavaRowType()));
+          }
+
+          public Expression index() {
+            return i_;
+          }
+
+          public Expression startIndex() {
+            return startX;
+          }
+
+          public Expression endIndex() {
+            return endX;
+          }
+
+          public Expression hasRows() {
+            return hasRows;
+          }
+
+          public Expression getFrameRowCount() {
+            return frameRowCount;
+          }
+
+          public Expression getPartitionRowCount() {
+            return partitionRowCount;
+          }
+        };
+      }
+    };
+  }
+
+  private Pair<Expression, Expression> getPartitionIterator(
+      BlockBuilder builder,
+      Expression source_,
+      PhysType inputPhysType,
+      Group group,
+      Expression comparator_) {
+    // Populate map of lists, one per partition
+    //   final Map<Integer, List<Employee>> multiMap =
+    //     new SortedMultiMap<Integer, List<Employee>>();
+    //    source.foreach(
+    //      new Function1<Employee, Void>() {
+    //        public Void apply(Employee v) {
+    //          final Integer k = v.deptno;
+    //          multiMap.putMulti(k, v);
+    //          return null;
+    //        }
+    //      });
+    //   final List<Xxx> list = new ArrayList<Xxx>(multiMap.size());
+    //   Iterator<Employee[]> iterator = multiMap.arrays(comparator);
+    //
+    if (group.keys.isEmpty()) {
+      // If partition key is empty, no need to partition.
+      //
+      //   final List<Employee> tempList =
+      //       source.into(new ArrayList<Employee>());
+      //   Iterator<Employee[]> iterator =
+      //       SortedMultiMap.singletonArrayIterator(comparator, tempList);
+      //   final List<Xxx> list = new ArrayList<Xxx>(tempList.size());
+
+      final Expression tempList_ = builder.append(
+          "tempList",
+          Expressions.convert_(
+              Expressions.call(
+                  source_,
+                  BuiltInMethod.INTO.method,
+                  Expressions.new_(ArrayList.class)),
+              List.class));
+      return Pair.of(tempList_,
+          builder.append(
+            "iterator",
+            Expressions.call(
+                null,
+                BuiltInMethod.SORTED_MULTI_MAP_SINGLETON.method,
+                comparator_,
+                tempList_)));
+    }
+    Expression multiMap_ =
+        builder.append(
+            "multiMap", Expressions.new_(SortedMultiMap.class));
+    final BlockBuilder builder2 = new BlockBuilder();
+    final ParameterExpression v_ =
+        Expressions.parameter(inputPhysType.getJavaRowType(),
+            builder2.newName("v"));
+    final DeclarationStatement declare =
+        Expressions.declare(
+            0, "key",
+            inputPhysType.selector(
+                v_,
+                BitSets.toList(group.keys),
+                JavaRowFormat.CUSTOM));
+    builder2.add(declare);
+    final ParameterExpression key_ = declare.parameter;
+    builder2.add(
+        Expressions.statement(
+            Expressions.call(
+                multiMap_,
+                BuiltInMethod.SORTED_MULTI_MAP_PUT_MULTI.method,
+                key_,
+                v_)));
+    builder2.add(
+        Expressions.return_(
+            null, Expressions.constant(null)));
+
+    builder.add(
+        Expressions.statement(
+            Expressions.call(
+                source_,
+                BuiltInMethod.ENUMERABLE_FOREACH.method,
+                Expressions.lambda(
+                    builder2.toBlock(), v_))));
+
+    return Pair.of(multiMap_,
+      builder.append(
+        "iterator",
+        Expressions.call(
+            multiMap_,
+            BuiltInMethod.SORTED_MULTI_MAP_ARRAYS.method,
+            comparator_)));
+  }
+
+  private Pair<Expression, Expression> getRowCollationKey(
+      BlockBuilder builder, PhysType inputPhysType,
+      Group group, int windowIdx) {
+    if (!(group.isRows || (group.upperBound.isUnbounded()
+        && group.lowerBound.isUnbounded()))) {
+      Pair<Expression, Expression> pair =
+          inputPhysType.generateCollationKey(
+              group.collation().getFieldCollations());
+      // optimize=false to prevent inlining of object create into for-loops
+      return Pair.of(
+          builder.append("keySelector" + windowIdx, pair.left, false),
+          builder.append("keyComparator" + windowIdx, pair.right, false));
+    } else {
+      return Pair.of(null, null);
+    }
+  }
+
+  private void declareAndResetState(final JavaTypeFactory typeFactory,
+      BlockBuilder builder, final Result result, int windowIdx,
+      List<AggImpState> aggs, PhysType outputPhysType,
+      List<Expression> outputRow) {
+    for (final AggImpState agg: aggs) {
+      agg.context =
+          new WinAggContext() {
+            public org.apache.calcite.sql.SqlAggFunction aggregation() {
+              return agg.call.getAggregation();
+            }
+
+            public RelDataType returnRelType() {
+              return agg.call.type;
+            }
+
+            public Type returnType() {
+              return EnumUtils.javaClass(typeFactory, returnRelType());
+            }
+
+            public List<? extends Type> parameterTypes() {
+              return EnumUtils.fieldTypes(typeFactory,
+                  parameterRelTypes());
+            }
+
+            public List<? extends RelDataType> parameterRelTypes() {
+              return EnumUtils.fieldRowTypes(result.physType.getRowType(),
+                  constants, agg.call.getArgList());
+            }
+          };
+      String aggName = "a" + agg.aggIdx;
+      if (CalcitePrepareImpl.DEBUG) {
+        aggName = Util.toJavaId(agg.call.getAggregation().getName(), 0)
+            .substring("ID$0$".length()) + aggName;
+      }
+      List<Type> state = agg.implementor.getStateType(agg.context);
+      final List<Expression> decls =
+          new ArrayList<Expression>(state.size());
+      for (int i = 0; i < state.size(); i++) {
+        Type type = state.get(i);
+        ParameterExpression pe =
+            Expressions.parameter(type,
+                builder.newName(aggName
+                    + "s" + i + "w" + windowIdx));
+        builder.add(Expressions.declare(0, pe, null));
+        decls.add(pe);
+      }
+      agg.state = decls;
+      Type aggHolderType = agg.context.returnType();
+      Type aggStorageType =
+          outputPhysType.getJavaFieldType(outputRow.size());
+      if (Primitive.is(aggHolderType) && !Primitive.is(aggStorageType)) {
+        aggHolderType = Primitive.box(aggHolderType);
+      }
+      ParameterExpression aggRes = Expressions.parameter(0,
+          aggHolderType,
+          builder.newName(aggName + "w" + windowIdx));
+
+      builder.add(Expressions.declare(0, aggRes,
+          Expressions.constant(
+              Primitive.is(aggRes.getType())
+                  ? Primitive.of(aggRes.getType()).defaultValue
+                  : null, aggRes.getType())));
+      agg.result = aggRes;
+      outputRow.add(aggRes);
+      agg.implementor.implementReset(agg.context,
+          new WinAggResetContextImpl(builder, agg.state,
+              null, null, null, null, null, null));
+    }
+  }
+
+  private void implementAdd(List<AggImpState> aggs,
+      final BlockBuilder builder7,
+      final Function<BlockBuilder, WinAggFrameResultContext> frame,
+      final Function<AggImpState, List<RexNode>> rexArguments,
+      final DeclarationStatement jDecl) {
+    for (final AggImpState agg : aggs) {
+      final WinAggAddContext addContext =
+          new WinAggAddContextImpl(builder7, agg.state, frame) {
+            public Expression currentPosition() {
+              return jDecl.parameter;
+            }
+
+            public List<RexNode> rexArguments() {
+              return rexArguments.apply(agg);
+            }
+          };
+      agg.implementor.implementAdd(agg.context, addContext);
+    }
+  }
+
+  private boolean implementResult(List<AggImpState> aggs,
+      final BlockBuilder builder,
+      final Function<BlockBuilder, WinAggFrameResultContext> frame,
+      final Function<AggImpState, List<RexNode>> rexArguments,
+      boolean cachedBlock) {
+    boolean nonEmpty = false;
+    for (final AggImpState agg : aggs) {
+      boolean needCache = true;
+      if (agg.implementor instanceof WinAggImplementor) {
+        WinAggImplementor imp = (WinAggImplementor) agg.implementor;
+        needCache = imp.needCacheWhenFrameIntact();
+      }
+      if (needCache ^ cachedBlock) {
+        // Regular aggregates do not change when the windowing frame keeps
+        // the same. Ths
+        continue;
+      }
+      nonEmpty = true;
+      Expression res = agg.implementor.implementResult(agg.context,
+          new WinAggResultContextImpl(builder, agg.state, frame) {
+            public List<RexNode> rexArguments() {
+              return rexArguments.apply(agg);
+            }
+          });
+      // Several count(a) and count(b) might share the result
+      Expression aggRes = builder.append("a" + agg.aggIdx + "res",
+          RexToLixTranslator.convert(res, agg.result.getType()));
+      builder.add(Expressions.statement(
+          Expressions.assign(agg.result, aggRes)));
+    }
+    return nonEmpty;
+  }
+
+  private Expression translateBound(RexToLixTranslator translator,
+      ParameterExpression i_, Expression row_, Expression min_,
+      Expression max_, Expression rows_, Group group,
+      boolean lower,
+      PhysType physType, Expression rowComparator,
+      Expression keySelector, Expression keyComparator) {
+    RexWindowBound bound = lower ? group.lowerBound : group.upperBound;
+    if (bound.isUnbounded()) {
+      return bound.isPreceding() ? min_ : max_;
+    }
+    if (group.isRows) {
+      if (bound.isCurrentRow()) {
+        return i_;
+      }
+      RexNode node = bound.getOffset();
+      Expression offs = translator.translate(node);
+      // Floating offset does not make sense since we refer to array index.
+      // Nulls do not make sense as well.
+      offs = RexToLixTranslator.convert(offs, int.class);
+
+      Expression b = i_;
+      if (bound.isFollowing()) {
+        b = Expressions.add(b, offs);
+      } else {
+        b = Expressions.subtract(b, offs);
+      }
+      return b;
+    }
+    Expression searchLower = min_;
+    Expression searchUpper = max_;
+    if (bound.isCurrentRow()) {
+      if (lower) {
+        searchUpper = i_;
+      } else {
+        searchLower = i_;
+      }
+    }
+
+    List<RelFieldCollation> fieldCollations =
+        group.collation().getFieldCollations();
+    if (bound.isCurrentRow() && fieldCollations.size() != 1) {
+      return Expressions.call(
+          (lower
+              ? BuiltInMethod.BINARY_SEARCH5_LOWER
+              : BuiltInMethod.BINARY_SEARCH5_UPPER).method,
+          rows_, row_, searchLower, searchUpper, keySelector, keyComparator);
+    }
+    assert fieldCollations.size() == 1
+        : "When using range window specification, ORDER BY should have"
+        + " exactly one expression."
+        + " Actual collation is " + group.collation();
+    // isRange
+    int orderKey =
+        fieldCollations.get(0).getFieldIndex();
+    RelDataType keyType =
+        physType.getRowType().getFieldList().get(orderKey).getType();
+    Type desiredKeyType = translator.typeFactory.getJavaClass(keyType);
+    if (bound.getOffset() == null) {
+      desiredKeyType = Primitive.box(desiredKeyType);
+    }
+    Expression val = translator.translate(new RexInputRef(orderKey,
+            keyType), desiredKeyType);
+    if (!bound.isCurrentRow()) {
+      RexNode node = bound.getOffset();
+      Expression offs = translator.translate(node);
+      // TODO: support date + interval somehow
+      if (bound.isFollowing()) {
+        val = Expressions.add(val, offs);
+      } else {
+        val = Expressions.subtract(val, offs);
+      }
+    }
+    return Expressions.call(
+        (lower
+            ? BuiltInMethod.BINARY_SEARCH6_LOWER
+            : BuiltInMethod.BINARY_SEARCH6_UPPER).method,
+        rows_, val, searchLower, searchUpper, keySelector, keyComparator);
+  }
+}
+
+// End EnumerableWindow.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindowRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindowRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindowRule.java
new file mode 100644
index 0000000..58e199f
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindowRule.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.logical.LogicalWindow;
+
+/**
+ * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalAggregate} to
+ * an {@link org.apache.calcite.adapter.enumerable.EnumerableAggregate}.
+ */
+class EnumerableWindowRule extends ConverterRule {
+  EnumerableWindowRule() {
+    super(LogicalWindow.class, Convention.NONE, EnumerableConvention.INSTANCE,
+        "EnumerableWindowRule");
+  }
+
+  public RelNode convert(RelNode rel) {
+    final LogicalWindow winAgg = (LogicalWindow) rel;
+    final RelTraitSet traitSet =
+        winAgg.getTraitSet().replace(EnumerableConvention.INSTANCE);
+    final RelNode child = winAgg.getInput();
+    final RelNode convertedChild =
+        convert(child,
+            child.getTraitSet().replace(EnumerableConvention.INSTANCE));
+    return new EnumerableWindow(rel.getCluster(), traitSet, convertedChild,
+        winAgg.getConstants(), winAgg.getRowType(), winAgg.groups);
+  }
+}
+
+// End EnumerableWindowRule.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java
index 26e728e..b96efb8 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java
@@ -14,15 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
 
-import net.hydromatic.linq4j.expressions.ParameterExpression;
-
-import net.hydromatic.optiq.DataContext;
-import net.hydromatic.optiq.impl.java.JavaTypeFactory;
-
-import org.eigenbase.rel.RelImplementorImpl;
-import org.eigenbase.rex.RexBuilder;
+import org.apache.calcite.DataContext;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.rel.RelImplementorImpl;
+import org.apache.calcite.rex.RexBuilder;
 
 /**
  * Abstract base class for implementations of {@link RelImplementorImpl}
@@ -33,13 +31,12 @@ public abstract class JavaRelImplementor extends RelImplementorImpl {
     super(rexBuilder);
   }
 
-  @Override
-  public JavaTypeFactory getTypeFactory() {
+  @Override public JavaTypeFactory getTypeFactory() {
     return (JavaTypeFactory) super.getTypeFactory();
   }
 
   /** Returns the expression with which to access the
-   * {@link net.hydromatic.optiq.DataContext}. */
+   * {@link org.apache.calcite.DataContext}. */
   public ParameterExpression getRootExpression() {
     return DataContext.ROOT;
   }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java
index 6773ff3..d1a119c 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java
@@ -14,16 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
 
-import net.hydromatic.linq4j.expressions.*;
-
-import net.hydromatic.optiq.BuiltinMethod;
-import net.hydromatic.optiq.impl.java.JavaTypeFactory;
-import net.hydromatic.optiq.runtime.FlatLists;
-import net.hydromatic.optiq.runtime.Unit;
-
-import org.eigenbase.reltype.RelDataType;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.ExpressionType;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.MemberExpression;
+import org.apache.calcite.linq4j.tree.Types;
+import org.apache.calcite.linq4j.tree.UnaryExpression;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.runtime.FlatLists;
+import org.apache.calcite.runtime.Unit;
+import org.apache.calcite.util.BuiltInMethod;
 
 import java.lang.reflect.Type;
 import java.util.AbstractList;
@@ -41,8 +44,7 @@ public enum JavaRowFormat {
       return typeFactory.getJavaClass(type);
     }
 
-    @Override
-    Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
+    @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
         int index) {
       return typeFactory.getJavaClass(type.getFieldList().get(index).getType());
     }
@@ -58,8 +60,7 @@ public enum JavaRowFormat {
       }
     }
 
-    @Override
-    public MemberExpression field(Expression expression, int field,
+    @Override public MemberExpression field(Expression expression, int field,
         Type fieldType) {
       final Type type = expression.getType();
       if (type instanceof Types.RecordType) {
@@ -85,8 +86,7 @@ public enum JavaRowFormat {
           type.getFieldList().get(0).getType());
     }
 
-    @Override
-    Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
+    @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
         int index) {
       return javaRowClass(typeFactory, type);
     }
@@ -97,8 +97,8 @@ public enum JavaRowFormat {
       return expressions.get(0);
     }
 
-    @Override
-    public Expression field(Expression expression, int field, Type fieldType) {
+    @Override public Expression field(Expression expression, int field,
+        Type fieldType) {
       assert field == 0;
       return expression;
     }
@@ -114,8 +114,7 @@ public enum JavaRowFormat {
       return FlatLists.ComparableList.class;
     }
 
-    @Override
-    Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
+    @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
         int index) {
       return Object.class;
     }
@@ -133,7 +132,7 @@ public enum JavaRowFormat {
             Expressions.call(
                 List.class,
                 null,
-                BuiltinMethod.LIST2.method,
+                BuiltInMethod.LIST2.method,
                 expressions),
             List.class);
       case 3:
@@ -141,7 +140,7 @@ public enum JavaRowFormat {
             Expressions.call(
                 List.class,
                 null,
-                BuiltinMethod.LIST3.method,
+                BuiltInMethod.LIST3.method,
                 expressions),
             List.class);
       default:
@@ -149,7 +148,7 @@ public enum JavaRowFormat {
             Expressions.call(
                 List.class,
                 null,
-                BuiltinMethod.ARRAYS_AS_LIST.method,
+                BuiltInMethod.ARRAYS_AS_LIST.method,
                 Expressions.newArrayInit(
                     Object.class,
                     expressions)),
@@ -157,11 +156,11 @@ public enum JavaRowFormat {
       }
     }
 
-    @Override
-    public Expression field(Expression expression, int field, Type fieldType) {
+    @Override public Expression field(Expression expression, int field,
+        Type fieldType) {
       return RexToLixTranslator.convert(
           Expressions.call(expression,
-              BuiltinMethod.LIST_GET.method,
+              BuiltInMethod.LIST_GET.method,
               Expressions.constant(field)),
           fieldType);
     }
@@ -175,8 +174,7 @@ public enum JavaRowFormat {
       return Object[].class;
     }
 
-    @Override
-    Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
+    @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
         int index) {
       return Object.class;
     }
@@ -188,11 +186,11 @@ public enum JavaRowFormat {
     }
 
     @Override public Expression comparer() {
-      return Expressions.call(BuiltinMethod.ARRAY_COMPARER.method);
+      return Expressions.call(BuiltInMethod.ARRAY_COMPARER.method);
     }
 
-    @Override
-    public Expression field(Expression expression, int field, Type fieldType) {
+    @Override public Expression field(Expression expression, int field,
+        Type fieldType) {
       return RexToLixTranslator.convert(
           Expressions.arrayIndex(expression, Expressions.constant(field)),
           fieldType);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java
index e97d621..c78a25c 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java
@@ -14,18 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
 
-import net.hydromatic.linq4j.expressions.BlockBuilder;
-
-import org.eigenbase.rex.RexNode;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.rex.RexNode;
 
 import java.util.Map;
 
 /**
- * Allows to build nested code blocks with tracking of current context and
- * the nullability of particular {@link org.eigenbase.rex.RexNode} expressions.
- * @see net.hydromatic.optiq.rules.java.StrictAggImplementor#implementAdd(AggContext, AggAddContext)
+ * Allows to build nested code blocks with tracking of current context and the
+ * nullability of particular {@link org.apache.calcite.rex.RexNode} expressions.
+ *
+ * @see org.apache.calcite.adapter.enumerable.StrictAggImplementor#implementAdd(AggContext, AggAddContext)
  */
 public interface NestedBlockBuilder {
   /**

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java
index 5f50f17..1caa47e 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java
@@ -14,18 +14,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
 
-import net.hydromatic.linq4j.expressions.BlockBuilder;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.rex.RexNode;
 
-import org.eigenbase.rex.RexNode;
-
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
- * Allows to build nested code blocks with tracking of current context and
- * the nullability of particular {@link org.eigenbase.rex.RexNode} expressions.
- * @see net.hydromatic.optiq.rules.java.StrictAggImplementor#implementAdd(AggContext, AggAddContext)
+ * Allows to build nested code blocks with tracking of current context and the
+ * nullability of particular {@link org.apache.calcite.rex.RexNode} expressions.
+ *
+ * @see org.apache.calcite.adapter.enumerable.StrictAggImplementor#implementAdd(AggContext, AggAddContext)
  */
 public class NestedBlockBuilderImpl implements NestedBlockBuilder {
   private final List<BlockBuilder> blocks = new ArrayList<BlockBuilder>();
@@ -113,4 +117,4 @@ public class NestedBlockBuilderImpl implements NestedBlockBuilder {
   }
 }
 
-// End NestedBlockBuilder.java
+// End NestedBlockBuilderImpl.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java
index 8926a4e..0144d3a 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java
@@ -14,20 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
 
-import net.hydromatic.linq4j.expressions.Expression;
-
-import org.eigenbase.rex.RexCall;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.rex.RexCall;
 
 import java.util.List;
 
 /**
- * Simplified version of {@link net.hydromatic.optiq.rules.java.CallImplementor}
+ * Simplified version of
+ * {@link org.apache.calcite.adapter.enumerable.CallImplementor}
  * that does not know about null semantics.
  *
- * @see net.hydromatic.optiq.rules.java.RexImpTable
- * @see net.hydromatic.optiq.rules.java.CallImplementor
+ * @see org.apache.calcite.adapter.enumerable.RexImpTable
+ * @see org.apache.calcite.adapter.enumerable.CallImplementor
  */
 public interface NotNullImplementor {
   /**

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java
index 7e98302..dedf300 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
 
 /**
  * Describes when a function/operator will return null.
@@ -40,3 +40,5 @@ public enum NullPolicy {
   NOT,
   NONE
 }
+
+// End NullPolicy.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java
index 51e60a0..e620c13 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java
@@ -14,15 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
-
-import net.hydromatic.linq4j.expressions.Expression;
-import net.hydromatic.linq4j.expressions.ParameterExpression;
-
-import org.eigenbase.rel.RelCollation;
-import org.eigenbase.rel.RelFieldCollation;
-import org.eigenbase.reltype.RelDataType;
-import org.eigenbase.util.Pair;
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.util.Pair;
 
 import java.lang.reflect.Type;
 import java.util.List;

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysTypeImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysTypeImpl.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysTypeImpl.java
index e30ce21..562e4ba 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysTypeImpl.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysTypeImpl.java
@@ -14,22 +14,26 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
-
-import net.hydromatic.linq4j.expressions.*;
-import net.hydromatic.linq4j.function.Function1;
-
-import net.hydromatic.optiq.BuiltinMethod;
-import net.hydromatic.optiq.impl.java.JavaTypeFactory;
-import net.hydromatic.optiq.runtime.Utilities;
-
-import org.eigenbase.rel.RelCollation;
-import org.eigenbase.rel.RelFieldCollation;
-import org.eigenbase.reltype.RelDataType;
-import org.eigenbase.reltype.RelDataTypeFactory;
-import org.eigenbase.reltype.RelDataTypeField;
-import org.eigenbase.util.Pair;
-import org.eigenbase.util.Util;
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.linq4j.function.Function1;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.MemberDeclaration;
+import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.linq4j.tree.Primitive;
+import org.apache.calcite.linq4j.tree.Types;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.runtime.Utilities;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.Util;
 
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
@@ -37,7 +41,14 @@ import com.google.common.collect.Lists;
 
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
-import java.util.*;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.apache.calcite.adapter.enumerable.EnumUtils.javaRowClass;
+import static org.apache.calcite.adapter.enumerable.EnumUtils.overridingMethodDecl;
 
 /** Implementation of {@link PhysType}. */
 public class PhysTypeImpl implements PhysType {
@@ -58,8 +69,7 @@ public class PhysTypeImpl implements PhysType {
     this.javaRowClass = javaRowClass;
     this.format = format;
     for (RelDataTypeField field : rowType.getFieldList()) {
-      fieldClasses.add(
-          JavaRules.EnumUtil.javaRowClass(typeFactory, field.getType()));
+      fieldClasses.add(javaRowClass(typeFactory, field.getType()));
     }
   }
 
@@ -85,8 +95,8 @@ public class PhysTypeImpl implements PhysType {
     }
     RelDataType rowType = builder.build();
     // Do not optimize if there are 0 or 1 fields.
-    return new PhysTypeImpl(
-        typeFactory, rowType, javaRowClass, JavaRowFormat.CUSTOM);
+    return new PhysTypeImpl(typeFactory, rowType, javaRowClass,
+        JavaRowFormat.CUSTOM);
   }
 
   public JavaRowFormat getFormat() {
@@ -128,7 +138,7 @@ public class PhysTypeImpl implements PhysType {
         project(fields, targetFormat);
     switch (format) {
     case SCALAR:
-      return Expressions.call(BuiltinMethod.IDENTITY_SELECTOR.method);
+      return Expressions.call(BuiltInMethod.IDENTITY_SELECTOR.method);
     default:
       return Expressions.lambda(Function1.class,
           targetPhysType.record(fieldReferences(parameter, fields)), parameter);
@@ -186,7 +196,7 @@ public class PhysTypeImpl implements PhysType {
     final ParameterExpression o_ =
         Expressions.parameter(javaRowClass, "o");
     final int fieldCount = rowType.getFieldCount();
-    return Expressions.call(exp, BuiltinMethod.SELECT.method,
+    return Expressions.call(exp, BuiltInMethod.SELECT.method,
         generateSelector(o_, Util.range(fieldCount), targetFormat));
   }
 
@@ -205,7 +215,7 @@ public class PhysTypeImpl implements PhysType {
       return Pair.<Expression, Expression>of(
           selector,
           Expressions.call(
-              BuiltinMethod.NULLS_COMPARATOR.method,
+              BuiltInMethod.NULLS_COMPARATOR.method,
               Expressions.constant(
                   collation.nullDirection
                       == RelFieldCollation.NullDirection.FIRST),
@@ -214,7 +224,7 @@ public class PhysTypeImpl implements PhysType {
                       == RelFieldCollation.Direction.DESCENDING)));
     }
     selector =
-        Expressions.call(BuiltinMethod.IDENTITY_SELECTOR.method);
+        Expressions.call(BuiltInMethod.IDENTITY_SELECTOR.method);
 
     // int c;
     // c = Utilities.compare(v0, v1);
@@ -281,7 +291,7 @@ public class PhysTypeImpl implements PhysType {
                     parameterV0, parameterV1),
                 body.toBlock()));
 
-    if (JavaRules.BRIDGE_METHODS) {
+    if (EnumerableRules.BRIDGE_METHODS) {
       final ParameterExpression parameterO0 =
           Expressions.parameter(Object.class, "o0");
       final ParameterExpression parameterO1 =
@@ -293,7 +303,7 @@ public class PhysTypeImpl implements PhysType {
               Expressions.call(
                   Expressions.parameter(
                       Comparable.class, "this"),
-                  BuiltinMethod.COMPARATOR_COMPARE.method,
+                  BuiltInMethod.COMPARATOR_COMPARE.method,
                   Expressions.convert_(
                       parameterO0,
                       javaRowClass),
@@ -301,8 +311,8 @@ public class PhysTypeImpl implements PhysType {
                       parameterO1,
                       javaRowClass))));
       memberDeclarations.add(
-          JavaRules.EnumUtil.overridingMethodDecl(
-              BuiltinMethod.COMPARATOR_COMPARE.method,
+          overridingMethodDecl(
+              BuiltInMethod.COMPARATOR_COMPARE.method,
               ImmutableList.of(parameterO0, parameterO1),
               bridgeBody.toBlock()));
     }
@@ -381,7 +391,7 @@ public class PhysTypeImpl implements PhysType {
                 ImmutableList.of(parameterV0, parameterV1),
                 body.toBlock()));
 
-    if (JavaRules.BRIDGE_METHODS) {
+    if (EnumerableRules.BRIDGE_METHODS) {
       final ParameterExpression parameterO0 =
           Expressions.parameter(Object.class, "o0");
       final ParameterExpression parameterO1 =
@@ -393,7 +403,7 @@ public class PhysTypeImpl implements PhysType {
               Expressions.call(
                   Expressions.parameter(
                       Comparable.class, "this"),
-                  BuiltinMethod.COMPARATOR_COMPARE.method,
+                  BuiltInMethod.COMPARATOR_COMPARE.method,
                   Expressions.convert_(
                       parameterO0,
                       javaRowClass),
@@ -401,8 +411,8 @@ public class PhysTypeImpl implements PhysType {
                       parameterO1,
                       javaRowClass))));
       memberDeclarations.add(
-          JavaRules.EnumUtil.overridingMethodDecl(
-              BuiltinMethod.COMPARATOR_COMPARE.method,
+          overridingMethodDecl(
+              BuiltInMethod.COMPARATOR_COMPARE.method,
               ImmutableList.of(parameterO0, parameterO1),
               bridgeBody.toBlock()));
     }
@@ -501,7 +511,7 @@ public class PhysTypeImpl implements PhysType {
             Expressions.call(
                 List.class,
                 null,
-                BuiltinMethod.LIST2.method,
+                BuiltInMethod.LIST2.method,
                 list),
             v1);
       case 3:
@@ -510,7 +520,7 @@ public class PhysTypeImpl implements PhysType {
             Expressions.call(
                 List.class,
                 null,
-                BuiltinMethod.LIST3.method,
+                BuiltInMethod.LIST3.method,
                 list),
             v1);
       default:
@@ -519,7 +529,7 @@ public class PhysTypeImpl implements PhysType {
             Expressions.call(
                 List.class,
                 null,
-                BuiltinMethod.ARRAYS_AS_LIST.method,
+                BuiltInMethod.ARRAYS_AS_LIST.method,
                 Expressions.newArrayInit(
                     Object.class,
                     list)),

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/ReflectiveCallNotNullImplementor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/ReflectiveCallNotNullImplementor.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/ReflectiveCallNotNullImplementor.java
index 527facf..bf35032 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/ReflectiveCallNotNullImplementor.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/ReflectiveCallNotNullImplementor.java
@@ -14,13 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
 
-import net.hydromatic.linq4j.expressions.Expression;
-import net.hydromatic.linq4j.expressions.Expressions;
-import net.hydromatic.linq4j.expressions.NewExpression;
-
-import org.eigenbase.rex.RexCall;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.NewExpression;
+import org.apache.calcite.rex.RexCall;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -28,7 +27,7 @@ import java.util.List;
 
 /**
  * Implementation of
- * {@link net.hydromatic.optiq.rules.java.NotNullImplementor}
+ * {@link org.apache.calcite.adapter.enumerable.NotNullImplementor}
  * that calls a given {@link java.lang.reflect.Method}.
  *
  * <p>When method is not static, a new instance of the required class is