From c5c2eda7997c5dfb9335b02a25272c0e6ddc48b1 Mon Sep 17 00:00:00 2001 From: adeneche Date: Tue, 19 Jan 2016 13:33:22 -0800 Subject: [PATCH 1/4] passing WindowPOP to window functions and framers --- .../impl/window/FrameSupportTemplate.java | 3 +- .../impl/window/NoFrameSupportTemplate.java | 3 +- .../impl/window/WindowFrameRecordBatch.java | 8 ++-- .../physical/impl/window/WindowFramer.java | 3 +- .../physical/impl/window/WindowFunction.java | 43 ++++++++++--------- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/FrameSupportTemplate.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/FrameSupportTemplate.java index 16c751349fb..36bccb35116 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/FrameSupportTemplate.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/FrameSupportTemplate.java @@ -20,6 +20,7 @@ import org.apache.drill.common.exceptions.DrillException; import org.apache.drill.exec.exception.SchemaChangeException; import org.apache.drill.exec.ops.OperatorContext; +import org.apache.drill.exec.physical.config.WindowPOP; import org.apache.drill.exec.record.VectorAccessible; import org.apache.drill.exec.record.VectorContainer; import org.apache.drill.exec.record.VectorWrapper; @@ -54,7 +55,7 @@ public abstract class FrameSupportTemplate implements WindowFramer { @Override public void setup(final List batches, final VectorContainer container, final OperatorContext oContext, - final boolean requireFullPartition) throws SchemaChangeException { + final boolean requireFullPartition, final WindowPOP popConfig) throws SchemaChangeException { this.container = container; this.batches = batches; diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/NoFrameSupportTemplate.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/NoFrameSupportTemplate.java index ac1eefc9965..21dfbba91e7 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/NoFrameSupportTemplate.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/NoFrameSupportTemplate.java @@ -20,6 +20,7 @@ import org.apache.drill.common.exceptions.DrillException; import org.apache.drill.exec.exception.SchemaChangeException; import org.apache.drill.exec.ops.OperatorContext; +import org.apache.drill.exec.physical.config.WindowPOP; import org.apache.drill.exec.record.VectorAccessible; import org.apache.drill.exec.record.VectorContainer; import org.apache.drill.exec.record.VectorWrapper; @@ -53,7 +54,7 @@ public abstract class NoFrameSupportTemplate implements WindowFramer { @Override public void setup(final List batches, final VectorContainer container, final OperatorContext oContext, - final boolean requireFullPartition) throws SchemaChangeException { + final boolean requireFullPartition, final WindowPOP popConfig) throws SchemaChangeException { this.container = container; this.batches = batches; diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFrameRecordBatch.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFrameRecordBatch.java index d6be1eb9bdd..46a6c0ea244 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFrameRecordBatch.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFrameRecordBatch.java @@ -212,7 +212,7 @@ private boolean canDoWork() { final boolean frameEndReached = partitionEndReached || !framers[0].isPeer(currentSize - 1, current, lastSize - 1, last); for (final WindowFunction function : functions) { - if (!function.canDoWork(batches.size(), hasOrderBy, frameEndReached, partitionEndReached)) { + if (!function.canDoWork(batches.size(), popConfig, frameEndReached, partitionEndReached)) { return false; } } @@ -279,7 +279,7 @@ private void createFramers(VectorAccessible batch) throws SchemaChangeException, final WindowFunction winfun = WindowFunction.fromExpression(call); if (winfun.materialize(ne, container, context.getFunctionRegistry())) { functions.add(winfun); - requireFullPartition |= winfun.requiresFullPartition(hasOrderBy); + requireFullPartition |= winfun.requiresFullPartition(popConfig); if (winfun.supportsCustomFrames()) { useCustomFrame = true; @@ -311,13 +311,13 @@ private void createFramers(VectorAccessible batch) throws SchemaChangeException, int index = 0; if (useDefaultFrame) { framers[index] = generateFramer(keyExprs, orderExprs, functions, false); - framers[index].setup(batches, container, oContext, requireFullPartition); + framers[index].setup(batches, container, oContext, requireFullPartition, popConfig); index++; } if (useCustomFrame) { framers[index] = generateFramer(keyExprs, orderExprs, functions, true); - framers[index].setup(batches, container, oContext, requireFullPartition); + framers[index].setup(batches, container, oContext, requireFullPartition, popConfig); } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFramer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFramer.java index 9b985c0cf3d..3d2d0fc3c8b 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFramer.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFramer.java @@ -21,6 +21,7 @@ import org.apache.drill.exec.compile.TemplateClassDefinition; import org.apache.drill.exec.exception.SchemaChangeException; import org.apache.drill.exec.ops.OperatorContext; +import org.apache.drill.exec.physical.config.WindowPOP; import org.apache.drill.exec.record.VectorAccessible; import org.apache.drill.exec.record.VectorContainer; @@ -32,7 +33,7 @@ public interface WindowFramer { TemplateClassDefinition FRAME_TEMPLATE_DEFINITION = new TemplateClassDefinition<>(WindowFramer.class, FrameSupportTemplate.class); void setup(final List batches, final VectorContainer container, final OperatorContext operatorContext, - final boolean requireFullPartition) throws SchemaChangeException; + final boolean requireFullPartition, final WindowPOP popConfig) throws SchemaChangeException; /** * process the inner batch and write the aggregated values in the container diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFunction.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFunction.java index 1c712972c9a..0116bd0c5f0 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFunction.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFunction.java @@ -36,6 +36,7 @@ import org.apache.drill.exec.expr.ValueVectorReadExpression; import org.apache.drill.exec.expr.ValueVectorWriteExpression; import org.apache.drill.exec.expr.fn.FunctionLookupContext; +import org.apache.drill.exec.physical.config.WindowPOP; import org.apache.drill.exec.record.MaterializedField; import org.apache.drill.exec.record.TypedFieldId; import org.apache.drill.exec.record.VectorContainer; @@ -95,23 +96,23 @@ static WindowFunction fromExpression(final FunctionCall call) { abstract boolean supportsCustomFrames(); /** - * @param hasOrderBy window definition contains an ORDER BY clause + * @param pop window group definition * @return true if this window function requires all batches of current partition to be available before processing * the first batch */ - public boolean requiresFullPartition(final boolean hasOrderBy) { + public boolean requiresFullPartition(final WindowPOP pop) { return true; } /** * @param numBatchesAvailable number of batches available for current partition - * @param hasOrderBy window definition contains an ORDER BY clause + * @param pop window group definition * @param frameEndReached we found the last row of the first batch's frame * @param partitionEndReached all batches of current partition are available * * @return true if this window function can process the first batch immediately */ - public boolean canDoWork(final int numBatchesAvailable, final boolean hasOrderBy, final boolean frameEndReached, + public boolean canDoWork(final int numBatchesAvailable, final WindowPOP pop, final boolean frameEndReached, final boolean partitionEndReached) { return partitionEndReached; } @@ -155,13 +156,13 @@ void generateCode(ClassGenerator cg) { } @Override - public boolean requiresFullPartition(final boolean hasOrderBy) { - return !hasOrderBy; + public boolean requiresFullPartition(final WindowPOP pop) { + return pop.getOrderings().length == 0; } @Override - public boolean canDoWork(int numBatchesAvailable, boolean hasOrderBy, boolean frameEndReached, boolean partitionEndReached) { - return partitionEndReached || (hasOrderBy && frameEndReached); + public boolean canDoWork(int numBatchesAvailable, WindowPOP pop, boolean frameEndReached, boolean partitionEndReached) { + return partitionEndReached || (!requiresFullPartition(pop) && frameEndReached); } @Override @@ -212,18 +213,18 @@ boolean materialize(final NamedExpression ne, final VectorContainer batch, Funct } @Override - public boolean requiresFullPartition(final boolean hasOrderBy) { + public boolean requiresFullPartition(final WindowPOP pop) { // CUME_DIST, PERCENT_RANK and NTILE require the length of current partition before processing it's first batch return type == Type.CUME_DIST || type == Type.PERCENT_RANK || type == Type.NTILE; } @Override - public boolean canDoWork(int numBatchesAvailable, final boolean hasOrderBy, boolean frameEndReached, boolean partitionEndReached) { + public boolean canDoWork(int numBatchesAvailable, final WindowPOP pop, boolean frameEndReached, boolean partitionEndReached) { assert numBatchesAvailable > 0 : "canDoWork() should not be called when numBatchesAvailable == 0"; // for CUME_DIST, PERCENT_RANK and NTILE we need the full partition // otherwise we can process the first batch immediately - return partitionEndReached || ! requiresFullPartition(hasOrderBy); + return partitionEndReached || ! requiresFullPartition(pop); } @Override @@ -319,12 +320,12 @@ boolean materialize(final NamedExpression ne, final VectorContainer batch, final } @Override - public boolean requiresFullPartition(final boolean hasOrderBy) { + public boolean requiresFullPartition(final WindowPOP pop) { return false; } @Override - public boolean canDoWork(int numBatchesAvailable, final boolean hasOrderBy, boolean frameEndReached, boolean partitionEndReached) { + public boolean canDoWork(int numBatchesAvailable, final WindowPOP pop, boolean frameEndReached, boolean partitionEndReached) { return partitionEndReached || numBatchesAvailable > 1; } @@ -389,12 +390,12 @@ void generateCode(ClassGenerator cg) { } @Override - public boolean requiresFullPartition(final boolean hasOrderBy) { + public boolean requiresFullPartition(final WindowPOP pop) { return false; } @Override - public boolean canDoWork(int numBatchesAvailable, final boolean hasOrderBy, boolean frameEndReached, boolean partitionEndReached) { + public boolean canDoWork(int numBatchesAvailable, final WindowPOP pop, boolean frameEndReached, boolean partitionEndReached) { assert numBatchesAvailable > 0 : "canDoWork() should not be called when numBatchesAvailable == 0"; return true; } @@ -449,13 +450,13 @@ void generateCode(ClassGenerator cg) { } @Override - public boolean requiresFullPartition(final boolean hasOrderBy) { - return !hasOrderBy; + public boolean requiresFullPartition(final WindowPOP pop) { + return pop.getOrderings().length == 0; } @Override - public boolean canDoWork(int numBatchesAvailable, boolean hasOrderBy, boolean frameEndReached, boolean partitionEndReached) { - return partitionEndReached || (hasOrderBy && frameEndReached); + public boolean canDoWork(int numBatchesAvailable, WindowPOP pop, boolean frameEndReached, boolean partitionEndReached) { + return partitionEndReached || (!requiresFullPartition(pop) && frameEndReached); } @Override @@ -533,12 +534,12 @@ void generateCode(final ClassGenerator cg) { } @Override - public boolean requiresFullPartition(boolean hasOrderBy) { + public boolean requiresFullPartition(final WindowPOP pop) { return false; } @Override - public boolean canDoWork(int numBatchesAvailable, boolean hasOrderBy, boolean frameEndReached, boolean partitionEndReached) { + public boolean canDoWork(int numBatchesAvailable, WindowPOP pop, boolean frameEndReached, boolean partitionEndReached) { assert numBatchesAvailable > 0 : "canDoWork() should not be called when numBatchesAvailable == 0"; return true; } From 82395aefce54eb89eb98fd7420f4fc6a4b369be1 Mon Sep 17 00:00:00 2001 From: adeneche Date: Tue, 19 Jan 2016 13:34:59 -0800 Subject: [PATCH 2/4] WindowPOP.Bound to describe FRAME bounds --- .../apache/drill/exec/opt/BasicOptimizer.java | 2 +- .../drill/exec/physical/config/WindowPOP.java | 36 +++++++++++++++---- .../exec/physical/impl/window/Partition.java | 3 ++ .../exec/planner/physical/WindowPrel.java | 4 +-- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/opt/BasicOptimizer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/opt/BasicOptimizer.java index 6e70506d229..018daa451ba 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/opt/BasicOptimizer.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/opt/BasicOptimizer.java @@ -158,7 +158,7 @@ public PhysicalOperator visitWindow(final Window window, final Object value) thr input = new Sort(input, ods, false); return new WindowPOP(input, window.getWithins(), window.getAggregations(), - window.getOrderings(), window.getStart(), window.getEnd()); + window.getOrderings(), null, null); } @Override diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/config/WindowPOP.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/config/WindowPOP.java index 5926a06ed02..46c8d072430 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/config/WindowPOP.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/config/WindowPOP.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; +import org.apache.calcite.rex.RexWindowBound; import org.apache.drill.common.logical.data.NamedExpression; import org.apache.drill.common.logical.data.Order; import org.apache.drill.exec.physical.base.AbstractSingle; @@ -33,15 +34,15 @@ public class WindowPOP extends AbstractSingle { private final NamedExpression[] withins; private final NamedExpression[] aggregations; private final Order.Ordering[] orderings; - private final long start; - private final long end; + private final Bound start; + private final Bound end; public WindowPOP(@JsonProperty("child") PhysicalOperator child, @JsonProperty("within") NamedExpression[] withins, @JsonProperty("aggregations") NamedExpression[] aggregations, @JsonProperty("orderings") Order.Ordering[] orderings, - @JsonProperty("start") long start, - @JsonProperty("end") long end) { + @JsonProperty("start") Bound start, + @JsonProperty("end") Bound end) { super(child); this.withins = withins; this.aggregations = aggregations; @@ -65,11 +66,11 @@ public int getOperatorType() { return UserBitShared.CoreOperatorType.WINDOW_VALUE; } - public long getStart() { + public Bound getStart() { return start; } - public long getEnd() { + public Bound getEnd() { return end; } @@ -84,4 +85,27 @@ public NamedExpression[] getWithins() { public Order.Ordering[] getOrderings() { return orderings; } + + @JsonTypeName("windowBound") + public static class Bound { + private final boolean unbounded; + private final long offset; + + public Bound(@JsonProperty("unbounded") boolean unbounded, @JsonProperty("offset") long offset) { + this.unbounded = unbounded; + this.offset = offset; + } + + public boolean isUnbounded() { + return unbounded; + } + + public long getOffset() { + return offset; + } + } + + public static Bound newBound(RexWindowBound windowBound) { + return new Bound(windowBound.isUnbounded(), Long.MIN_VALUE); //TODO: Get offset to work + } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/Partition.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/Partition.java index 66cf72060ad..92bff6e0d84 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/Partition.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/Partition.java @@ -45,6 +45,9 @@ public long getRemaining() { return remaining; } + public long getLength() { + return length; + } /** * @param length number of rows in this partition * @param partial if true, then length is not the full length of the partition but just the number of rows in the diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/WindowPrel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/WindowPrel.java index c27b547c65c..51d34808974 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/WindowPrel.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/WindowPrel.java @@ -105,8 +105,8 @@ public PhysicalOperator getPhysicalOperator(PhysicalPlanCreator creator) throws withins.toArray(new NamedExpression[withins.size()]), aggs.toArray(new NamedExpression[aggs.size()]), orderings.toArray(new Order.Ordering[orderings.size()]), - Long.MIN_VALUE, //TODO: Get first/last to work - Long.MIN_VALUE); + WindowPOP.newBound(window.lowerBound), + WindowPOP.newBound(window.upperBound)); creator.addMetadata(this, windowPOP); return windowPOP; From 93333e1568f54d51894ae5d8740b7c0e8aa9067c Mon Sep 17 00:00:00 2001 From: adeneche Date: Wed, 20 Jan 2016 11:41:26 -0800 Subject: [PATCH 3/4] DRILL-4261: Add support for RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING --- .../physical/impl/window/FrameSupportTemplate.java | 14 ++++++++++++-- .../exec/physical/impl/window/WindowFunction.java | 4 ++-- .../sql/parser/UnsupportedOperatorsVisitor.java | 5 +++-- .../exec/physical/impl/window/TestWindowFrame.java | 10 ++++++++++ exec/java-exec/src/test/resources/window/q3.sql | 9 +++++++++ exec/java-exec/src/test/resources/window/q4.sql | 9 +++++++++ 6 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 exec/java-exec/src/test/resources/window/q3.sql create mode 100644 exec/java-exec/src/test/resources/window/q4.sql diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/FrameSupportTemplate.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/FrameSupportTemplate.java index 36bccb35116..d69e0c00fe7 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/FrameSupportTemplate.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/FrameSupportTemplate.java @@ -53,6 +53,8 @@ public abstract class FrameSupportTemplate implements WindowFramer { private Partition partition; + private boolean unboundedFollowing; // true if the frame is of the form RANGE BETWEEN X AND UNBOUNDED FOLLOWING + @Override public void setup(final List batches, final VectorContainer container, final OperatorContext oContext, final boolean requireFullPartition, final WindowPOP popConfig) throws SchemaChangeException { @@ -66,6 +68,7 @@ public void setup(final List batches, final VectorContainer con partition = null; this.requireFullPartition = requireFullPartition; + unboundedFollowing = popConfig.getEnd().isUnbounded(); } private void allocateInternal() { @@ -218,6 +221,7 @@ private long aggregatePeers(final int start) throws SchemaChangeException { VectorAccessible last = current; long length = 0; + final long remaining = partition.getLength(); // a single frame can include rows from multiple batches // start processing first batch and, if necessary, move to next batches @@ -227,8 +231,14 @@ private long aggregatePeers(final int start) throws SchemaChangeException { // for every remaining row in the partition, count it if it's a peer row for (int row = (batch == current) ? start : 0; row < recordCount; row++, length++) { - if (!isPeer(start, current, row, batch)) { - break; + if (unboundedFollowing) { + if (length >= remaining) { + break; + } + } else { + if (!isPeer(start, current, row, batch)) { + break; + } } evaluatePeer(row); diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFunction.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFunction.java index 0116bd0c5f0..b267ed6bb7e 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFunction.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/window/WindowFunction.java @@ -157,7 +157,7 @@ void generateCode(ClassGenerator cg) { @Override public boolean requiresFullPartition(final WindowPOP pop) { - return pop.getOrderings().length == 0; + return pop.getOrderings().length == 0 || pop.getEnd().isUnbounded(); } @Override @@ -451,7 +451,7 @@ void generateCode(ClassGenerator cg) { @Override public boolean requiresFullPartition(final WindowPOP pop) { - return pop.getOrderings().length == 0; + return pop.getOrderings().length == 0 || pop.getEnd().isUnbounded(); } @Override diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java index effe022ccb9..0a134cba4f9 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java @@ -178,13 +178,14 @@ public SqlNode visit(SqlCall sqlCall) { // it is a default frame boolean isSupported = (lowerBound == null && upperBound == null); - // When OVER clause contain an ORDER BY clause the following frames are equivalent to the default frame: + // When OVER clause contain an ORDER BY clause the following frames are supported: // RANGE UNBOUNDED PRECEDING // RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + // RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING if(window.getOrderList().size() != 0 && !window.isRows() && SqlWindow.isUnboundedPreceding(lowerBound) - && (upperBound == null || SqlWindow.isCurrentRow(upperBound))) { + && (upperBound == null || SqlWindow.isCurrentRow(upperBound) || SqlWindow.isUnboundedFollowing(upperBound))) { isSupported = true; } 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 index 10abbff8b1d..7914bc7b224 100644 --- 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 @@ -106,6 +106,16 @@ public void testMultipleFramers() throws Exception { ); } + @Test + public void testUnboundedFollowing() throws Exception { + testBuilder() + .sqlQuery(String.format(getFile("window/q3.sql"), TEST_RES_PATH)) + .ordered() + .sqlBaselineQuery(String.format(getFile("window/q3.sql"), TEST_RES_PATH)) + .build() + .run(); + } + /** * 2 batches with 2 partitions (position_id column), each batch contains a different partition */ diff --git a/exec/java-exec/src/test/resources/window/q3.sql b/exec/java-exec/src/test/resources/window/q3.sql new file mode 100644 index 00000000000..0efb137c52a --- /dev/null +++ b/exec/java-exec/src/test/resources/window/q3.sql @@ -0,0 +1,9 @@ +SELECT + position_id, + employee_id, + LAST_VALUE(employee_id) + OVER(PARTITION BY position_id + ORDER by employee_id + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `last_value` +FROM + dfs_test.`%s/window/b4.p4` diff --git a/exec/java-exec/src/test/resources/window/q4.sql b/exec/java-exec/src/test/resources/window/q4.sql new file mode 100644 index 00000000000..5e1fb22f5ff --- /dev/null +++ b/exec/java-exec/src/test/resources/window/q4.sql @@ -0,0 +1,9 @@ +SELECT + position_id, + employee_id, + MAX(employee_id) OVER(PARTITION BY position_id) AS `last_value` +FROM ( + SELECT * + FROM dfs_test.`%s/window/b4.p4` + ORDER BY position_id, employee_id +) From 5a1b0112faef7d6992791c44305d10facc57f390 Mon Sep 17 00:00:00 2001 From: adeneche Date: Thu, 21 Jan 2016 17:35:13 -0800 Subject: [PATCH 4/4] fixed unit test --- .../apache/drill/exec/physical/impl/window/TestWindowFrame.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 7914bc7b224..5e9a94e4da3 100644 --- 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 @@ -111,7 +111,7 @@ public void testUnboundedFollowing() throws Exception { testBuilder() .sqlQuery(String.format(getFile("window/q3.sql"), TEST_RES_PATH)) .ordered() - .sqlBaselineQuery(String.format(getFile("window/q3.sql"), TEST_RES_PATH)) + .sqlBaselineQuery(String.format(getFile("window/q4.sql"), TEST_RES_PATH)) .build() .run(); }