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)"); + } +}