http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillWindowRel.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillWindowRel.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillWindowRel.java
new file mode 100644
index 0000000..113f98c
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillWindowRel.java
@@ -0,0 +1,111 @@
+/**
+ * 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.drill.exec.planner.logical;
+
+import com.google.common.collect.Lists;
+import net.hydromatic.linq4j.Ord;
+import net.hydromatic.optiq.util.BitSets;
+import org.apache.drill.common.expression.ExpressionPosition;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.ValueExpressions;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.Order;
+import org.apache.drill.exec.planner.common.DrillWindowRelBase;
+import org.eigenbase.rel.AggregateCall;
+import org.eigenbase.rel.RelFieldCollation;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.rex.RexLiteral;
+
+import java.util.List;
+
+public class DrillWindowRel extends DrillWindowRelBase implements DrillRel {
+  /**
+   * Creates a window relational expression.
+   *
+   * @param cluster Cluster
+   * @param traits
+   * @param child   Input relational expression
+   * @param rowType Output row type
+   * @param windows Windows
+   */
+  public DrillWindowRel(
+      RelOptCluster cluster,
+      RelTraitSet traits,
+      RelNode child,
+      List<RexLiteral> constants,
+      RelDataType rowType,
+      List<Window> windows) {
+    super(cluster, traits, child, constants, rowType, windows);
+  }
+
+  @Override
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    return new DrillWindowRel(getCluster(), traitSet, sole(inputs), constants, 
getRowType(), windows);
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    final LogicalOperator inputOp = implementor.visitChild(this, 0, 
getChild());
+    org.apache.drill.common.logical.data.Window.Builder builder = new 
org.apache.drill.common.logical.data.Window.Builder();
+    final List<String> fields = getRowType().getFieldNames();
+    final List<String> childFields = getChild().getRowType().getFieldNames();
+    for (Window window : windows) {
+
+      for(RelFieldCollation orderKey : window.orderKeys.getFieldCollations()) {
+        builder.addOrdering(new Order.Ordering(orderKey.getDirection(), new 
FieldReference(fields.get(orderKey.getFieldIndex()))));
+      }
+
+      for (int group : BitSets.toIter(window.groupSet)) {
+        FieldReference fr = new FieldReference(childFields.get(group), 
ExpressionPosition.UNKNOWN);
+        builder.addWithin(fr, fr);
+      }
+
+      int groupCardinality = window.groupSet.cardinality();
+      for (Ord<AggregateCall> aggCall : 
Ord.zip(window.getAggregateCalls(this))) {
+        FieldReference ref = new FieldReference(fields.get(groupCardinality + 
aggCall.i));
+        LogicalExpression expr = toDrill(aggCall.e, childFields);
+        builder.addAggregation(ref, expr);
+      }
+    }
+    builder.setInput(inputOp);
+    org.apache.drill.common.logical.data.Window frame = builder.build();
+    return frame;
+  }
+
+  protected LogicalExpression toDrill(AggregateCall call, List<String> fn) {
+    List<LogicalExpression> args = Lists.newArrayList();
+    for (Integer i : call.getArgList()) {
+      args.add(new FieldReference(fn.get(i)));
+    }
+
+    // for count(1).
+    if (args.isEmpty()) {
+      args.add(new ValueExpressions.LongExpression(1l));
+    }
+    LogicalExpression expr = new 
FunctionCall(call.getAggregation().getName().toLowerCase(), args, 
ExpressionPosition.UNKNOWN);
+    return expr;
+  }
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillWindowRule.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillWindowRule.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillWindowRule.java
new file mode 100644
index 0000000..847e87a
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillWindowRule.java
@@ -0,0 +1,52 @@
+/**
+ * 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.drill.exec.planner.logical;
+
+import com.google.common.collect.Lists;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.WindowRel;
+import org.eigenbase.relopt.Convention;
+import org.eigenbase.relopt.RelOptRule;
+import org.eigenbase.relopt.RelOptRuleCall;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.rex.RexLiteral;
+
+public class DrillWindowRule extends RelOptRule {
+  public static final RelOptRule INSTANCE = new DrillWindowRule();
+
+  private DrillWindowRule() {
+    super(RelOptHelper.some(WindowRel.class, Convention.NONE, 
RelOptHelper.any(RelNode.class)), "DrillWindowRule");
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final WindowRel window = call.rel(0);
+    final RelNode input = call.rel(1);
+    final RelTraitSet traits = 
window.getTraitSet().plus(DrillRel.DRILL_LOGICAL);
+    final RelNode convertedInput = convert(input, traits);
+    call.transformTo(
+        new DrillWindowRel(
+            window.getCluster(),
+            traits,
+            convertedInput,
+            Lists.<RexLiteral>newArrayList(),
+            window.getRowType(),
+            window.windows));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/AggPrelBase.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/AggPrelBase.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/AggPrelBase.java
index 05fb64a..a69188b 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/AggPrelBase.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/AggPrelBase.java
@@ -17,21 +17,16 @@
  */
 package org.apache.drill.exec.planner.physical;
 
-import java.util.BitSet;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import net.hydromatic.linq4j.Ord;
 import net.hydromatic.optiq.util.BitSets;
-
 import org.apache.drill.common.expression.ExpressionPosition;
 import org.apache.drill.common.expression.FieldReference;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.ValueExpressions;
 import org.apache.drill.common.logical.data.NamedExpression;
-import org.apache.drill.exec.planner.logical.DrillParseContext;
 import org.apache.drill.exec.planner.physical.visitor.PrelVisitor;
 import org.eigenbase.rel.AggregateCall;
 import org.eigenbase.rel.AggregateRelBase;
@@ -48,8 +43,10 @@ import org.eigenbase.sql.SqlKind;
 import org.eigenbase.sql.type.OperandTypes;
 import org.eigenbase.sql.type.ReturnTypes;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 
 public abstract class AggPrelBase extends AggregateRelBase implements Prel {
 
@@ -130,7 +127,7 @@ public abstract class AggPrelBase extends AggregateRelBase 
implements Prel {
     for (Ord<AggregateCall> aggCall : Ord.zip(aggCalls)) {
       int aggExprOrdinal = groupSet.cardinality() + aggCall.i;
       FieldReference ref = new FieldReference(fields.get(aggExprOrdinal));
-      LogicalExpression expr = toDrill(aggCall.e, childFields, new 
DrillParseContext());
+      LogicalExpression expr = toDrill(aggCall.e, childFields);
       NamedExpression ne = new NamedExpression(expr, ref);
       aggExprs.add(ne);
 
@@ -162,7 +159,7 @@ public abstract class AggPrelBase extends AggregateRelBase 
implements Prel {
     }
   }
 
-  protected LogicalExpression toDrill(AggregateCall call, List<String> fn, 
DrillParseContext pContext) {
+  protected LogicalExpression toDrill(AggregateCall call, List<String> fn) {
     List<LogicalExpression> args = Lists.newArrayList();
     for (Integer i : call.getArgList()) {
       args.add(new FieldReference(fn.get(i)));

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/LimitPrel.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/LimitPrel.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/LimitPrel.java
index 5060195..6012a5a 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/LimitPrel.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/LimitPrel.java
@@ -17,10 +17,6 @@
  */
 package org.apache.drill.exec.planner.physical;
 
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
 import org.apache.drill.exec.physical.base.PhysicalOperator;
 import org.apache.drill.exec.physical.config.Limit;
 import org.apache.drill.exec.planner.common.DrillLimitRelBase;
@@ -32,6 +28,10 @@ import org.eigenbase.relopt.RelTraitSet;
 import org.eigenbase.rex.RexLiteral;
 import org.eigenbase.rex.RexNode;
 
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
 public class LimitPrel extends DrillLimitRelBase implements Prel {
 
   public LimitPrel(RelOptCluster cluster, RelTraitSet traitSet, RelNode child, 
RexNode offset, RexNode fetch) {

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/StreamingWindowPrel.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/StreamingWindowPrel.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/StreamingWindowPrel.java
new file mode 100644
index 0000000..f1a8bc0
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/StreamingWindowPrel.java
@@ -0,0 +1,136 @@
+/**
+ * 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.drill.exec.planner.physical;
+
+import com.google.common.collect.Lists;
+import net.hydromatic.optiq.util.BitSets;
+import org.apache.drill.common.expression.ExpressionPosition;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.ValueExpressions;
+import org.apache.drill.common.logical.data.NamedExpression;
+import org.apache.drill.exec.physical.base.PhysicalOperator;
+import org.apache.drill.exec.physical.config.WindowPOP;
+import org.apache.drill.exec.planner.common.DrillWindowRelBase;
+import org.apache.drill.exec.planner.physical.visitor.PrelVisitor;
+import org.apache.drill.exec.record.BatchSchema;
+import org.eigenbase.rel.AggregateCall;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.rex.RexLiteral;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class StreamingWindowPrel extends DrillWindowRelBase implements Prel {
+  public StreamingWindowPrel(RelOptCluster cluster,
+                             RelTraitSet traits,
+                             RelNode child,
+                             List<RexLiteral> constants,
+                             RelDataType rowType,
+                             Window window) {
+    super(cluster, traits, child, constants, rowType, 
Collections.singletonList(window));
+  }
+
+  @Override
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    return new StreamingWindowPrel(getCluster(), traitSet, sole(inputs), 
constants, getRowType(), windows.get(0));
+  }
+
+  @Override
+  public PhysicalOperator getPhysicalOperator(PhysicalPlanCreator creator) 
throws IOException {
+    Prel child = (Prel) this.getChild();
+
+    PhysicalOperator childPOP = child.getPhysicalOperator(creator);
+
+    final List<String> childFields = getChild().getRowType().getFieldNames();
+
+    checkState(windows.size() == 1, "Only one window is expected in 
WindowPrel");
+
+    Window window = windows.get(0);
+    List<NamedExpression> withins = Lists.newArrayList();
+    List<NamedExpression> aggs = Lists.newArrayList();
+    for (int group : BitSets.toIter(window.groupSet)) {
+      FieldReference fr = new FieldReference(childFields.get(group), 
ExpressionPosition.UNKNOWN);
+      withins.add(new NamedExpression(fr, fr));
+    }
+
+    for (AggregateCall aggCall : window.getAggregateCalls(this)) {
+      FieldReference ref = new FieldReference(aggCall.getName());
+      LogicalExpression expr = toDrill(aggCall, childFields);
+      aggs.add(new NamedExpression(expr, ref));
+    }
+
+    WindowPOP windowPOP = new WindowPOP(
+        childPOP,
+        withins.toArray(new NamedExpression[withins.size()]),
+        aggs.toArray(new NamedExpression[aggs.size()]),
+        Long.MIN_VALUE, //TODO: Get first/last to work
+        Long.MIN_VALUE);
+
+    creator.addMetadata(this, windowPOP);
+    return windowPOP;
+  }
+
+  protected LogicalExpression toDrill(AggregateCall call, List<String> fn) {
+    List<LogicalExpression> args = Lists.newArrayList();
+    for (Integer i : call.getArgList()) {
+      args.add(new FieldReference(fn.get(i)));
+    }
+
+    // for count(1).
+    if (args.isEmpty()) {
+      args.add(new ValueExpressions.LongExpression(1l));
+    }
+    LogicalExpression expr = new 
FunctionCall(call.getAggregation().getName().toLowerCase(), args, 
ExpressionPosition.UNKNOWN);
+    return expr;
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(PrelVisitor<T, X, E> 
logicalVisitor, X value) throws E {
+    return logicalVisitor.visitPrel(this, value);
+  }
+
+  @Override
+  public BatchSchema.SelectionVectorMode[] getSupportedEncodings() {
+    return BatchSchema.SelectionVectorMode.ALL;
+  }
+
+  @Override
+  public BatchSchema.SelectionVectorMode getEncoding() {
+    return BatchSchema.SelectionVectorMode.NONE;
+  }
+
+  @Override
+  public boolean needsFinalColumnReordering() {
+    return false;
+  }
+
+  @Override
+  public Iterator<Prel> iterator() {
+    return PrelUtil.iter(getChild());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/StreamingWindowPrule.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/StreamingWindowPrule.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/StreamingWindowPrule.java
new file mode 100644
index 0000000..00c20b2
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/StreamingWindowPrule.java
@@ -0,0 +1,133 @@
+/**
+ * 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.drill.exec.planner.physical;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import net.hydromatic.linq4j.Ord;
+import net.hydromatic.optiq.util.BitSets;
+import org.apache.drill.exec.planner.logical.DrillRel;
+import org.apache.drill.exec.planner.logical.DrillWindowRel;
+import org.apache.drill.exec.planner.logical.RelOptHelper;
+import org.eigenbase.rel.RelCollation;
+import org.eigenbase.rel.RelCollationImpl;
+import org.eigenbase.rel.RelFieldCollation;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.WindowRelBase;
+import org.eigenbase.relopt.RelOptRule;
+import org.eigenbase.relopt.RelOptRuleCall;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.reltype.RelDataTypeField;
+import org.eigenbase.reltype.RelRecordType;
+import org.eigenbase.sql.SqlAggFunction;
+
+import java.util.List;
+
+public class StreamingWindowPrule extends RelOptRule {
+  public static final RelOptRule INSTANCE = new StreamingWindowPrule();
+
+  private StreamingWindowPrule() {
+    super(RelOptHelper.some(DrillWindowRel.class, DrillRel.DRILL_LOGICAL, 
RelOptHelper.any(RelNode.class)), "Prel.WindowPrule");
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final DrillWindowRel window = call.rel(0);
+    RelNode input = call.rel(1);
+
+    // TODO: Order window based on existing partition by
+    //input.getTraitSet().subsumes()
+
+    for (final Ord<WindowRelBase.Window> w : Ord.zip(window.windows)) {
+      WindowRelBase.Window windowBase = w.getValue();
+      DrillDistributionTrait distOnAllKeys =
+          new 
DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED,
+              ImmutableList.copyOf(getDistributionFields(windowBase)));
+
+      RelCollation collation = getCollation(windowBase);
+      RelTraitSet traits = 
call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL).plus(collation).plus(distOnAllKeys);
+      final RelNode convertedInput = convert(input, traits);
+
+      List<RelDataTypeField> newRowFields = Lists.newArrayList();
+      for(RelDataTypeField field : convertedInput.getRowType().getFieldList()) 
{
+        newRowFields.add(field);
+      }
+
+      Iterable<RelDataTypeField> newWindowFields = 
Iterables.filter(window.getRowType().getFieldList(), new 
Predicate<RelDataTypeField>() {
+            @Override
+            public boolean apply(RelDataTypeField relDataTypeField) {
+              return relDataTypeField.getName().startsWith("w" + w.i + "$");
+            }
+      });
+
+      for(RelDataTypeField newField : newWindowFields) {
+        newRowFields.add(newField);
+      }
+
+      RelDataType rowType = new RelRecordType(newRowFields);
+
+      List<WindowRelBase.RexWinAggCall> newWinAggCalls = Lists.newArrayList();
+      for(Ord<WindowRelBase.RexWinAggCall> aggOrd : 
Ord.zip(windowBase.aggCalls)) {
+        WindowRelBase.RexWinAggCall aggCall = aggOrd.getValue();
+        newWinAggCalls.add(new WindowRelBase.RexWinAggCall(
+            (SqlAggFunction)aggCall.getOperator(), aggCall.getType(), 
aggCall.getOperands(), aggOrd.i)
+        );
+      }
+
+      windowBase = new WindowRelBase.Window(
+          windowBase.groupSet,
+          windowBase.isRows,
+          windowBase.lowerBound,
+          windowBase.upperBound,
+          windowBase.orderKeys,
+          newWinAggCalls
+      );
+
+      input = new StreamingWindowPrel(
+          window.getCluster(),
+          window.getTraitSet().merge(traits),
+          convertedInput,
+          window.getConstants(),
+          rowType,
+          windowBase);
+    }
+
+    call.transformTo(input);
+  }
+
+  private RelCollation getCollation(WindowRelBase.Window window) {
+    List<RelFieldCollation> fields = Lists.newArrayList();
+    for (int group : BitSets.toIter(window.groupSet)) {
+      fields.add(new RelFieldCollation(group));
+    }
+    return RelCollationImpl.of(fields);
+  }
+
+  private List<DrillDistributionTrait.DistributionField> 
getDistributionFields(WindowRelBase.Window window) {
+    List<DrillDistributionTrait.DistributionField> groupByFields = 
Lists.newArrayList();
+    for (int group : BitSets.toIter(window.groupSet)) {
+      DrillDistributionTrait.DistributionField field = new 
DrillDistributionTrait.DistributionField(group);
+      groupByFields.add(field);
+    }
+    return groupByFields;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
index 85a5734..97d873c 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillOperatorTable.java
@@ -17,8 +17,8 @@
  */
 package org.apache.drill.exec.planner.sql;
 
-import java.util.List;
-
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Lists;
 import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry;
 import org.eigenbase.sql.SqlFunctionCategory;
 import org.eigenbase.sql.SqlIdentifier;
@@ -27,8 +27,7 @@ import org.eigenbase.sql.SqlOperatorTable;
 import org.eigenbase.sql.SqlSyntax;
 import org.eigenbase.sql.fun.SqlStdOperatorTable;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
+import java.util.List;
 
 public class DrillOperatorTable extends SqlStdOperatorTable {
   static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(DrillOperatorTable.class);

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
index 0b8668b..7ab2e9f 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlAggOperator.java
@@ -60,4 +60,4 @@ public class DrillSqlAggOperator extends SqlAggFunction {
   public RelDataType getReturnType(RelDataTypeFactory typeFactory) {
     return getAny(typeFactory);
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
index 2238155..2de46ee 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
@@ -28,7 +28,6 @@ import net.hydromatic.optiq.tools.Planner;
 import net.hydromatic.optiq.tools.RelConversionException;
 import net.hydromatic.optiq.tools.RuleSet;
 import net.hydromatic.optiq.tools.ValidationException;
-
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.physical.PhysicalPlan;
 import org.apache.drill.exec.planner.cost.DrillCostBase;
@@ -38,14 +37,19 @@ import 
org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
 import org.apache.drill.exec.planner.sql.handlers.DefaultSqlHandler;
 import org.apache.drill.exec.planner.sql.handlers.ExplainHandler;
 import org.apache.drill.exec.planner.sql.handlers.SetOptionHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
 import org.apache.drill.exec.planner.sql.parser.DrillSqlCall;
 import 
org.apache.drill.exec.planner.sql.parser.impl.DrillParserWithCompoundIdConverter;
 import org.apache.drill.exec.store.StoragePluginRegistry;
 import org.apache.drill.exec.util.Pointer;
 import org.eigenbase.rel.RelCollationTraitDef;
+import org.eigenbase.rel.rules.ReduceExpressionsRule;
+import org.eigenbase.rel.rules.WindowedAggSplitterRule;
 import org.eigenbase.relopt.ConventionTraitDef;
 import org.eigenbase.relopt.RelOptCostFactory;
 import org.eigenbase.relopt.RelTraitDef;
+import org.eigenbase.relopt.hep.HepPlanner;
+import org.eigenbase.relopt.hep.HepProgramBuilder;
 import org.eigenbase.sql.SqlNode;
 import org.eigenbase.sql.parser.SqlParseException;
 
@@ -53,6 +57,7 @@ public class DrillSqlWorker {
   static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(DrillSqlWorker.class);
 
   private final Planner planner;
+  private final HepPlanner hepPlanner;
   public final static int LOGICAL_RULES = 0;
   public final static int PHYSICAL_MEM_RULES = 1;
   private final QueryContext context;
@@ -79,7 +84,12 @@ public class DrillSqlWorker {
         .costFactory(costFactory) //
         .build();
     this.planner = Frameworks.getPlanner(config);
-
+    HepProgramBuilder builder = new HepProgramBuilder();
+    builder.addRuleClass(ReduceExpressionsRule.class);
+    builder.addRuleClass(WindowedAggSplitterRule.class);
+    this.hepPlanner = new HepPlanner(builder.build());
+    hepPlanner.addRule(ReduceExpressionsRule.CALC_INSTANCE);
+    hepPlanner.addRule(WindowedAggSplitterRule.PROJECT);
   }
 
   private RuleSet[] getRules(QueryContext context) {
@@ -99,23 +109,24 @@ public class DrillSqlWorker {
     SqlNode sqlNode = planner.parse(sql);
 
     AbstractSqlHandler handler;
+    SqlHandlerConfig config = new SqlHandlerConfig(hepPlanner, planner, 
context);
 
     // TODO: make this use path scanning or something similar.
     switch(sqlNode.getKind()){
     case EXPLAIN:
-      handler = new ExplainHandler(planner, context);
+      handler = new ExplainHandler(config);
       break;
     case SET_OPTION:
       handler = new SetOptionHandler(context);
       break;
     case OTHER:
       if (sqlNode instanceof DrillSqlCall) {
-        handler = ((DrillSqlCall)sqlNode).getSqlHandler(planner, context);
+        handler = ((DrillSqlCall)sqlNode).getSqlHandler(config);
         break;
       }
       // fallthrough
     default:
-      handler = new DefaultSqlHandler(planner, context, textPlan);
+      handler = new DefaultSqlHandler(config, textPlan);
     }
 
     return handler.getPlan(sqlNode);

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
index 708951a..df2f807 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
@@ -40,13 +40,14 @@ import 
org.apache.drill.exec.planner.types.DrillFixedRelDataTypeImpl;
 import org.apache.drill.exec.store.AbstractSchema;
 import org.eigenbase.rel.RelNode;
 import org.eigenbase.relopt.RelOptUtil;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.reltype.RelDataType;
 import org.eigenbase.sql.SqlNode;
 
 public class CreateTableHandler extends DefaultSqlHandler {
 
-  public CreateTableHandler(Planner planner, QueryContext context) {
-    super(planner, context);
+  public CreateTableHandler(SqlHandlerConfig config) {
+    super(config);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
index e63474f..0bb59bf 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
@@ -60,6 +60,7 @@ import org.apache.drill.exec.util.Pointer;
 import org.eigenbase.rel.RelNode;
 import org.eigenbase.relopt.RelOptUtil;
 import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlExplainLevel;
 import org.eigenbase.sql.SqlNode;
 
@@ -70,19 +71,23 @@ import com.google.common.collect.Lists;
 public class DefaultSqlHandler extends AbstractSqlHandler {
   static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(DefaultSqlHandler.class);
 
-  protected final Planner planner;
+  protected final SqlHandlerConfig config;
   protected final QueryContext context;
+  protected final HepPlanner hepPlanner;
+  protected final Planner planner;
   private Pointer<String> textPlan;
   private final long targetSliceSize;
 
-  public DefaultSqlHandler(Planner planner, QueryContext context) {
-    this(planner, context, null);
+  public DefaultSqlHandler(SqlHandlerConfig config) {
+    this(config, null);
   }
 
-  public DefaultSqlHandler(Planner planner, QueryContext context, 
Pointer<String> textPlan) {
+  public DefaultSqlHandler(SqlHandlerConfig config, Pointer<String> textPlan) {
     super();
-    this.planner = planner;
-    this.context = context;
+    this.planner = config.getPlanner();
+    this.context = config.getContext();
+    this.hepPlanner = config.getHepPlanner();
+    this.config = config;
     this.textPlan = textPlan;
     targetSliceSize = 
context.getOptions().getOption(ExecConstants.SLICE_TARGET).num_val;
   }
@@ -139,7 +144,9 @@ public class DefaultSqlHandler extends AbstractSqlHandler {
   }
 
   protected RelNode convertToRel(SqlNode node) throws RelConversionException {
-    return planner.convert(node);
+    RelNode convertedNode = planner.convert(node);
+    hepPlanner.setRoot(convertedNode);
+    return hepPlanner.findBestExp();
   }
 
   protected DrillRel convertToDrel(RelNode relNode) throws 
RelConversionException {

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
index e6f1fe1..84082e3 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
@@ -30,6 +30,7 @@ import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.parser.DrillParserUtil;
 import org.apache.drill.exec.planner.sql.parser.SqlDescribeTable;
 import org.apache.drill.exec.store.AbstractSchema;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlIdentifier;
 import org.eigenbase.sql.SqlLiteral;
 import org.eigenbase.sql.SqlNode;
@@ -43,7 +44,7 @@ import com.google.common.collect.ImmutableList;
 
 public class DescribeTableHandler extends DefaultSqlHandler {
 
-  public DescribeTableHandler(Planner planner, QueryContext context) { 
super(planner, context); }
+  public DescribeTableHandler(SqlHandlerConfig config) { super(config); }
 
   /** Rewrite the parse tree as SELECT ... FROM INFORMATION_SCHEMA.COLUMNS ... 
*/
   @Override
@@ -104,4 +105,3 @@ public class DescribeTableHandler extends DefaultSqlHandler 
{
     }
   }
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ExplainHandler.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ExplainHandler.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ExplainHandler.java
index f324321..8beed34 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ExplainHandler.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ExplainHandler.java
@@ -17,12 +17,8 @@
  */
 package org.apache.drill.exec.planner.sql.handlers;
 
-import java.io.IOException;
-
-import net.hydromatic.optiq.tools.Planner;
 import net.hydromatic.optiq.tools.RelConversionException;
 import net.hydromatic.optiq.tools.ValidationException;
-
 import org.apache.drill.common.logical.LogicalPlan;
 import org.apache.drill.common.logical.PlanProperties.Generator.ResultMode;
 import org.apache.drill.exec.ops.QueryContext;
@@ -41,13 +37,15 @@ import org.eigenbase.sql.SqlExplainLevel;
 import org.eigenbase.sql.SqlLiteral;
 import org.eigenbase.sql.SqlNode;
 
+import java.io.IOException;
+
 public class ExplainHandler extends DefaultSqlHandler {
   static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(ExplainHandler.class);
 
   private ResultMode mode;
   private SqlExplainLevel level = SqlExplainLevel.ALL_ATTRIBUTES;
-  public ExplainHandler(Planner planner, QueryContext context) {
-    super(planner, context);
+  public ExplainHandler(SqlHandlerConfig config) {
+    super(config);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowFileHandler.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowFileHandler.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowFileHandler.java
index 3627a7b..ff3542d 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowFileHandler.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowFileHandler.java
@@ -35,6 +35,7 @@ import 
org.apache.drill.exec.store.dfs.WorkspaceSchemaFactory.WorkspaceSchema;
 import org.apache.drill.exec.store.dfs.shim.DrillFileSystem;
 import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.Path;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlIdentifier;
 import org.eigenbase.sql.SqlNode;
 
@@ -42,8 +43,8 @@ import org.eigenbase.sql.SqlNode;
 public class ShowFileHandler extends DefaultSqlHandler {
   static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(SetOptionHandler.class);
 
-  public ShowFileHandler(Planner planner, QueryContext context) {
-    super(planner, context);
+  public ShowFileHandler(SqlHandlerConfig config) {
+    super(config);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowSchemasHandler.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowSchemasHandler.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowSchemasHandler.java
index 5e77628..b055218 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowSchemasHandler.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowSchemasHandler.java
@@ -26,6 +26,7 @@ import net.hydromatic.optiq.tools.RelConversionException;
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.parser.DrillParserUtil;
 import org.apache.drill.exec.planner.sql.parser.SqlShowSchemas;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlIdentifier;
 import org.eigenbase.sql.SqlNode;
 import org.eigenbase.sql.SqlNodeList;
@@ -37,7 +38,7 @@ import com.google.common.collect.ImmutableList;
 
 public class ShowSchemasHandler extends DefaultSqlHandler {
 
-  public ShowSchemasHandler(Planner planner, QueryContext context) { 
super(planner, context); }
+  public ShowSchemasHandler(SqlHandlerConfig config) { super(config); }
 
   /** Rewrite the parse tree as SELECT ... FROM INFORMATION_SCHEMA.SCHEMATA 
... */
   @Override
@@ -61,4 +62,3 @@ public class ShowSchemasHandler extends DefaultSqlHandler {
         fromClause, where, null, null, null, null, null, null);
   }
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowTablesHandler.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowTablesHandler.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowTablesHandler.java
index a1c5aee..0a029f7 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowTablesHandler.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ShowTablesHandler.java
@@ -35,6 +35,7 @@ import org.eigenbase.sql.SqlLiteral;
 import org.eigenbase.sql.SqlNode;
 import org.eigenbase.sql.SqlNodeList;
 import org.eigenbase.sql.SqlSelect;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.fun.SqlStdOperatorTable;
 import org.eigenbase.sql.parser.SqlParserPos;
 
@@ -43,7 +44,7 @@ import com.google.common.collect.Lists;
 
 public class ShowTablesHandler extends DefaultSqlHandler {
 
-  public ShowTablesHandler(Planner planner, QueryContext context) { 
super(planner, context); }
+  public ShowTablesHandler(SqlHandlerConfig config) { super(config); }
 
   /** Rewrite the parse tree as SELECT ... FROM INFORMATION_SCHEMA.`TABLES` 
... */
   @Override
@@ -105,4 +106,3 @@ public class ShowTablesHandler extends DefaultSqlHandler {
         fromClause, where, null, null, null, null, null, null);
   }
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/SqlHandlerConfig.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/SqlHandlerConfig.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/SqlHandlerConfig.java
new file mode 100644
index 0000000..132a2c9
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/SqlHandlerConfig.java
@@ -0,0 +1,47 @@
+/**
+ * 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.drill.exec.planner.sql.handlers;
+
+import net.hydromatic.optiq.tools.Planner;
+import org.apache.drill.exec.ops.QueryContext;
+import org.eigenbase.relopt.hep.HepPlanner;
+
+public class SqlHandlerConfig {
+  private final QueryContext context;
+  private final HepPlanner hepPlanner;
+  private final Planner planner;
+
+  public SqlHandlerConfig(HepPlanner hepPlanner, Planner planner, QueryContext 
context) {
+    this.hepPlanner = hepPlanner;
+    this.planner = planner;
+    this.context = context;
+  }
+
+  public Planner getPlanner() {
+    return planner;
+  }
+
+  public HepPlanner getHepPlanner() {
+    return hepPlanner;
+  }
+
+  public QueryContext getContext() {
+    return context;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java
index 4005b81..a6bd8b7 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java
@@ -22,6 +22,8 @@ import net.hydromatic.optiq.tools.Planner;
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
 import org.apache.drill.exec.planner.sql.handlers.DefaultSqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.parser.SqlParserPos;
 
@@ -34,7 +36,7 @@ public abstract class DrillSqlCall extends SqlCall {
     super(pos);
   }
 
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new DefaultSqlHandler(planner, context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new DefaultSqlHandler(config);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateTable.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateTable.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateTable.java
index 10db4c4..5e3c215 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateTable.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateTable.java
@@ -24,6 +24,8 @@ import net.hydromatic.optiq.tools.Planner;
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
 import org.apache.drill.exec.planner.sql.handlers.CreateTableHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.SqlIdentifier;
 import org.eigenbase.sql.SqlKind;
@@ -90,8 +92,8 @@ public class SqlCreateTable extends DrillSqlCall {
   }
 
   @Override
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new CreateTableHandler(planner, context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new CreateTableHandler(config);
   }
 
   public List<String> getSchemaPath() {

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java
index ccd08e1..b7352b4 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java
@@ -17,12 +17,10 @@
  */
 package org.apache.drill.exec.planner.sql.parser;
 
-import java.util.List;
-
-import net.hydromatic.optiq.tools.Planner;
-
-import org.apache.drill.exec.ops.QueryContext;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
 import org.apache.drill.exec.planner.sql.handlers.ViewHandler;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.SqlIdentifier;
@@ -35,8 +33,7 @@ import org.eigenbase.sql.SqlSpecialOperator;
 import org.eigenbase.sql.SqlWriter;
 import org.eigenbase.sql.parser.SqlParserPos;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
+import java.util.List;
 
 public class SqlCreateView extends DrillSqlCall {
   public static final SqlSpecialOperator OPERATOR = new 
SqlSpecialOperator("CREATE_VIEW", SqlKind.OTHER) {
@@ -103,8 +100,8 @@ public class SqlCreateView extends DrillSqlCall {
   }
 
   @Override
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new ViewHandler.CreateView(planner, context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new ViewHandler.CreateView(config.getPlanner(), 
config.getContext());
   }
 
   public List<String> getSchemaPath() {

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
index 29275d7..7d464e1 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
@@ -24,6 +24,8 @@ import net.hydromatic.optiq.tools.Planner;
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
 import org.apache.drill.exec.planner.sql.handlers.DescribeTableHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.SqlIdentifier;
 import org.eigenbase.sql.SqlKind;
@@ -89,8 +91,8 @@ public class SqlDescribeTable extends DrillSqlCall {
   }
 
   @Override
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new DescribeTableHandler(planner, context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new DescribeTableHandler(config);
   }
 
   public SqlIdentifier getTable() { return table; }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java
index 33b71b7..a0d6f7b 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java
@@ -24,7 +24,9 @@ import net.hydromatic.optiq.tools.Planner;
 
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
 import org.apache.drill.exec.planner.sql.handlers.ViewHandler.DropView;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.SqlIdentifier;
 import org.eigenbase.sql.SqlKind;
@@ -70,8 +72,8 @@ public class SqlDropView extends DrillSqlCall {
   }
 
   @Override
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new DropView(context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new DropView(config.getContext());
   }
 
   public List<String> getSchemaPath() {

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowFiles.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowFiles.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowFiles.java
index 8779969..38abfeb 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowFiles.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowFiles.java
@@ -25,6 +25,8 @@ import net.hydromatic.optiq.tools.Planner;
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
 import org.apache.drill.exec.planner.sql.handlers.ShowFileHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.SqlIdentifier;
 import org.eigenbase.sql.SqlKind;
@@ -76,8 +78,8 @@ public class SqlShowFiles extends DrillSqlCall {
   }
 
   @Override
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new ShowFileHandler(planner, context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new ShowFileHandler(config);
   }
 
   public SqlIdentifier getDb() { return db; }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
index 9b42295..9d8771a 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
@@ -24,6 +24,8 @@ import net.hydromatic.optiq.tools.Planner;
 import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
 import org.apache.drill.exec.planner.sql.handlers.ShowSchemasHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
+import org.eigenbase.relopt.hep.HepPlanner;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.SqlKind;
 import org.eigenbase.sql.SqlLiteral;
@@ -85,8 +87,8 @@ public class SqlShowSchemas extends DrillSqlCall {
   }
 
   @Override
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new ShowSchemasHandler(planner, context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new ShowSchemasHandler(config);
   }
 
   public SqlNode getLikePattern() { return likePattern; }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
index 33d20aa..da3f0fd 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
@@ -17,13 +17,10 @@
  */
 package org.apache.drill.exec.planner.sql.parser;
 
-import java.util.List;
-
-import net.hydromatic.optiq.tools.Planner;
-
-import org.apache.drill.exec.ops.QueryContext;
+import com.google.common.collect.Lists;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
 import org.apache.drill.exec.planner.sql.handlers.ShowTablesHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.SqlIdentifier;
 import org.eigenbase.sql.SqlKind;
@@ -34,7 +31,7 @@ import org.eigenbase.sql.SqlSpecialOperator;
 import org.eigenbase.sql.SqlWriter;
 import org.eigenbase.sql.parser.SqlParserPos;
 
-import com.google.common.collect.Lists;
+import java.util.List;
 
 /**
  * Sql parse tree node to represent statement:
@@ -92,8 +89,8 @@ public class SqlShowTables extends DrillSqlCall {
   }
 
   @Override
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new ShowTablesHandler(planner, context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new ShowTablesHandler(config);
   }
 
   public SqlIdentifier getDb() { return db; }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
index ed4695e..c8af002 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
@@ -17,13 +17,8 @@
  */
 package org.apache.drill.exec.planner.sql.parser;
 
-import java.util.Collections;
-import java.util.List;
-
-import net.hydromatic.optiq.tools.Planner;
-
-import org.apache.drill.exec.ops.QueryContext;
 import org.apache.drill.exec.planner.sql.handlers.AbstractSqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandlerConfig;
 import org.apache.drill.exec.planner.sql.handlers.UseSchemaHandler;
 import org.eigenbase.sql.SqlCall;
 import org.eigenbase.sql.SqlIdentifier;
@@ -35,6 +30,9 @@ import org.eigenbase.sql.SqlSpecialOperator;
 import org.eigenbase.sql.SqlWriter;
 import org.eigenbase.sql.parser.SqlParserPos;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Sql parser tree node to represent <code>USE SCHEMA</code> statement.
  */
@@ -73,8 +71,8 @@ public class SqlUseSchema extends DrillSqlCall {
   }
 
   @Override
-  public AbstractSqlHandler getSqlHandler(Planner planner, QueryContext 
context) {
-    return new UseSchemaHandler(context);
+  public AbstractSqlHandler getSqlHandler(SqlHandlerConfig config) {
+    return new UseSchemaHandler(config.getContext());
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/record/AbstractSingleRecordBatch.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/record/AbstractSingleRecordBatch.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/record/AbstractSingleRecordBatch.java
index 0adc09e..f05243d 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/record/AbstractSingleRecordBatch.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/record/AbstractSingleRecordBatch.java
@@ -27,6 +27,7 @@ public abstract class AbstractSingleRecordBatch<T extends 
PhysicalOperator> exte
 
   protected final RecordBatch incoming;
   private boolean first = true;
+  protected boolean done = false;
   protected boolean outOfMemory = false;
 
   public AbstractSingleRecordBatch(T popConfig, FragmentContext context, 
RecordBatch incoming) throws OutOfMemoryException {
@@ -41,6 +42,11 @@ public abstract class AbstractSingleRecordBatch<T extends 
PhysicalOperator> exte
 
   @Override
   public IterOutcome innerNext() {
+    // Short circuit if record batch has already sent all data and is done
+    if (done) {
+      return IterOutcome.NONE;
+    }
+
     IterOutcome upstream = next(incoming);
     if (!first && upstream == IterOutcome.OK && incoming.getRecordCount() == 
0) {
       do {
@@ -100,6 +106,5 @@ public abstract class AbstractSingleRecordBatch<T extends 
PhysicalOperator> exte
   }
 
   protected abstract void setupNewSchema() throws SchemaChangeException;
-  protected abstract void doWork();
-
+  protected abstract IterOutcome doWork();
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/main/java/org/apache/drill/exec/record/VectorContainer.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/record/VectorContainer.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/record/VectorContainer.java
index e2f4a95..b1b7c76 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/record/VectorContainer.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/record/VectorContainer.java
@@ -105,6 +105,23 @@ public class VectorContainer extends AbstractMapVector 
implements Iterable<Vecto
     return vc;
   }
 
+  public static VectorContainer getTransferClone(VectorAccessible incoming, 
VectorWrapper[] ignoreWrappers) {
+    VectorContainer vc = new VectorContainer();
+    for (VectorWrapper<?> w : incoming) {
+      if(ignoreWrappers != null) {
+        for(VectorWrapper wrapper : ignoreWrappers) {
+          if (w == wrapper) {
+            continue;
+          }
+        }
+      }
+
+      vc.cloneAndTransfer(w);
+    }
+
+    return vc;
+  }
+
   public static VectorContainer canonicalize(VectorContainer original) {
     VectorContainer vc = new VectorContainer();
     List<VectorWrapper<?>> canonicalWrappers = new 
ArrayList<VectorWrapper<?>>(original.wrappers);

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/test/java/org/apache/drill/exec/ExecTest.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/ExecTest.java 
b/exec/java-exec/src/test/java/org/apache/drill/exec/ExecTest.java
index e7c6dc0..0272b23 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/ExecTest.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/ExecTest.java
@@ -21,7 +21,7 @@ import org.apache.drill.exec.metrics.DrillMetrics;
 import org.apache.drill.test.DrillTest;
 import org.junit.After;
 
-public class ExecTest extends DrillTest{
+public class ExecTest extends DrillTest {
 
   @After
   public void clear(){

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestSimpleLimit.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestSimpleLimit.java
 
b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestSimpleLimit.java
index 3ba6cb1..7cdb41a 100644
--- 
a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestSimpleLimit.java
+++ 
b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestSimpleLimit.java
@@ -117,6 +117,7 @@ public class TestSimpleLimit extends ExecTest {
     if(context.getFailureCause() != null){
       throw context.getFailureCause();
     }
+
     assertTrue(!context.isFailed());
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/window/TestWindowFrame.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/window/TestWindowFrame.java
 
b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/window/TestWindowFrame.java
new file mode 100644
index 0000000..ac7b035
--- /dev/null
+++ 
b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/window/TestWindowFrame.java
@@ -0,0 +1,202 @@
+/**
+ * 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.drill.exec.physical.impl.window;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import org.apache.drill.common.config.DrillConfig;
+import org.apache.drill.common.expression.PathSegment;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.util.FileUtils;
+import org.apache.drill.exec.client.DrillClient;
+import org.apache.drill.exec.pop.PopUnitTestBase;
+import org.apache.drill.exec.proto.UserBitShared;
+import org.apache.drill.exec.record.RecordBatchLoader;
+import org.apache.drill.exec.record.VectorWrapper;
+import org.apache.drill.exec.rpc.user.QueryResultBatch;
+import org.apache.drill.exec.server.Drillbit;
+import org.apache.drill.exec.server.RemoteServiceSet;
+import org.apache.drill.exec.vector.BigIntVector;
+import org.apache.drill.exec.vector.NullableBigIntVector;
+import org.apache.drill.exec.vector.ValueVector;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestWindowFrame extends PopUnitTestBase {
+
+  @Test
+  public void testWindowFrameWithOneKeyCount() throws Throwable {
+    try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
+         Drillbit bit = new Drillbit(CONFIG, serviceSet);
+         DrillClient client = new DrillClient(CONFIG, 
serviceSet.getCoordinator())) {
+
+      // run query.
+      bit.run();
+      client.connect();
+      List<QueryResultBatch> results = 
client.runQuery(UserBitShared.QueryType.PHYSICAL,
+          
Files.toString(FileUtils.getResourceAsFile("/window/oneKeyCount.json"), 
Charsets.UTF_8)
+              .replace("#{DATA_FILE}", 
FileUtils.getResourceAsFile("/window/oneKeyCountData.json").toURI().toString())
+      );
+
+      long[] cntArr = {1, 2, 1, 2};
+      long[] sumArr = {100, 150, 25, 75};
+
+      // look at records
+      RecordBatchLoader batchLoader = new 
RecordBatchLoader(bit.getContext().getAllocator());
+      int recordCount = 0;
+
+      assertEquals(2, results.size());
+
+      QueryResultBatch batch = results.get(0);
+      assertTrue(batchLoader.load(batch.getHeader().getDef(), 
batch.getData()));
+      batchLoader.load(batch.getHeader().getDef(), batch.getData());
+
+      for (int r = 0; r < batchLoader.getRecordCount(); r++) {
+        recordCount++;
+        VectorWrapper<?> wrapper = batchLoader.getValueAccessorById(
+            BigIntVector.class,
+            batchLoader.getValueVectorId(new SchemaPath(new 
PathSegment.NameSegment("cnt"))).getFieldIds()[0]
+        );
+        assertEquals(cntArr[r], 
wrapper.getValueVector().getAccessor().getObject(r));
+        wrapper = batchLoader.getValueAccessorById(
+            NullableBigIntVector.class,
+            batchLoader.getValueVectorId(new SchemaPath(new 
PathSegment.NameSegment("sum"))).getFieldIds()[0]
+        );
+        assertEquals(sumArr[r], 
wrapper.getValueVector().getAccessor().getObject(r));
+      }
+      batchLoader.clear();
+      batch.release();
+
+      assertEquals(4, recordCount);
+    }
+  }
+
+  @Test
+  public void testWindowFrameWithOneKeyMultipleBatches() throws Throwable {
+    try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
+         Drillbit bit = new Drillbit(CONFIG, serviceSet);
+         DrillClient client = new DrillClient(CONFIG, 
serviceSet.getCoordinator())) {
+
+      // run query.
+      bit.run();
+      client.connect();
+      List<QueryResultBatch> results = 
client.runQuery(UserBitShared.QueryType.PHYSICAL,
+          
Files.toString(FileUtils.getResourceAsFile("/window/oneKeyCountMultiBatch.json"),
 Charsets.UTF_8)
+              .replace("#{DATA_FILE}", 
FileUtils.getResourceAsFile("/window/mediumData.json").toURI().toString()));
+
+      // look at records
+      RecordBatchLoader batchLoader = new 
RecordBatchLoader(bit.getContext().getAllocator());
+      int recordCount = 0;
+
+      assertEquals(2, results.size());
+
+      QueryResultBatch batch = results.get(0);
+      assertTrue(batchLoader.load(batch.getHeader().getDef(), 
batch.getData()));
+      batchLoader.load(batch.getHeader().getDef(), batch.getData());
+      ValueVector.Accessor output = 
batchLoader.getValueAccessorById(NullableBigIntVector.class,
+          batchLoader.getValueVectorId(
+              new SchemaPath(new 
PathSegment.NameSegment("output"))).getFieldIds()[0]
+      ).getValueVector().getAccessor();
+      ValueVector.Accessor sum = batchLoader.getValueAccessorById(
+          BigIntVector.class,
+          batchLoader.getValueVectorId(
+              new SchemaPath(new 
PathSegment.NameSegment("sum"))).getFieldIds()[0]
+      ).getValueVector().getAccessor();
+      ValueVector.Accessor cnt = batchLoader.getValueAccessorById(
+          BigIntVector.class,
+          batchLoader.getValueVectorId(
+              new SchemaPath(new 
PathSegment.NameSegment("cnt"))).getFieldIds()[0]
+      ).getValueVector().getAccessor();
+      int lastGroup = -1;
+      long groupCounter = 0;
+      long s = 0;
+      for (int r = 1; r <= batchLoader.getRecordCount(); r++) {
+        recordCount++;
+        int group = r / 4;
+        if(lastGroup != group) {
+          lastGroup = group;
+          groupCounter = 1;
+          s = 0;
+        } else {
+          groupCounter++;
+        }
+
+        s += group * 8 + r % 4;
+
+        assertEquals("Count, Row " + r, groupCounter, cnt.getObject(r - 1));
+        assertEquals("Sum, Row " + r, s, sum.getObject(r - 1));
+        assertEquals("Output, Row " + r, s, output.getObject(r - 1));
+      }
+      batchLoader.clear();
+      batch.release();
+
+      assertEquals(1000, recordCount);
+    }
+  }
+
+  @Test
+  public void testWindowFrameWithTwoKeys() throws Throwable {
+    try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
+         Drillbit bit = new Drillbit(CONFIG, serviceSet);
+         DrillClient client = new DrillClient(CONFIG, 
serviceSet.getCoordinator())) {
+
+      // run query.
+      bit.run();
+      client.connect();
+      List<QueryResultBatch> results = 
client.runQuery(UserBitShared.QueryType.PHYSICAL,
+          Files.toString(FileUtils.getResourceAsFile("/window/twoKeys.json"), 
Charsets.UTF_8)
+              .replace("#{DATA_FILE}", 
FileUtils.getResourceAsFile("/window/twoKeysData.json").toURI().toString())
+      );
+
+      long[] cntArr = {1, 2, 1, 2, 1, 2, 1, 2};
+      long[] sumArr = {5, 15, 15, 35, 25, 55, 35, 75};
+
+      // look at records
+      RecordBatchLoader batchLoader = new 
RecordBatchLoader(bit.getContext().getAllocator());
+      int recordCount = 0;
+
+      assertEquals(2, results.size());
+
+      QueryResultBatch batch = results.get(0);
+      assertTrue(batchLoader.load(batch.getHeader().getDef(), 
batch.getData()));
+      batchLoader.load(batch.getHeader().getDef(), batch.getData());
+
+      for (int r = 0; r < batchLoader.getRecordCount(); r++) {
+        recordCount++;
+        VectorWrapper<?> wrapper = batchLoader.getValueAccessorById(
+            BigIntVector.class,
+            batchLoader.getValueVectorId(new SchemaPath(new 
PathSegment.NameSegment("cnt"))).getFieldIds()[0]
+        );
+        assertEquals(cntArr[r], 
wrapper.getValueVector().getAccessor().getObject(r));
+        wrapper = batchLoader.getValueAccessorById(
+            NullableBigIntVector.class,
+            batchLoader.getValueVectorId(new SchemaPath(new 
PathSegment.NameSegment("sum"))).getFieldIds()[0]
+        );
+        assertEquals(sumArr[r], 
wrapper.getValueVector().getAccessor().getObject(r));
+      }
+      batchLoader.clear();
+      batch.release();
+
+      assertEquals(8, recordCount);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/8def6e91/exec/java-exec/src/test/java/org/apache/drill/exec/sql/TestWindowFunctions.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/test/java/org/apache/drill/exec/sql/TestWindowFunctions.java
 
b/exec/java-exec/src/test/java/org/apache/drill/exec/sql/TestWindowFunctions.java
new file mode 100644
index 0000000..780a7ce
--- /dev/null
+++ 
b/exec/java-exec/src/test/java/org/apache/drill/exec/sql/TestWindowFunctions.java
@@ -0,0 +1,29 @@
+/**
+ * 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.drill.exec.sql;
+
+import org.apache.drill.BaseTestQuery;
+import org.junit.Test;
+
+public class TestWindowFunctions extends BaseTestQuery {
+  @Test
+  public void testWindowSum() throws Exception {
+    test("select sum(position_id) over w from cp.`employee.json` window w as ( 
partition by position_id order by position_id)");
+  }
+}

Reply via email to