This is an automated email from the ASF dual-hosted git repository.

abhishek pushed a commit to branch 29.0.0
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/29.0.0 by this push:
     new bb56851dd7c Range support in window expressions (support them as 
groups) (#15365) (#15703)
bb56851dd7c is described below

commit bb56851dd7c629bd4fad29d8fcace8a304eee379
Author: Zoltan Haindrich <[email protected]>
AuthorDate: Wed Jan 17 16:50:06 2024 +0100

    Range support in window expressions (support them as groups) (#15365) 
(#15703)
    
    * support groups windowing mode; which is a close relative of ranges (but 
not in the standard)
    * all windows with range expressions will be executed wit it groups
    * it will be 100% correct in case for both bounds its true that: 
isCurrentRow() || isUnBounded()
      * this covers OVER ( ORDER BY COL )
    * for other cases it will have some chances of getting correct results...
    
    (cherry picked from commit 8a43db9395bc142d089dcb05892d9f33f118af99)
---
 .../hll/sql/HllSketchSqlAggregatorTest.java        |  24 ++
 .../druid/query/operator/window/WindowFrame.java   |  59 +++-
 .../window/WindowFramedAggregateProcessor.java     |  30 +-
 .../semantic/DefaultFramedOnHeapAggregatable.java  | 310 ++++++++++++++++++++-
 .../window/WindowFramedAggregateProcessorTest.java |  13 +-
 .../DefaultFramedOnHeapAggregatableTest.java       |  52 ++++
 .../semantic/FramedOnHeapAggregatableTest.java     | 166 ++++++++++-
 .../apache/druid/sql/calcite/rel/Windowing.java    |   8 +-
 .../druid/query/OperatorFactoryBuilders.java       |   8 +
 .../apache/druid/sql/calcite/CalciteQueryTest.java |  66 +++++
 .../druid/sql/calcite/DrillWindowQueryTest.java    |  49 ----
 .../calcite/tests/window/range_handling.sqlTest    |  24 ++
 .../calcite/tests/window/simpleSum.sqlTest         |   8 +-
 .../wikipediaAggregationsMultipleOrdering.sqlTest  |  10 +-
 .../window/wikipediaCumulativeOrdered.sqlTest      |  50 ++--
 .../window/wikipediaFramedAggregations.sqlTest     |   8 +-
 .../tests/window/windowed_long_null.sqlTest        |   2 +-
 17 files changed, 785 insertions(+), 102 deletions(-)

diff --git 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
index 8701abbe486..4d5e2ce354a 100644
--- 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
+++ 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
@@ -75,6 +75,7 @@ import 
org.apache.druid.segment.writeout.OffHeapMemorySegmentWriteOutMediumFacto
 import org.apache.druid.server.SpecificSegmentsQuerySegmentWalker;
 import org.apache.druid.sql.calcite.BaseCalciteQueryTest;
 import org.apache.druid.sql.calcite.filtration.Filtration;
+import org.apache.druid.sql.calcite.planner.PlannerContext;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.TestDataBuilder;
 import org.apache.druid.sql.guice.SqlModule;
@@ -1157,6 +1158,29 @@ public class HllSketchSqlAggregatorTest extends 
BaseCalciteQueryTest
     );
   }
 
+  @Test
+  public void testHllWithOrderedWindowing()
+  {
+    testBuilder()
+        .queryContext(ImmutableMap.of(PlannerContext.CTX_ENABLE_WINDOW_FNS, 
true))
+        .sql(
+            "SELECT dim1,coalesce(cast(l1 as integer),-999),"
+                + " HLL_SKETCH_ESTIMATE( DS_HLL(dim1) OVER ( ORDER BY l1 ), 
true)"
+                + " FROM druid.foo"
+                + " WHERE length(dim1)>0"
+        )
+        .expectedResults(
+            ImmutableList.of(
+                new Object[] {"1", -999, 3.0D},
+                new Object[] {"def", -999, 3.0D},
+                new Object[] {"abc", -999, 3.0D},
+                new Object[] {"2", 0, 4.0D},
+                new Object[] {"10.1", 325323, 5.0D}
+            )
+        )
+        .run();
+  }
+
   /**
    * This is an extremely subtle test, so we explain with a comment.  The `m1` 
column in the input data looks like
    * `["1.0", "2.0", "3.0", "4.0", "5.0", "6.0"]` while the `d1` column looks 
like
diff --git 
a/processing/src/main/java/org/apache/druid/query/operator/window/WindowFrame.java
 
b/processing/src/main/java/org/apache/druid/query/operator/window/WindowFrame.java
index b0dcc61415b..b70df2c5203 100644
--- 
a/processing/src/main/java/org/apache/druid/query/operator/window/WindowFrame.java
+++ 
b/processing/src/main/java/org/apache/druid/query/operator/window/WindowFrame.java
@@ -21,14 +21,19 @@ package org.apache.druid.query.operator.window;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.Lists;
+import org.apache.druid.query.operator.ColumnWithDirection;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 public class WindowFrame
 {
   public static WindowFrame unbounded()
   {
-    return new WindowFrame(PeerType.ROWS, true, 0, true, 0);
+    return new WindowFrame(PeerType.ROWS, true, 0, true, 0, null);
   }
 
   @SuppressWarnings("unused")
@@ -44,6 +49,7 @@ public class WindowFrame
   private final int lowerOffset;
   private final boolean upperUnbounded;
   private final int upperOffset;
+  private final List<ColumnWithDirection> orderBy;
 
   @JsonCreator
   public WindowFrame(
@@ -51,7 +57,8 @@ public class WindowFrame
       @JsonProperty("lowUnbounded") boolean lowerUnbounded,
       @JsonProperty("lowOffset") int lowerOffset,
       @JsonProperty("uppUnbounded") boolean upperUnbounded,
-      @JsonProperty("uppOffset") int upperOffset
+      @JsonProperty("uppOffset") int upperOffset,
+      @JsonProperty("orderBy") List<ColumnWithDirection> orderBy
   )
   {
     this.peerType = peerType;
@@ -59,6 +66,7 @@ public class WindowFrame
     this.lowerOffset = lowerOffset;
     this.upperUnbounded = upperUnbounded;
     this.upperOffset = upperOffset;
+    this.orderBy = orderBy;
   }
 
   @JsonProperty("peerType")
@@ -91,6 +99,12 @@ public class WindowFrame
     return upperOffset;
   }
 
+  @JsonProperty("orderBy")
+  public List<ColumnWithDirection> getOrderBy()
+  {
+    return orderBy;
+  }
+
   @Override
   public boolean equals(Object o)
   {
@@ -105,13 +119,14 @@ public class WindowFrame
            && lowerOffset == that.lowerOffset
            && upperUnbounded == that.upperUnbounded
            && upperOffset == that.upperOffset
-           && peerType == that.peerType;
+           && peerType == that.peerType
+           && Objects.equals(orderBy, that.orderBy);
   }
 
   @Override
   public int hashCode()
   {
-    return Objects.hash(peerType, lowerUnbounded, lowerOffset, upperUnbounded, 
upperOffset);
+    return Objects.hash(peerType, lowerUnbounded, lowerOffset, upperUnbounded, 
upperOffset, orderBy);
   }
 
   @Override
@@ -123,6 +138,42 @@ public class WindowFrame
            ", lowerOffset=" + lowerOffset +
            ", upperUnbounded=" + upperUnbounded +
            ", upperOffset=" + upperOffset +
+           ", orderBy=" + orderBy +
            '}';
   }
+
+  public static WindowFrame forOrderBy(ColumnWithDirection... orderBy)
+  {
+    return new WindowFrame(PeerType.RANGE, true, 0, false, 0, 
Lists.newArrayList(orderBy));
+  }
+
+  public List<String> getOrderByColNames()
+  {
+    if (orderBy == null) {
+      return Collections.emptyList();
+    }
+    return 
orderBy.stream().map(ColumnWithDirection::getColumn).collect(Collectors.toList());
+  }
+
+  /**
+   * Calculates the applicable lower offset if the max number of rows is known.
+   */
+  public int getLowerOffsetClamped(int maxRows)
+  {
+    if (lowerUnbounded) {
+      return maxRows;
+    }
+    return Math.min(maxRows, lowerOffset);
+  }
+
+  /**
+   * Calculates the applicable upper offset if the max number of rows is known.
+   */
+  public int getUpperOffsetClamped(int maxRows)
+  {
+    if (upperUnbounded) {
+      return maxRows;
+    }
+    return Math.min(maxRows, upperOffset);
+  }
 }
diff --git 
a/processing/src/main/java/org/apache/druid/query/operator/window/WindowFramedAggregateProcessor.java
 
b/processing/src/main/java/org/apache/druid/query/operator/window/WindowFramedAggregateProcessor.java
index a67cb519407..26e790a841e 100644
--- 
a/processing/src/main/java/org/apache/druid/query/operator/window/WindowFramedAggregateProcessor.java
+++ 
b/processing/src/main/java/org/apache/druid/query/operator/window/WindowFramedAggregateProcessor.java
@@ -28,6 +28,7 @@ import 
org.apache.druid.query.rowsandcols.semantic.FramedOnHeapAggregatable;
 
 import javax.annotation.Nullable;
 import java.util.Arrays;
+import java.util.Objects;
 
 public class WindowFramedAggregateProcessor implements Processor
 {
@@ -73,7 +74,6 @@ public class WindowFramedAggregateProcessor implements 
Processor
     if (agger == null) {
       agger = new 
DefaultFramedOnHeapAggregatable(RowsAndColumns.expectAppendable(inputPartition));
     }
-
     return agger.aggregateAll(frame, aggregations);
   }
 
@@ -96,4 +96,32 @@ public class WindowFramedAggregateProcessor implements 
Processor
            ", aggregations=" + Arrays.toString(aggregations) +
            '}';
   }
+
+  @Override
+  public int hashCode()
+  {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + Arrays.hashCode(aggregations);
+    result = prime * result + Objects.hash(frame);
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj)
+  {
+    if (this == obj) {
+      return true;
+    }
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    WindowFramedAggregateProcessor other = (WindowFramedAggregateProcessor) 
obj;
+    return Arrays.equals(aggregations, other.aggregations) && 
Objects.equals(frame, other.frame);
+  }
+
+
 }
diff --git 
a/processing/src/main/java/org/apache/druid/query/rowsandcols/semantic/DefaultFramedOnHeapAggregatable.java
 
b/processing/src/main/java/org/apache/druid/query/rowsandcols/semantic/DefaultFramedOnHeapAggregatable.java
index cb7ae58c935..8b34b62f06f 100644
--- 
a/processing/src/main/java/org/apache/druid/query/rowsandcols/semantic/DefaultFramedOnHeapAggregatable.java
+++ 
b/processing/src/main/java/org/apache/druid/query/rowsandcols/semantic/DefaultFramedOnHeapAggregatable.java
@@ -19,6 +19,9 @@
 
 package org.apache.druid.query.rowsandcols.semantic;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.java.util.common.UOE;
 import org.apache.druid.query.aggregation.Aggregator;
 import org.apache.druid.query.aggregation.AggregatorFactory;
@@ -37,16 +40,16 @@ import 
org.apache.druid.segment.column.ColumnCapabilitiesImpl;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.concurrent.atomic.AtomicInteger;
 
 public class DefaultFramedOnHeapAggregatable implements 
FramedOnHeapAggregatable
 {
   private final AppendableRowsAndColumns rac;
 
-  public DefaultFramedOnHeapAggregatable(
-      AppendableRowsAndColumns rac
-  )
+  public DefaultFramedOnHeapAggregatable(AppendableRowsAndColumns rac)
   {
     this.rac = rac;
   }
@@ -62,7 +65,6 @@ public class DefaultFramedOnHeapAggregatable implements 
FramedOnHeapAggregatable
       return computeUnboundedAggregates(aggFactories);
     }
 
-
     if (frame.getPeerType() == WindowFrame.PeerType.ROWS) {
       if (frame.isLowerUnbounded()) {
         return computeCumulativeAggregates(aggFactories, 
frame.getUpperOffset());
@@ -85,7 +87,305 @@ public class DefaultFramedOnHeapAggregatable implements 
FramedOnHeapAggregatable
         }
       }
     } else {
-      throw new UOE("RANGE peer groupings are unsupported");
+      return computeGroupAggregates(aggFactories, frame);
+    }
+  }
+
+  /**
+   * Handles population/creation of new RAC columns.
+   */
+  static class ResultPopulator
+  {
+
+    private final Object[][] results;
+    private final AggregatorFactory[] aggFactories;
+
+    public ResultPopulator(AggregatorFactory[] aggFactories, int numRows)
+    {
+      this.aggFactories = aggFactories;
+      results = new Object[aggFactories.length][numRows];
+    }
+
+    public void write(Interval outputRows, AggIntervalCursor aggCursor)
+    {
+      for (int col = 0; col < aggFactories.length; col++) {
+        Arrays.fill(results[col], outputRows.a, outputRows.b, 
aggCursor.getValue(col));
+      }
+    }
+
+    public void appendTo(AppendableRowsAndColumns rac)
+    {
+      for (int i = 0; i < aggFactories.length; ++i) {
+        rac.addColumn(
+            aggFactories[i].getName(),
+            new ObjectArrayColumn(results[i], 
aggFactories[i].getIntermediateType())
+        );
+      }
+    }
+  }
+
+  private RowsAndColumns computeGroupAggregates(
+      AggregatorFactory[] aggFactories,
+      WindowFrame frame)
+  {
+    Iterable<AggInterval> groupIterator = buildGroupIteratorFor(rac, frame);
+    ResultPopulator resultRac = new ResultPopulator(aggFactories, 
rac.numRows());
+    AggIntervalCursor aggCursor = new AggIntervalCursor(rac, aggFactories);
+    for (AggInterval aggInterval : groupIterator) {
+      aggCursor.moveTo(aggInterval.inputRows);
+      resultRac.write(aggInterval.outputRows, aggCursor);
+    }
+    resultRac.appendTo(rac);
+    return rac;
+  }
+
+  public static Iterable<AggInterval> 
buildGroupIteratorFor(AppendableRowsAndColumns rac, WindowFrame frame)
+  {
+    int[] groupBoundaries = 
ClusteredGroupPartitioner.fromRAC(rac).computeBoundaries(frame.getOrderByColNames());
+    return new GroupIteratorForWindowFrame(frame, groupBoundaries);
+  }
+
+  static class GroupIteratorForWindowFrame implements Iterable<AggInterval>
+  {
+    private final int[] groupBoundaries;
+    private final int numGroups;
+    // lower inclusive
+    private final int lowerOffset;
+    // upper exclusive
+    private final int upperOffset;
+
+    public GroupIteratorForWindowFrame(WindowFrame frame, int[] 
groupBoundaries)
+    {
+      this.groupBoundaries = groupBoundaries;
+      numGroups = groupBoundaries.length - 1;
+      lowerOffset = frame.getLowerOffsetClamped(numGroups);
+      upperOffset = Math.min(numGroups, frame.getUpperOffsetClamped(numGroups) 
+ 1);
+    }
+
+    @Override
+    public Iterator<AggInterval> iterator()
+    {
+      return new Iterator<AggInterval>()
+      {
+        int currentGroupIndex = 0;
+
+        @Override
+        public boolean hasNext()
+        {
+          return currentGroupIndex < numGroups;
+        }
+
+        @Override
+        public AggInterval next()
+        {
+          if (!hasNext()) {
+            throw new IllegalStateException();
+          }
+          AggInterval r = new AggInterval(
+              Interval.of(
+                  groupToRowIndex(relativeGroupId(0)),
+                  groupToRowIndex(relativeGroupId(1))
+              ),
+              Interval.of(
+                  groupToRowIndex(relativeGroupId(-lowerOffset)),
+                  groupToRowIndex(relativeGroupId(upperOffset))
+              )
+          );
+
+          currentGroupIndex++;
+          return r;
+        }
+
+        private int groupToRowIndex(int groupId)
+        {
+          return groupBoundaries[groupId];
+        }
+
+        private int relativeGroupId(int groupOffset)
+        {
+          // invert iteration order at the end to get benefits of 
incremenental aggregations
+          // for example if we have [0 BEFORE 1 AFTER]: for say 3 groups the 
order will be 0,2,1 instead of 0,1,2
+          final int groupIndex = invertedOrderForLastK(currentGroupIndex, 
numGroups, upperOffset);
+
+          int groupId = groupIndex + groupOffset;
+          if (groupId < 0) {
+            return 0;
+          }
+          if (groupId >= numGroups) {
+            return numGroups;
+          }
+          return groupId;
+        }
+      };
+    }
+  }
+
+  /**
+   * Inverts order for the last K elements.
+   *
+   * For n=3, k=2 - it changes the iteration to 0,2,1
+   */
+  @VisibleForTesting
+  public static int invertedOrderForLastK(int x, int n, int k)
+  {
+    Preconditions.checkState(k <= n);
+    if (k <= 1 || x + k < n) {
+      // we are in the non-interesting part
+      return x;
+    }
+    int i = x - (n - k);
+    return n - 1 - i;
+  }
+
+  /**
+   * Basic [a,b) interval; left inclusive/right exclusive.
+   */
+  static class Interval implements Iterable<Integer>
+  {
+    final int a;
+    final int b;
+
+    public static Interval of(int a, int b)
+    {
+      return new Interval(a, b);
+    }
+
+    public Interval(int a, int b)
+    {
+      this.a = a;
+      this.b = b;
+    }
+
+    @Override
+    public Iterator<Integer> iterator()
+    {
+      return new Iterator<Integer>()
+      {
+        int current = a;
+
+        @Override
+        public Integer next()
+        {
+          if (!hasNext()) {
+            throw new IllegalStateException();
+          }
+          return current++;
+        }
+
+        @Override
+        public boolean hasNext()
+        {
+          return current < b;
+        }
+      };
+    }
+
+    @Override
+    public String toString()
+    {
+      return StringUtils.format("Interval [%d ... %d[", a, b);
+    }
+  }
+
+  /**
+   * Represents an aggregation interval.
+   *
+   * Describes that the aggregation of {@link #inputRows} should be outputted 
to
+   * all {@link #outputRows} specified.
+   */
+  static class AggInterval
+  {
+    final Interval outputRows;
+    final Interval inputRows;
+
+    public AggInterval(Interval outputRows, Interval inputRows)
+    {
+      this.outputRows = outputRows;
+      this.inputRows = inputRows;
+    }
+  }
+
+  public static Object cloneAggValue(AggregatorFactory aggFactory, Object 
value)
+  {
+    if (value == null || value instanceof Number) {
+      // no need for the hussle
+      return value;
+    }
+    Object[] currentValue = new Object[1];
+    currentValue[0] = value;
+    final CumulativeColumnSelectorFactory combiningFactory = new 
CumulativeColumnSelectorFactory(
+        aggFactory,
+        currentValue,
+        0
+    );
+    Aggregator combiningAgg = 
aggFactory.getCombiningFactory().factorize(combiningFactory);
+
+    combiningAgg.aggregate();
+    return combiningAgg.get();
+  }
+
+  /**
+   * Handles computations of aggregates for an {@link Interval}.
+   *
+   * Provides aggregates computed for a given {@link Interval}.
+   * It could try to leverage earlier calculations internally if possible.
+   */
+  static class AggIntervalCursor
+  {
+    private AggregatorFactory[] aggFactories;
+    private final AtomicInteger rowIdProvider;
+    private final ColumnSelectorFactory columnSelectorFactory;
+
+    /** Current interval the aggregators contain value for */
+    private Interval currentRows = new Interval(0, 0);
+    private final Aggregator[] aggregators;
+
+    AggIntervalCursor(AppendableRowsAndColumns rac, AggregatorFactory[] 
aggFactories)
+    {
+      this.aggFactories = aggFactories;
+      aggregators = new Aggregator[aggFactories.length];
+      rowIdProvider = new AtomicInteger(0);
+      columnSelectorFactory = 
ColumnSelectorFactoryMaker.fromRAC(rac).make(rowIdProvider);
+      newAggregators();
+    }
+
+    public Object getValue(int aggIdx)
+    {
+      return cloneAggValue(aggFactories[aggIdx], aggregators[aggIdx].get());
+    }
+
+    /**
+     * Reposition aggregation window to a new Interval.
+     */
+    public void moveTo(Interval newRows)
+    {
+      if (currentRows.a == newRows.a && currentRows.b < newRows.b) {
+        // incremental addition of additional values
+        for (int i = currentRows.b; i < newRows.b; i++) {
+          aggregate(i);
+        }
+      } else {
+        newAggregators();
+        for (int i : newRows) {
+          aggregate(i);
+        }
+      }
+      currentRows = newRows;
+    }
+
+    private void newAggregators()
+    {
+      for (int i = 0; i < aggFactories.length; i++) {
+        aggregators[i] = aggFactories[i].factorize(columnSelectorFactory);
+      }
+    }
+
+    private void aggregate(int rowIdx)
+    {
+      rowIdProvider.set(rowIdx);
+      for (int i = 0; i < aggFactories.length; i++) {
+        aggregators[i].aggregate();
+      }
     }
   }
 
diff --git 
a/processing/src/test/java/org/apache/druid/query/operator/window/WindowFramedAggregateProcessorTest.java
 
b/processing/src/test/java/org/apache/druid/query/operator/window/WindowFramedAggregateProcessorTest.java
index 145d37a4384..88d79c87cdb 100644
--- 
a/processing/src/test/java/org/apache/druid/query/operator/window/WindowFramedAggregateProcessorTest.java
+++ 
b/processing/src/test/java/org/apache/druid/query/operator/window/WindowFramedAggregateProcessorTest.java
@@ -20,6 +20,7 @@
 package org.apache.druid.query.operator.window;
 
 import com.google.common.collect.ImmutableMap;
+import nl.jqno.equalsverifier.EqualsVerifier;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.query.aggregation.AggregatorFactory;
 import org.apache.druid.query.aggregation.DoubleSumAggregatorFactory;
@@ -44,7 +45,7 @@ public class WindowFramedAggregateProcessorTest
   @Test
   public void testIsPassThruWhenRACReturnsSemanticInterface()
   {
-    final WindowFrame theFrame = new WindowFrame(WindowFrame.PeerType.ROWS, 
true, 0, false, 0);
+    final WindowFrame theFrame = new WindowFrame(WindowFrame.PeerType.ROWS, 
true, 0, false, 0, null);
     final AggregatorFactory[] theAggs = {
         new LongMaxAggregatorFactory("cummMax", "intCol"),
         new DoubleSumAggregatorFactory("cummSum", "doubleCol")
@@ -75,7 +76,7 @@ public class WindowFramedAggregateProcessorTest
   @Test
   public void testDoesStuffWhenNoSemanticInterfacesAvailable()
   {
-    final WindowFrame theFrame = new WindowFrame(WindowFrame.PeerType.ROWS, 
true, 0, false, 0);
+    final WindowFrame theFrame = new WindowFrame(WindowFrame.PeerType.ROWS, 
true, 0, false, 0, null);
     final AggregatorFactory[] theAggs = {
         new LongSumAggregatorFactory("sum", "intCol")
     };
@@ -93,4 +94,12 @@ public class WindowFramedAggregateProcessorTest
         .allColumnsRegistered()
         .validate(processed);
   }
+
+  @Test
+  public void testEquals()
+  {
+    EqualsVerifier.forClass(WindowFramedAggregateProcessor.class)
+        .usingGetClass()
+        .verify();
+  }
 }
diff --git 
a/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/DefaultFramedOnHeapAggregatableTest.java
 
b/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/DefaultFramedOnHeapAggregatableTest.java
new file mode 100644
index 00000000000..6bcb5b1cf3d
--- /dev/null
+++ 
b/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/DefaultFramedOnHeapAggregatableTest.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.druid.query.rowsandcols.semantic;
+
+import org.junit.Test;
+
+import static 
org.apache.druid.query.rowsandcols.semantic.DefaultFramedOnHeapAggregatable.invertedOrderForLastK;
+import static org.junit.Assert.assertEquals;
+
+public class DefaultFramedOnHeapAggregatableTest
+{
+  @Test
+  public void testInvertedOrderForLastK()
+  {
+    assertEquals(0, invertedOrderForLastK(0, 3, 1));
+    assertEquals(1, invertedOrderForLastK(1, 3, 1));
+    assertEquals(2, invertedOrderForLastK(2, 3, 1));
+  }
+
+  @Test
+  public void testInvertedOrderForLastK2()
+  {
+    assertEquals(0, invertedOrderForLastK(0, 3, 2));
+    assertEquals(2, invertedOrderForLastK(1, 3, 2));
+    assertEquals(1, invertedOrderForLastK(2, 3, 2));
+  }
+
+  @Test
+  public void testInvertedOrderForLastK3()
+  {
+    assertEquals(2, invertedOrderForLastK(0, 3, 3));
+    assertEquals(1, invertedOrderForLastK(1, 3, 3));
+    assertEquals(0, invertedOrderForLastK(2, 3, 3));
+  }
+}
diff --git 
a/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/FramedOnHeapAggregatableTest.java
 
b/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/FramedOnHeapAggregatableTest.java
index 0de6a069904..d00e12b3b66 100644
--- 
a/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/FramedOnHeapAggregatableTest.java
+++ 
b/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/FramedOnHeapAggregatableTest.java
@@ -25,8 +25,10 @@ import 
org.apache.druid.query.aggregation.DoubleSumAggregatorFactory;
 import org.apache.druid.query.aggregation.LongMaxAggregatorFactory;
 import org.apache.druid.query.aggregation.LongMinAggregatorFactory;
 import org.apache.druid.query.aggregation.LongSumAggregatorFactory;
+import org.apache.druid.query.operator.ColumnWithDirection;
 import org.apache.druid.query.operator.window.RowsAndColumnsHelper;
 import org.apache.druid.query.operator.window.WindowFrame;
+import org.apache.druid.query.operator.window.WindowFrame.PeerType;
 import org.apache.druid.query.rowsandcols.MapOfColumnsRowsAndColumns;
 import org.apache.druid.query.rowsandcols.RowsAndColumns;
 import org.apache.druid.query.rowsandcols.column.Column;
@@ -36,6 +38,7 @@ import 
org.apache.druid.query.rowsandcols.column.ObjectArrayColumn;
 import org.apache.druid.segment.column.ColumnType;
 import org.junit.Test;
 
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.Function;
@@ -62,7 +65,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, false, 0),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, false, 0, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -88,7 +91,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 1, false, 2),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 1, false, 2, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -114,7 +117,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, false, 2),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, false, 2, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -140,7 +143,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 2, false, 0),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 2, false, 0, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -166,7 +169,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 5, false, 7),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 5, false, 7, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -194,7 +197,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 5, false, 1),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 5, false, 1, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -222,7 +225,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 5, false, 0),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 5, false, 0, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -250,7 +253,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 1, false, 7),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 1, false, 7, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -278,7 +281,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, false, 7),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, false, 7, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -306,7 +309,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, false, 7),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, false, 7, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -334,7 +337,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 5, false, 0),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 5, false, 0, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new DoubleMaxAggregatorFactory("maxFromInt", "intCol"),
@@ -368,7 +371,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, true, 0, true, 0),
+        new WindowFrame(WindowFrame.PeerType.ROWS, true, 0, true, 0, null),
         new AggregatorFactory[]{
             new LongSumAggregatorFactory("sumFromLong", "intCol"),
             new LongSumAggregatorFactory("sumFromDouble", "doubleCol"),
@@ -406,7 +409,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, true, 0, false, 0),
+        new WindowFrame(WindowFrame.PeerType.ROWS, true, 0, false, 0, null),
         new AggregatorFactory[]{
             new LongMaxAggregatorFactory("cummMax", "intCol"),
             new DoubleSumAggregatorFactory("cummSum", "doubleCol")
@@ -440,7 +443,7 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
     FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
 
     final RowsAndColumns results = agger.aggregateAll(
-        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, true, 0),
+        new WindowFrame(WindowFrame.PeerType.ROWS, false, 0, true, 0, null),
         new AggregatorFactory[]{
             new LongMaxAggregatorFactory("cummMax", "intCol"),
             new DoubleSumAggregatorFactory("cummSum", "doubleCol")
@@ -456,4 +459,139 @@ public class FramedOnHeapAggregatableTest extends 
SemanticTestBase
         .allColumnsRegistered()
         .validate(results);
   }
+
+
+
+  @Test
+  public void testRangeOrderBy()
+  {
+    WindowFrame frame = 
WindowFrame.forOrderBy(ColumnWithDirection.ascending("c1"));
+    int[] c1Vals = new int[] {0, 0, 0, 1, 1, 1, 2, 2, 2, 2};
+    int[] c2Vals = new int[] {1, 1, 2, 1, 1, 2, 1, 1, 1, 2};
+    int[] resVals = new int[] {4, 4, 4, 8, 8, 8, 13, 13, 13, 13};
+
+    simpleWindowingTest(frame, c1Vals, c2Vals, resVals);
+  }
+
+  @Test
+  public void testRangeB1()
+  {
+    WindowFrame frame = new WindowFrame(
+        PeerType.RANGE,
+        false,
+        1,
+        false,
+        0,
+        Collections.singletonList(ColumnWithDirection.ascending("c1"))
+    );
+
+    int[] c1Vals = new int[] {0, 1, 2, 2, 3, 4, 5};
+    int[] c2Vals = new int[] {0, 1, 1, 1, 3, 4, 5};
+    int[] resVals = new int[] {0, 1, 3, 3, 5, 7, 9};
+
+    simpleWindowingTest(frame, c1Vals, c2Vals, resVals);
+  }
+
+  @Test
+  public void testRangeA1()
+  {
+    WindowFrame frame = new WindowFrame(
+        PeerType.RANGE,
+        false,
+        0,
+        false,
+        1,
+        Collections.singletonList(ColumnWithDirection.ascending("c1"))
+    );
+
+    int[] c1Vals = new int[] {0, 1, 2, 2, 3, 4, 5};
+    int[] c2Vals = new int[] {0, 1, 1, 1, 3, 4, 5};
+    int[] resVals = new int[] {1, 3, 5, 5, 7, 9, 5};
+
+    simpleWindowingTest(frame, c1Vals, c2Vals, resVals);
+  }
+
+  @Test
+  public void testRangeB1A1()
+  {
+    WindowFrame frame = new WindowFrame(
+        PeerType.RANGE,
+        false,
+        1,
+        false,
+        1,
+        Collections.singletonList(ColumnWithDirection.ascending("c1"))
+    );
+
+    int[] c1Vals = new int[] {0, 1, 2, 3, 4, 5};
+    int[] c2Vals = new int[] {0, 1, 2, 3, 4, 5};
+    int[] resVals = new int[] {1, 3, 6, 9, 12, 9};
+
+    simpleWindowingTest(frame, c1Vals, c2Vals, resVals);
+  }
+
+
+  @Test
+  public void testRangeB1A1_2()
+  {
+    WindowFrame frame = new WindowFrame(
+        PeerType.RANGE,
+        false,
+        1,
+        false,
+        1,
+        Collections.singletonList(ColumnWithDirection.ascending("c1"))
+    );
+
+    int[] c1Vals = new int[] {0, 0, 1, 2, 3, 3, 4, 4, 5};
+    int[] c2Vals = new int[] {0, 0, 1, 2, 2, 1, 2, 2, 5};
+    int[] resVals = new int[] {1, 1, 3, 6, 9, 9, 12, 12, 9};
+
+    simpleWindowingTest(frame, c1Vals, c2Vals, resVals);
+  }
+
+  @Test
+  public void testRangeB1A2()
+  {
+    WindowFrame frame = new WindowFrame(
+        PeerType.RANGE,
+        false,
+        1,
+        false,
+        2,
+        Collections.singletonList(ColumnWithDirection.ascending("c1"))
+    );
+
+    int[] c1Vals = new int[] {0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3};
+    int[] c2Vals = new int[] {1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1};
+    int[] resVals = new int[] {13, 13, 13, 16, 16, 16, 12, 12, 12, 12, 8, 8, 
8};
+
+    simpleWindowingTest(frame, c1Vals, c2Vals, resVals);
+  }
+
+  private void simpleWindowingTest(WindowFrame frame, int[] c1Vals, int[] 
c2Vals, int[] resVals)
+  {
+    Map<String, Column> map = new LinkedHashMap<>();
+    map.put("c1", new IntArrayColumn(c1Vals));
+    map.put("c2", new IntArrayColumn(c2Vals));
+
+    RowsAndColumns rac = make(MapOfColumnsRowsAndColumns.fromMap(map));
+
+    FramedOnHeapAggregatable agger = FramedOnHeapAggregatable.fromRAC(rac);
+
+    final RowsAndColumns results = agger.aggregateAll(
+        frame,
+        new AggregatorFactory[] {
+            new LongSumAggregatorFactory("res", "c2")
+        }
+    );
+
+    new RowsAndColumnsHelper()
+    .expectColumn("c1", c1Vals)
+    .expectColumn("c2", c2Vals)
+    .expectColumn("res", resVals)
+        .allColumnsRegistered()
+        .validate(results);
+  }
+
 }
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/Windowing.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/rel/Windowing.java
index 9f8d3d091b5..60f0f1d539d 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/Windowing.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/Windowing.java
@@ -355,12 +355,16 @@ public class Windowing
 
     public WindowFrame getWindowFrame()
     {
+      if (group.lowerBound.isUnbounded() && group.upperBound.isUnbounded()) {
+        return WindowFrame.unbounded();
+      }
       return new WindowFrame(
-          WindowFrame.PeerType.ROWS,
+          group.isRows ? WindowFrame.PeerType.ROWS : 
WindowFrame.PeerType.RANGE,
           group.lowerBound.isUnbounded(),
           figureOutOffset(group.lowerBound),
           group.upperBound.isUnbounded(),
-          figureOutOffset(group.upperBound)
+          figureOutOffset(group.upperBound),
+          group.isRows ? null : getOrdering()
       );
     }
 
diff --git 
a/sql/src/test/java/org/apache/druid/query/OperatorFactoryBuilders.java 
b/sql/src/test/java/org/apache/druid/query/OperatorFactoryBuilders.java
index 29aae495e8f..0550959f94b 100644
--- a/sql/src/test/java/org/apache/druid/query/OperatorFactoryBuilders.java
+++ b/sql/src/test/java/org/apache/druid/query/OperatorFactoryBuilders.java
@@ -20,6 +20,7 @@
 package org.apache.druid.query;
 
 import com.google.common.base.Preconditions;
+import org.apache.druid.query.aggregation.AggregatorFactory;
 import org.apache.druid.query.filter.DimFilter;
 import org.apache.druid.query.operator.ColumnWithDirection;
 import org.apache.druid.query.operator.ColumnWithDirection.Direction;
@@ -30,6 +31,8 @@ import org.apache.druid.query.operator.OperatorFactory;
 import org.apache.druid.query.operator.ScanOperatorFactory;
 import org.apache.druid.query.operator.window.ComposingProcessor;
 import org.apache.druid.query.operator.window.Processor;
+import org.apache.druid.query.operator.window.WindowFrame;
+import org.apache.druid.query.operator.window.WindowFramedAggregateProcessor;
 import org.apache.druid.query.operator.window.WindowOperatorFactory;
 import org.apache.druid.query.operator.window.ranking.WindowRankProcessor;
 
@@ -99,4 +102,9 @@ public class OperatorFactoryBuilders
   {
     return new WindowRankProcessor(Arrays.asList(groupingColumns), 
outputColumn, false);
   }
+
+  public static Processor framedAggregateProcessor(WindowFrame window, 
AggregatorFactory... aggregations)
+  {
+    return new WindowFramedAggregateProcessor(window, aggregations);
+  }
 }
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
index 43e8e4f77c9..716955d0cf4 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
@@ -96,6 +96,7 @@ import org.apache.druid.query.groupby.orderby.NoopLimitSpec;
 import org.apache.druid.query.groupby.orderby.OrderByColumnSpec;
 import org.apache.druid.query.groupby.orderby.OrderByColumnSpec.Direction;
 import org.apache.druid.query.operator.ColumnWithDirection;
+import org.apache.druid.query.operator.window.WindowFrame;
 import org.apache.druid.query.ordering.StringComparators;
 import org.apache.druid.query.scan.ScanQuery;
 import org.apache.druid.query.scan.ScanQuery.ResultFormat;
@@ -15037,4 +15038,69 @@ public class CalciteQueryTest extends 
BaseCalciteQueryTest
         .expectedResults(expectedResults)
         .run();
   }
+
+  @NotYetSupported(Modes.CANNOT_TRANSLATE)
+  @Test
+  public void testWindowingWithOrderBy()
+  {
+    skipVectorize();
+    msqIncompatible();
+    testBuilder()
+        .sql(
+            "SELECT\n"
+                + "  FLOOR(__time TO DAY) t,\n"
+                + "  SUM(cnt) c,\n"
+                + "  SUM(SUM(cnt)) OVER (ORDER BY FLOOR(__time TO DAY)) cc\n"
+                + "FROM foo\n"
+                + "GROUP BY FLOOR(__time TO DAY)"
+        )
+        .queryContext(
+            ImmutableMap.of(
+                PlannerContext.CTX_ENABLE_WINDOW_FNS, true,
+                QueryContexts.ENABLE_DEBUG, true
+            )
+        )
+        .expectedQuery(
+            WindowOperatorQueryBuilder.builder()
+                .setDataSource(
+                    Druids.newTimeseriesQueryBuilder()
+                        .dataSource(CalciteTests.DATASOURCE1)
+                        .intervals(querySegmentSpec(Filtration.eternity()))
+                        .granularity(Granularities.DAY)
+                        .aggregators(
+                            new LongSumAggregatorFactory("a0", "cnt")
+                        )
+                        .context(OUTER_LIMIT_CONTEXT)
+                        .build()
+                )
+                .setSignature(
+                    RowSignature.builder()
+                        .add("d0", ColumnType.LONG)
+                        .add("a0", ColumnType.LONG)
+                        .add("w0", ColumnType.LONG)
+                        .build()
+                )
+                .setOperators(
+                    OperatorFactoryBuilders.naivePartitionOperator(),
+                    OperatorFactoryBuilders.windowOperators(
+                        OperatorFactoryBuilders.framedAggregateProcessor(
+                            
WindowFrame.forOrderBy(ColumnWithDirection.ascending("d0")),
+                            new LongSumAggregatorFactory("w0", "a0")
+                        )
+                    )
+                )
+                .build()
+        )
+        .expectedResults(
+            ImmutableList.of(
+                new Object[] {946684800000L, 1L, 1L},
+                new Object[] {946771200000L, 1L, 2L},
+                new Object[] {946857600000L, 1L, 3L},
+                new Object[] {978307200000L, 1L, 4L},
+                new Object[] {978393600000L, 1L, 5L},
+                new Object[] {978480000000L, 1L, 6L}
+            )
+        )
+        .run();
+  }
 }
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/DrillWindowQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/DrillWindowQueryTest.java
index 5d2098b760e..d343cfe9800 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/DrillWindowQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/DrillWindowQueryTest.java
@@ -4972,7 +4972,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_7")
   @Test
   public void test_aggregates_winFnQry_7()
@@ -4987,7 +4986,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/testW_Nulls_11")
   @Test
   public void test_aggregates_testW_Nulls_11()
@@ -5256,7 +5254,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/testW_Nulls_7")
   @Test
   public void test_aggregates_testW_Nulls_7()
@@ -5271,7 +5268,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/testW_Nulls_9")
   @Test
   public void test_aggregates_testW_Nulls_9()
@@ -5293,7 +5289,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_64")
   @Test
   public void test_aggregates_winFnQry_64()
@@ -5301,7 +5296,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_65")
   @Test
   public void test_aggregates_winFnQry_65()
@@ -5389,7 +5383,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_76")
   @Test
   public void test_aggregates_winFnQry_76()
@@ -5397,7 +5390,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_77")
   @Test
   public void test_aggregates_winFnQry_77()
@@ -5405,7 +5397,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_78")
   @Test
   public void test_aggregates_winFnQry_78()
@@ -5427,7 +5418,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_81")
   @Test
   public void test_aggregates_winFnQry_81()
@@ -5435,7 +5425,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_82")
   @Test
   public void test_aggregates_winFnQry_82()
@@ -6225,7 +6214,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_16")
   @Test
   public void test_aggregates_winFnQry_16()
@@ -6241,7 +6229,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_1")
   @Test
   public void test_aggregates_winFnQry_1()
@@ -6249,7 +6236,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_26")
   @Test
   public void test_aggregates_winFnQry_26()
@@ -6257,7 +6243,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_28")
   @Test
   public void test_aggregates_winFnQry_28()
@@ -6265,7 +6250,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_2")
   @Test
   public void test_aggregates_winFnQry_2()
@@ -6273,7 +6257,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_31")
   @Test
   public void test_aggregates_winFnQry_31()
@@ -6281,7 +6264,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_3")
   @Test
   public void test_aggregates_winFnQry_3()
@@ -6289,7 +6271,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_46")
   @Test
   public void test_aggregates_winFnQry_46()
@@ -6297,7 +6278,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_47")
   @Test
   public void test_aggregates_winFnQry_47()
@@ -6305,7 +6285,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_48")
   @Test
   public void test_aggregates_winFnQry_48()
@@ -6313,7 +6292,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_49")
   @Test
   public void test_aggregates_winFnQry_49()
@@ -6321,7 +6299,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_4")
   @Test
   public void test_aggregates_winFnQry_4()
@@ -6329,7 +6306,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_50")
   @Test
   public void test_aggregates_winFnQry_50()
@@ -6337,7 +6313,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_51")
   @Test
   public void test_aggregates_winFnQry_51()
@@ -6345,7 +6320,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_52")
   @Test
   public void test_aggregates_winFnQry_52()
@@ -6353,7 +6327,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_53")
   @Test
   public void test_aggregates_winFnQry_53()
@@ -6361,7 +6334,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_54")
   @Test
   public void test_aggregates_winFnQry_54()
@@ -6369,7 +6341,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_55")
   @Test
   public void test_aggregates_winFnQry_55()
@@ -6377,7 +6348,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_5")
   @Test
   public void test_aggregates_winFnQry_5()
@@ -6401,7 +6371,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/winFnQry_8")
   @Test
   public void test_aggregates_winFnQry_8()
@@ -6479,7 +6448,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_10")
   @Test
   public void test_aggregates_woPrtnBy_10()
@@ -6487,7 +6455,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_12")
   @Test
   public void test_aggregates_woPrtnBy_12()
@@ -6495,7 +6462,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_13")
   @Test
   public void test_aggregates_woPrtnBy_13()
@@ -6503,7 +6469,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_14")
   @Test
   public void test_aggregates_woPrtnBy_14()
@@ -6511,7 +6476,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_15")
   @Test
   public void test_aggregates_woPrtnBy_15()
@@ -6519,7 +6483,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_17")
   @Test
   public void test_aggregates_woPrtnBy_17()
@@ -6527,7 +6490,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_18")
   @Test
   public void test_aggregates_woPrtnBy_18()
@@ -6535,7 +6497,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_19")
   @Test
   public void test_aggregates_woPrtnBy_19()
@@ -6543,7 +6504,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_20")
   @Test
   public void test_aggregates_woPrtnBy_20()
@@ -6551,7 +6511,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_25")
   @Test
   public void test_aggregates_woPrtnBy_25()
@@ -6559,7 +6518,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_3")
   @Test
   public void test_aggregates_woPrtnBy_3()
@@ -6567,7 +6525,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_4")
   @Test
   public void test_aggregates_woPrtnBy_4()
@@ -6575,7 +6532,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_5")
   @Test
   public void test_aggregates_woPrtnBy_5()
@@ -6583,7 +6539,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_6")
   @Test
   public void test_aggregates_woPrtnBy_6()
@@ -6591,7 +6546,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_7")
   @Test
   public void test_aggregates_woPrtnBy_7()
@@ -6599,7 +6553,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_8")
   @Test
   public void test_aggregates_woPrtnBy_8()
@@ -6607,7 +6560,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("aggregates/woPrtnBy_9")
   @Test
   public void test_aggregates_woPrtnBy_9()
@@ -7557,7 +7509,6 @@ public class DrillWindowQueryTest extends 
BaseCalciteQueryTest
     windowQueryTest();
   }
 
-  @NotYetSupported(Modes.RESULT_MISMATCH)
   @DrillTest("nestedAggs/cte_win_05")
   @Test
   public void test_nestedAggs_cte_win_05()
diff --git a/sql/src/test/resources/calcite/tests/window/range_handling.sqlTest 
b/sql/src/test/resources/calcite/tests/window/range_handling.sqlTest
new file mode 100644
index 00000000000..717778d1fe2
--- /dev/null
+++ b/sql/src/test/resources/calcite/tests/window/range_handling.sqlTest
@@ -0,0 +1,24 @@
+type: "operatorValidation"
+
+sql: |
+  SELECT
+    FLOOR(m1/3),
+    DENSE_RANK() OVER (ORDER BY FLOOR(m1/3)),
+    'prefix',
+    COUNT(1) OVER (ORDER BY FLOOR(m1/3) ROWS BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW),
+    COUNT(1) OVER (ORDER BY FLOOR(m1/3) RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW),
+    'postfix',
+    COUNT(1) OVER (ORDER BY FLOOR(m1/3) ROWS BETWEEN CURRENT ROW AND UNBOUNDED 
FOLLOWING),
+    COUNT(1) OVER (ORDER BY FLOOR(m1/3) RANGE BETWEEN CURRENT ROW AND 
UNBOUNDED FOLLOWING),
+    'k(1)',
+    COUNT(1) OVER (ORDER BY FLOOR(m1/3) ROWS BETWEEN 1 PRECEDING AND 1 
FOLLOWING),
+    COUNT(1) OVER (ORDER BY FLOOR(m1/3) RANGE BETWEEN 1 PRECEDING AND 1 
FOLLOWING)
+  FROM foo
+
+expectedResults:
+  - [0.0,1,"prefix",1,2,"postfix",6,6,"k(1)",2,5]
+  - [0.0,1,"prefix",2,2,"postfix",5,6,"k(1)",3,5]
+  - [1.0,2,"prefix",3,5,"postfix",4,4,"k(1)",3,6]
+  - [1.0,2,"prefix",4,5,"postfix",3,4,"k(1)",3,6]
+  - [1.0,2,"prefix",5,5,"postfix",2,4,"k(1)",3,6]
+  - [2.0,3,"prefix",6,6,"postfix",1,1,"k(1)",2,4]
diff --git a/sql/src/test/resources/calcite/tests/window/simpleSum.sqlTest 
b/sql/src/test/resources/calcite/tests/window/simpleSum.sqlTest
index d4affc6ec56..9ca9f88e850 100644
--- a/sql/src/test/resources/calcite/tests/window/simpleSum.sqlTest
+++ b/sql/src/test/resources/calcite/tests/window/simpleSum.sqlTest
@@ -13,7 +13,13 @@ expectedOperators:
   - type: "window"
     processor:
       type: "framedAgg"
-      frame: { peerType: "ROWS", lowUnbounded: true, lowOffset: 0, 
uppUnbounded: false, uppOffset: 0 }
+      frame:
+          peerType: "RANGE"
+          lowUnbounded: true
+          lowOffset: 0
+          uppUnbounded: false
+          uppOffset: 0
+          orderBy: [ {column: "d0", direction: ASC} ]
       aggregations:
         - { type: "longSum", name: "w0", fieldName: "a0" }
 
diff --git 
a/sql/src/test/resources/calcite/tests/window/wikipediaAggregationsMultipleOrdering.sqlTest
 
b/sql/src/test/resources/calcite/tests/window/wikipediaAggregationsMultipleOrdering.sqlTest
index e441d0f6f76..221f7a52bcd 100644
--- 
a/sql/src/test/resources/calcite/tests/window/wikipediaAggregationsMultipleOrdering.sqlTest
+++ 
b/sql/src/test/resources/calcite/tests/window/wikipediaAggregationsMultipleOrdering.sqlTest
@@ -15,7 +15,15 @@ expectedOperators:
   - type: "window"
     processor:
       type: "framedAgg"
-      frame: { peerType: "ROWS", lowUnbounded: false, lowOffset: 3, 
uppUnbounded: false, uppOffset: 2 }
+      frame:
+        peerType: "RANGE"
+        lowUnbounded: false
+        lowOffset: 3
+        uppUnbounded: false
+        uppOffset: 2
+        orderBy:
+          - column: d1
+            direction: ASC
       aggregations:
         - { type: "longSum", name: "w0", fieldName: "a0" }
   - { type: "naiveSort", columns: [ { column: "d1", direction: "ASC" }, { 
column: "a0", direction: "ASC"} ]}
diff --git 
a/sql/src/test/resources/calcite/tests/window/wikipediaCumulativeOrdered.sqlTest
 
b/sql/src/test/resources/calcite/tests/window/wikipediaCumulativeOrdered.sqlTest
index a5ed81a50c0..884ee77113c 100644
--- 
a/sql/src/test/resources/calcite/tests/window/wikipediaCumulativeOrdered.sqlTest
+++ 
b/sql/src/test/resources/calcite/tests/window/wikipediaCumulativeOrdered.sqlTest
@@ -38,7 +38,15 @@ expectedOperators:
         - { "type": "denseRank", "group": [ "a0" ], "outputColumn": "w8" }
         - { "type": "cumeDist", "group": [ "a0" ], "outputColumn": "w9" }
         - type: "framedAgg"
-          frame: { peerType: "ROWS", lowUnbounded: true, lowOffset: 0, 
uppUnbounded: false, uppOffset: 0 }
+          frame:
+            peerType: "RANGE"
+            lowUnbounded: true
+            lowOffset: 0
+            uppUnbounded: false
+            uppOffset: 0
+            orderBy:
+              - column: a0
+                direction: ASC
           aggregations:
             - { "type": "longSum", "name": "w0", "fieldName": "a0" }
 
@@ -86,7 +94,7 @@ expectedResults:
   - 
["AR",1442084400000,-5,-650,1442077200000,1442030400000,-591,2514,1,3,0.125,3,0.17647058823529413]
   - 
["AR",1442030400000,-3,-653,1442055600000,1442066400000,-591,2514,1,4,0.1875,4,0.23529411764705882]
   - 
["AR",1442066400000,0,-653,1442084400000,1442019600000,-591,2514,1,5,0.25,5,0.29411764705882354]
-  - 
["AR",1442019600000,1,-652,1442030400000,1442080800000,-591,2514,1,6,0.3125,6,0.4117647058823529]
+  - 
["AR",1442019600000,1,-651,1442030400000,1442080800000,-591,2514,1,6,0.3125,6,0.4117647058823529]
   - 
["AR",1442080800000,1,-651,1442066400000,1442062800000,-591,2514,2,6,0.3125,6,0.4117647058823529]
   - 
["AR",1442062800000,29,-622,1442019600000,1442098800000,-591,2514,2,8,0.4375,7,0.47058823529411764]
   - 
["AR",1442098800000,64,-558,1442080800000,1442037600000,-591,2514,2,9,0.5,8,0.5294117647058824]
@@ -153,7 +161,7 @@ expectedResults:
   - ["BG",1442052000000,18936,19592,1442059200000,null,9,18936,3,5,1.0,5,1.0]
   - ["BH",1442052000000,44,44,null,null,44,44,1,1,0.0,1,1.0]
   - 
["BO",1442095200000,-4,-4,null,1442080800000,-4,4,1,1,0.0,1,0.3333333333333333]
-  - ["BO",1442080800000,4,0,null,1442088000000,-4,4,2,2,0.5,2,1.0]
+  - ["BO",1442080800000,4,4,null,1442088000000,-4,4,2,2,0.5,2,1.0]
   - ["BO",1442088000000,4,4,1442095200000,null,-4,4,3,2,0.5,2,1.0]
   - 
["BR",1442098800000,-645,-645,null,1442080800000,-645,2253,1,1,0.0,1,0.043478260869565216]
   - 
["BR",1442080800000,-267,-912,null,1442016000000,-645,2253,1,2,0.045454545454545456,2,0.08695652173913043]
@@ -178,7 +186,7 @@ expectedResults:
   - 
["BR",1442066400000,1034,4210,1442095200000,1442073600000,-645,2253,3,21,0.9090909090909091,21,0.9130434782608695]
   - 
["BR",1442073600000,2087,6297,1442023200000,1442077200000,-645,2253,3,22,0.9545454545454546,22,0.9565217391304348]
   - ["BR",1442077200000,2253,8550,1442066400000,null,-645,2253,3,23,1.0,23,1.0]
-  - 
["BY",1442055600000,1,1,null,1442084400000,1,1464,1,1,0.0,1,0.2857142857142857]
+  - 
["BY",1442055600000,1,2,null,1442084400000,1,1464,1,1,0.0,1,0.2857142857142857]
   - 
["BY",1442084400000,1,2,null,1442080800000,1,1464,1,1,0.0,1,0.2857142857142857]
   - 
["BY",1442080800000,28,30,1442055600000,1442077200000,1,1464,1,3,0.3333333333333333,2,0.42857142857142855]
   - 
["BY",1442077200000,30,60,1442084400000,1442088000000,1,1464,2,4,0.5,3,0.5714285714285714]
@@ -224,13 +232,13 @@ expectedResults:
   - 
["CL",1442066400000,-41,-687,1442019600000,1442077200000,-370,390,1,3,0.10526315789473684,3,0.15]
   - 
["CL",1442077200000,-15,-702,1442095200000,1442059200000,-370,390,1,4,0.15789473684210525,4,0.2]
   - 
["CL",1442059200000,-12,-714,1442066400000,1442034000000,-370,390,1,5,0.21052631578947367,5,0.25]
-  - 
["CL",1442034000000,-1,-715,1442077200000,1442041200000,-370,390,1,6,0.2631578947368421,6,0.35]
+  - 
["CL",1442034000000,-1,-716,1442077200000,1442041200000,-370,390,1,6,0.2631578947368421,6,0.35]
   - 
["CL",1442041200000,-1,-716,1442059200000,1442037600000,-370,390,1,6,0.2631578947368421,6,0.35]
   - 
["CL",1442037600000,2,-714,1442034000000,1442098800000,-370,390,2,8,0.3684210526315789,7,0.4]
   - 
["CL",1442098800000,9,-705,1442041200000,1442070000000,-370,390,2,9,0.42105263157894735,8,0.45]
   - 
["CL",1442070000000,13,-692,1442037600000,1442023200000,-370,390,2,10,0.47368421052631576,9,0.5]
   - 
["CL",1442023200000,15,-677,1442098800000,1442062800000,-370,390,2,11,0.5263157894736842,10,0.55]
-  - 
["CL",1442062800000,17,-660,1442070000000,1442080800000,-370,390,2,12,0.5789473684210527,11,0.65]
+  - 
["CL",1442062800000,17,-643,1442070000000,1442080800000,-370,390,2,12,0.5789473684210527,11,0.65]
   - 
["CL",1442080800000,17,-643,1442023200000,1442091600000,-370,390,2,12,0.5789473684210527,11,0.65]
   - 
["CL",1442091600000,20,-623,1442062800000,1442030400000,-370,390,2,14,0.6842105263157895,12,0.7]
   - 
["CL",1442030400000,40,-583,1442080800000,1442084400000,-370,390,3,15,0.7368421052631579,13,0.75]
@@ -265,7 +273,7 @@ expectedResults:
   - 
["CO",1442088000000,17150,19751,1442059200000,1442073600000,-45,39860,3,14,0.9285714285714286,14,0.9333333333333333]
   - 
["CO",1442073600000,39860,59611,1442077200000,null,-45,39860,3,15,1.0,15,1.0]
   - ["CR",1442041200000,51,51,null,1442019600000,51,2497,1,1,0.0,1,0.125]
-  - 
["CR",1442019600000,62,113,null,1442023200000,51,2497,1,2,0.14285714285714285,2,0.375]
+  - 
["CR",1442019600000,62,175,null,1442023200000,51,2497,1,2,0.14285714285714285,2,0.375]
   - 
["CR",1442023200000,62,175,1442041200000,1442088000000,51,2497,1,2,0.14285714285714285,2,0.375]
   - 
["CR",1442088000000,72,247,1442019600000,1442026800000,51,2497,2,4,0.42857142857142855,3,0.5]
   - 
["CR",1442026800000,140,387,1442023200000,1442048400000,51,2497,2,5,0.5714285714285714,4,0.625]
@@ -318,7 +326,7 @@ expectedResults:
   - 
["DK",1442080800000,61,39,1442044800000,1442091600000,-97,416,3,10,0.8181818181818182,9,0.8333333333333334]
   - 
["DK",1442091600000,139,178,1442055600000,1442066400000,-97,416,3,11,0.9090909090909091,10,0.9166666666666666]
   - ["DK",1442066400000,416,594,1442080800000,null,-97,416,3,12,1.0,11,1.0]
-  - ["DO",1442023200000,8,8,null,1442084400000,8,200,1,1,0.0,1,0.4]
+  - ["DO",1442023200000,8,16,null,1442084400000,8,200,1,1,0.0,1,0.4]
   - ["DO",1442084400000,8,16,null,1442095200000,8,200,1,1,0.0,1,0.4]
   - ["DO",1442095200000,13,29,1442023200000,1442066400000,8,200,2,3,0.5,2,0.6]
   - ["DO",1442066400000,35,64,1442084400000,1442073600000,8,200,2,4,0.75,3,0.8]
@@ -440,7 +448,7 @@ expectedResults:
   - 
["HK",1442091600000,-3,-342,1442019600000,1442095200000,-211,5545,1,4,0.16666666666666666,4,0.21052631578947367]
   - 
["HK",1442095200000,-1,-343,1442041200000,1442080800000,-211,5545,1,5,0.2222222222222222,5,0.2631578947368421]
   - 
["HK",1442080800000,0,-343,1442091600000,1442048400000,-211,5545,1,6,0.2777777777777778,6,0.3157894736842105]
-  - 
["HK",1442048400000,1,-342,1442095200000,1442062800000,-211,5545,1,7,0.3333333333333333,7,0.42105263157894735]
+  - 
["HK",1442048400000,1,-341,1442095200000,1442062800000,-211,5545,1,7,0.3333333333333333,7,0.42105263157894735]
   - 
["HK",1442062800000,1,-341,1442080800000,1442059200000,-211,5545,2,7,0.3333333333333333,7,0.42105263157894735]
   - 
["HK",1442059200000,2,-339,1442048400000,1442052000000,-211,5545,2,9,0.4444444444444444,8,0.47368421052631576]
   - 
["HK",1442052000000,15,-324,1442062800000,1442044800000,-211,5545,2,10,0.5,9,0.5263157894736842]
@@ -488,14 +496,14 @@ expectedResults:
   - ["ID",1442030400000,279,-255,1442070000000,null,-416,279,3,13,1.0,13,1.0]
   - ["IE",1442070000000,-100,-100,null,1442091600000,-100,1062,1,1,0.0,1,0.125]
   - 
["IE",1442091600000,-71,-171,null,1442026800000,-100,1062,1,2,0.14285714285714285,2,0.25]
-  - 
["IE",1442026800000,1,-170,1442070000000,1442030400000,-100,1062,1,3,0.2857142857142857,3,0.5]
+  - 
["IE",1442026800000,1,-169,1442070000000,1442030400000,-100,1062,1,3,0.2857142857142857,3,0.5]
   - 
["IE",1442030400000,1,-169,1442091600000,1442048400000,-100,1062,2,3,0.2857142857142857,3,0.5]
   - 
["IE",1442048400000,27,-142,1442026800000,1442077200000,-100,1062,2,5,0.5714285714285714,4,0.625]
   - 
["IE",1442077200000,403,261,1442030400000,1442084400000,-100,1062,2,6,0.7142857142857143,5,0.75]
   - 
["IE",1442084400000,819,1080,1442048400000,1442066400000,-100,1062,3,7,0.8571428571428571,6,0.875]
   - ["IE",1442066400000,1062,2142,1442077200000,null,-100,1062,3,8,1.0,7,1.0]
   - ["IL",1442095200000,0,0,null,1442066400000,0,2745,1,1,0.0,1,0.0625]
-  - 
["IL",1442066400000,3,3,null,1442098800000,0,2745,1,2,0.06666666666666667,2,0.1875]
+  - 
["IL",1442066400000,3,6,null,1442098800000,0,2745,1,2,0.06666666666666667,2,0.1875]
   - 
["IL",1442098800000,3,6,1442095200000,1442055600000,0,2745,1,2,0.06666666666666667,2,0.1875]
   - ["IL",1442055600000,4,10,1442066400000,1442048400000,0,2745,1,4,0.2,3,0.25]
   - 
["IL",1442048400000,25,35,1442098800000,1442073600000,0,2745,1,5,0.26666666666666666,4,0.3125]
@@ -626,7 +634,7 @@ expectedResults:
   - 
["KR",1442066400000,3299,9957,1442030400000,1442055600000,-374,3640,3,21,0.9523809523809523,21,0.9545454545454546]
   - 
["KR",1442055600000,3640,13597,1442062800000,null,-374,3640,3,22,1.0,22,1.0]
   - ["KW",1442080800000,-33,-33,null,1442055600000,-33,1815,1,1,0.0,1,0.25]
-  - 
["KW",1442055600000,-2,-35,null,1442077200000,-33,1815,1,2,0.3333333333333333,2,0.75]
+  - 
["KW",1442055600000,-2,-37,null,1442077200000,-33,1815,1,2,0.3333333333333333,2,0.75]
   - 
["KW",1442077200000,-2,-37,1442080800000,1442070000000,-33,1815,2,2,0.3333333333333333,2,0.75]
   - ["KW",1442070000000,1815,1778,1442055600000,null,-33,1815,3,4,1.0,3,1.0]
   - 
["KZ",1442077200000,-317,-317,null,1442084400000,-317,439,1,1,0.0,1,0.09090909090909091]
@@ -675,7 +683,7 @@ expectedResults:
   - 
["MX",1442041200000,-294,-1126,1442095200000,1442016000000,-456,3874,1,3,0.125,3,0.17647058823529413]
   - 
["MX",1442016000000,-67,-1193,1442080800000,1442073600000,-456,3874,1,4,0.1875,4,0.23529411764705882]
   - 
["MX",1442073600000,-21,-1214,1442041200000,1442066400000,-456,3874,1,5,0.25,5,0.29411764705882354]
-  - 
["MX",1442066400000,-1,-1215,1442016000000,1442070000000,-456,3874,1,6,0.3125,6,0.4117647058823529]
+  - 
["MX",1442066400000,-1,-1216,1442016000000,1442070000000,-456,3874,1,6,0.3125,6,0.4117647058823529]
   - 
["MX",1442070000000,-1,-1216,1442073600000,1442037600000,-456,3874,2,6,0.3125,6,0.4117647058823529]
   - 
["MX",1442037600000,4,-1212,1442066400000,1442098800000,-456,3874,2,8,0.4375,7,0.47058823529411764]
   - 
["MX",1442098800000,28,-1184,1442070000000,1442030400000,-456,3874,2,9,0.5,8,0.5294117647058824]
@@ -692,8 +700,8 @@ expectedResults:
   - 
["MY",1442019600000,-7,-144,1442044800000,1442030400000,-127,1028,1,3,0.18181818181818182,3,0.25]
   - 
["MY",1442030400000,-3,-147,1442077200000,1442059200000,-127,1028,1,4,0.2727272727272727,4,0.3333333333333333]
   - 
["MY",1442059200000,0,-147,1442019600000,1442055600000,-127,1028,2,5,0.36363636363636365,5,0.4166666666666667]
-  - 
["MY",1442055600000,1,-146,1442030400000,1442066400000,-127,1028,2,6,0.45454545454545453,6,0.6666666666666666]
-  - 
["MY",1442066400000,1,-145,1442059200000,1442073600000,-127,1028,2,6,0.45454545454545453,6,0.6666666666666666]
+  - 
["MY",1442055600000,1,-144,1442030400000,1442066400000,-127,1028,2,6,0.45454545454545453,6,0.6666666666666666]
+  - 
["MY",1442066400000,1,-144,1442059200000,1442073600000,-127,1028,2,6,0.45454545454545453,6,0.6666666666666666]
   - 
["MY",1442073600000,1,-144,1442055600000,1442048400000,-127,1028,2,6,0.45454545454545453,6,0.6666666666666666]
   - 
["MY",1442048400000,649,505,1442066400000,1442098800000,-127,1028,3,9,0.7272727272727273,7,0.75]
   - 
["MY",1442098800000,739,1244,1442073600000,1442041200000,-127,1028,3,10,0.8181818181818182,8,0.8333333333333334]
@@ -721,7 +729,7 @@ expectedResults:
   - 
["NO",1442048400000,-447,-447,null,1442095200000,-447,447,1,1,0.0,1,0.09090909090909091]
   - 
["NO",1442095200000,-1,-448,null,1442098800000,-447,447,1,2,0.1,2,0.18181818181818182]
   - 
["NO",1442098800000,2,-446,1442048400000,1442088000000,-447,447,1,3,0.2,3,0.2727272727272727]
-  - 
["NO",1442088000000,15,-431,1442095200000,1442091600000,-447,447,1,4,0.3,4,0.45454545454545453]
+  - 
["NO",1442088000000,15,-416,1442095200000,1442091600000,-447,447,1,4,0.3,4,0.45454545454545453]
   - 
["NO",1442091600000,15,-416,1442098800000,1442055600000,-447,447,2,4,0.3,4,0.45454545454545453]
   - 
["NO",1442055600000,29,-387,1442088000000,1442080800000,-447,447,2,6,0.5,5,0.5454545454545454]
   - 
["NO",1442080800000,31,-356,1442091600000,1442019600000,-447,447,2,7,0.6,6,0.6363636363636364]
@@ -744,7 +752,7 @@ expectedResults:
   - 
["PE",1442077200000,-163,-163,null,1442084400000,-163,1861,1,1,0.0,1,0.1111111111111111]
   - 
["PE",1442084400000,-68,-231,null,1442095200000,-163,1861,1,2,0.125,2,0.2222222222222222]
   - 
["PE",1442095200000,-19,-250,1442077200000,1442026800000,-163,1861,1,3,0.25,3,0.3333333333333333]
-  - 
["PE",1442026800000,-12,-262,1442084400000,1442062800000,-163,1861,2,4,0.375,4,0.5555555555555556]
+  - 
["PE",1442026800000,-12,-274,1442084400000,1442062800000,-163,1861,2,4,0.375,4,0.5555555555555556]
   - 
["PE",1442062800000,-12,-274,1442095200000,1442080800000,-163,1861,2,4,0.375,4,0.5555555555555556]
   - 
["PE",1442080800000,-2,-276,1442026800000,1442023200000,-163,1861,2,6,0.625,5,0.6666666666666666]
   - 
["PE",1442023200000,26,-250,1442062800000,1442019600000,-163,1861,3,7,0.75,6,0.7777777777777778]
@@ -911,7 +919,7 @@ expectedResults:
   - 
["TR",1442095200000,-29,-29,null,1442080800000,-29,3048,1,1,0.0,1,0.06666666666666667]
   - 
["TR",1442080800000,-1,-30,null,1442041200000,-29,3048,1,2,0.07142857142857142,2,0.13333333333333333]
   - 
["TR",1442041200000,1,-29,1442095200000,1442044800000,-29,3048,1,3,0.14285714285714285,3,0.2]
-  - 
["TR",1442044800000,41,12,1442080800000,1442052000000,-29,3048,1,4,0.21428571428571427,4,0.3333333333333333]
+  - 
["TR",1442044800000,41,53,1442080800000,1442052000000,-29,3048,1,4,0.21428571428571427,4,0.3333333333333333]
   - 
["TR",1442052000000,41,53,1442041200000,1442066400000,-29,3048,1,4,0.21428571428571427,4,0.3333333333333333]
   - 
["TR",1442066400000,85,138,1442044800000,1442048400000,-29,3048,2,6,0.35714285714285715,5,0.4]
   - 
["TR",1442048400000,88,226,1442052000000,1442077200000,-29,3048,2,7,0.42857142857142855,6,0.4666666666666667]
@@ -931,8 +939,8 @@ expectedResults:
   - 
["TW",1442019600000,0,-566,1442095200000,1442030400000,-272,772,1,5,0.19047619047619047,5,0.3181818181818182]
   - 
["TW",1442030400000,0,-566,1442098800000,1442084400000,-272,772,1,5,0.19047619047619047,5,0.3181818181818182]
   - 
["TW",1442084400000,0,-566,1442019600000,1442044800000,-272,772,1,5,0.19047619047619047,5,0.3181818181818182]
-  - 
["TW",1442044800000,24,-542,1442030400000,1442052000000,-272,772,1,8,0.3333333333333333,6,0.45454545454545453]
-  - 
["TW",1442052000000,24,-518,1442084400000,1442080800000,-272,772,2,8,0.3333333333333333,6,0.45454545454545453]
+  - 
["TW",1442044800000,24,-494,1442030400000,1442052000000,-272,772,1,8,0.3333333333333333,6,0.45454545454545453]
+  - 
["TW",1442052000000,24,-494,1442084400000,1442080800000,-272,772,2,8,0.3333333333333333,6,0.45454545454545453]
   - 
["TW",1442080800000,24,-494,1442044800000,1442055600000,-272,772,2,8,0.3333333333333333,6,0.45454545454545453]
   - 
["TW",1442055600000,48,-446,1442052000000,1442048400000,-272,772,2,11,0.47619047619047616,7,0.5]
   - 
["TW",1442048400000,75,-371,1442080800000,1442016000000,-272,772,2,12,0.5238095238095238,8,0.5454545454545454]
@@ -951,7 +959,7 @@ expectedResults:
   - 
["UA",1442095200000,-30,-599,1442091600000,1442088000000,-388,14202,1,3,0.1111111111111111,3,0.15789473684210525]
   - 
["UA",1442088000000,-21,-620,1442077200000,1442059200000,-388,14202,1,4,0.16666666666666666,4,0.21052631578947367]
   - 
["UA",1442059200000,-2,-622,1442095200000,1442037600000,-388,14202,1,5,0.2222222222222222,5,0.2631578947368421]
-  - 
["UA",1442037600000,-1,-623,1442088000000,1442080800000,-388,14202,1,6,0.2777777777777778,6,0.3684210526315789]
+  - 
["UA",1442037600000,-1,-624,1442088000000,1442080800000,-388,14202,1,6,0.2777777777777778,6,0.3684210526315789]
   - 
["UA",1442080800000,-1,-624,1442059200000,1442048400000,-388,14202,1,6,0.2777777777777778,6,0.3684210526315789]
   - 
["UA",1442048400000,2,-622,1442037600000,1442084400000,-388,14202,2,8,0.3888888888888889,7,0.42105263157894735]
   - 
["UA",1442084400000,5,-617,1442080800000,1442098800000,-388,14202,2,9,0.4444444444444444,8,0.47368421052631576]
diff --git 
a/sql/src/test/resources/calcite/tests/window/wikipediaFramedAggregations.sqlTest
 
b/sql/src/test/resources/calcite/tests/window/wikipediaFramedAggregations.sqlTest
index 0644c9a354d..12e5736951b 100644
--- 
a/sql/src/test/resources/calcite/tests/window/wikipediaFramedAggregations.sqlTest
+++ 
b/sql/src/test/resources/calcite/tests/window/wikipediaFramedAggregations.sqlTest
@@ -14,7 +14,13 @@ expectedOperators:
   - type: "window"
     processor:
       type: "framedAgg"
-      frame: { peerType: "ROWS", lowUnbounded: false, lowOffset: 3, 
uppUnbounded: false, uppOffset: 2 }
+      frame:
+          peerType: "RANGE"
+          lowUnbounded: false
+          lowOffset: 3
+          uppUnbounded: false
+          uppOffset: 2
+          orderBy: [ {column: "d1", direction: ASC} ]
       aggregations:
         - { type: "longSum", name: "w0", fieldName: "a0" }
 
diff --git 
a/sql/src/test/resources/calcite/tests/window/windowed_long_null.sqlTest 
b/sql/src/test/resources/calcite/tests/window/windowed_long_null.sqlTest
index 2288425b8e5..c96b979c0da 100644
--- a/sql/src/test/resources/calcite/tests/window/windowed_long_null.sqlTest
+++ b/sql/src/test/resources/calcite/tests/window/windowed_long_null.sqlTest
@@ -31,7 +31,7 @@ expectedOperators:
   - type: "window"
     processor:
       type: "framedAgg"
-      frame: { peerType: "ROWS", lowUnbounded: true, lowOffset: 0, 
uppUnbounded: false, uppOffset: 0 }
+      frame: { peerType: "RANGE", lowUnbounded: true, lowOffset: 0, 
uppUnbounded: false, uppOffset: 0, orderBy: [{ column: l1, direction: ASC }] }
       aggregations:
         - { type: "longMin", name: "w1", fieldName: "l2" }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to