提交 ee85a66b authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Do not reevaluate window aggregates in fast methods when frame is not changed

上级 d902164b
...@@ -123,7 +123,8 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -123,7 +123,8 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
false); iter.hasNext();) { false); iter.hasNext();) {
updateFromExpressions(session, aggregateData, iter.next()); updateFromExpressions(session, aggregateData, iter.next());
} }
i = processGroup(session, result, ordered, rowIdColumn, i, size, aggregateData, grouped); Value r = getAggregatedValue(session, aggregateData);
i = processGroup(session, result, r, ordered, rowIdColumn, i, size, aggregateData, grouped);
} }
} }
...@@ -132,6 +133,7 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -132,6 +133,7 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
Object aggregateData = createAggregateData(); Object aggregateData = createAggregateData();
int size = ordered.size(); int size = ordered.size();
int lastIncludedRow = -1; int lastIncludedRow = -1;
Value r = null;
for (int i = 0; i < size;) { for (int i = 0; i < size;) {
int newLast = WindowFrame.getEndIndex(over, session, ordered, getOverOrderBySort(), i); int newLast = WindowFrame.getEndIndex(over, session, ordered, getOverOrderBySort(), i);
assert newLast >= lastIncludedRow; assert newLast >= lastIncludedRow;
...@@ -140,8 +142,11 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -140,8 +142,11 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
updateFromExpressions(session, aggregateData, ordered.get(j)); updateFromExpressions(session, aggregateData, ordered.get(j));
} }
lastIncludedRow = newLast; lastIncludedRow = newLast;
r = getAggregatedValue(session, aggregateData);
} else if (r == null) {
r = getAggregatedValue(session, aggregateData);
} }
i = processGroup(session, result, ordered, rowIdColumn, i, size, aggregateData, grouped); i = processGroup(session, result, r, ordered, rowIdColumn, i, size, aggregateData, grouped);
} }
} }
...@@ -149,6 +154,7 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -149,6 +154,7 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
ArrayList<Value[]> ordered, int rowIdColumn, boolean grouped) { ArrayList<Value[]> ordered, int rowIdColumn, boolean grouped) {
Object aggregateData = createAggregateData(); Object aggregateData = createAggregateData();
int firstIncludedRow = ordered.size(); int firstIncludedRow = ordered.size();
Value r = null;
for (int i = firstIncludedRow - 1; i >= 0;) { for (int i = firstIncludedRow - 1; i >= 0;) {
int newLast = over.getWindowFrame().getStartIndex(session, ordered, getOverOrderBySort(), i); int newLast = over.getWindowFrame().getStartIndex(session, ordered, getOverOrderBySort(), i);
assert newLast <= firstIncludedRow; assert newLast <= firstIncludedRow;
...@@ -157,9 +163,11 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -157,9 +163,11 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
updateFromExpressions(session, aggregateData, ordered.get(j)); updateFromExpressions(session, aggregateData, ordered.get(j));
} }
firstIncludedRow = newLast; firstIncludedRow = newLast;
r = getAggregatedValue(session, aggregateData);
} else if (r == null) {
r = getAggregatedValue(session, aggregateData);
} }
Value[] lastRowInGroup = ordered.get(i), currentRowInGroup = lastRowInGroup; Value[] lastRowInGroup = ordered.get(i), currentRowInGroup = lastRowInGroup;
Value r = getAggregatedValue(session, aggregateData);
do { do {
result.put(currentRowInGroup[rowIdColumn].getInt(), r); result.put(currentRowInGroup[rowIdColumn].getInt(), r);
} while (--i >= 0 && grouped } while (--i >= 0 && grouped
...@@ -167,10 +175,9 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -167,10 +175,9 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
} }
} }
private int processGroup(Session session, HashMap<Integer, Value> result, ArrayList<Value[]> ordered, private int processGroup(Session session, HashMap<Integer, Value> result, Value r, ArrayList<Value[]> ordered,
int rowIdColumn, int i, int size, Object aggregateData, boolean grouped) { int rowIdColumn, int i, int size, Object aggregateData, boolean grouped) {
Value[] firstRowInGroup = ordered.get(i), currentRowInGroup = firstRowInGroup; Value[] firstRowInGroup = ordered.get(i), currentRowInGroup = firstRowInGroup;
Value r = getAggregatedValue(session, aggregateData);
do { do {
result.put(currentRowInGroup[rowIdColumn].getInt(), r); result.put(currentRowInGroup[rowIdColumn].getInt(), r);
} while (++i < size && grouped } while (++i < size && grouped
......
...@@ -311,6 +311,22 @@ SELECT *, ...@@ -311,6 +311,22 @@ SELECT *,
> 8 9 [7, 8] [9, 9] [4, 5, 6, 7, 8] [8, 8, 8, 9, 9] [9, 9, 8, 8, 8] [4, 5, 6, 7, 8] [8, 8, 8, 9, 9] > 8 9 [7, 8] [9, 9] [4, 5, 6, 7, 8] [8, 8, 8, 9, 9] [9, 9, 8, 8, 8] [4, 5, 6, 7, 8] [8, 8, 8, 9, 9]
> rows: 8 > rows: 8
SELECT *,
ARRAY_AGG(ID ORDER BY ID) OVER (ORDER BY VALUE RANGE BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) A1,
ARRAY_AGG(ID) OVER (ORDER BY VALUE RANGE BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) A2
FROM TEST;
> ID VALUE A1 A2
> -- ----- ------------------------ ------------------------
> 1 1 [1, 2, 3, 4, 5, 6, 7, 8] [1, 2]
> 2 1 [1, 2, 3, 4, 5, 6, 7, 8] [1, 2]
> 3 5 [3, 4, 5, 6, 7, 8] [1, 2, 3]
> 4 8 [4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8]
> 5 8 [4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8]
> 6 8 [4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8]
> 7 9 [4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8]
> 8 9 [4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8]
> rows: 8
SELECT *, ARRAY_AGG(ID) OVER (ORDER BY VALUE ROWS -1 PRECEDING) FROM TEST; SELECT *, ARRAY_AGG(ID) OVER (ORDER BY VALUE ROWS -1 PRECEDING) FROM TEST;
> exception INVALID_VALUE_2 > exception INVALID_VALUE_2
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论