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

Remember expression index in window frame bound

上级 05ea7099
...@@ -95,13 +95,12 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -95,13 +95,12 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
boolean grouped = frame == null boolean grouped = frame == null
|| frame.getUnits() != WindowFrameUnits.ROWS && frame.getExclusion().isGroupOrNoOthers(); || frame.getUnits() != WindowFrameUnits.ROWS && frame.getExclusion().isGroupOrNoOthers();
if (frame == null) { if (frame == null) {
aggregateFastPartition(session, result, ordered, -1, rowIdColumn, grouped); aggregateFastPartition(session, result, ordered, rowIdColumn, grouped);
return; return;
} }
int frameParametersOffset = getWindowFrameParametersOffset();
boolean variableBounds = frame.isVariableBounds(); boolean variableBounds = frame.isVariableBounds();
if (variableBounds) { if (variableBounds) {
variableBounds = checkVariableBounds(frame, ordered, frameParametersOffset); variableBounds = checkVariableBounds(frame, ordered);
} }
if (variableBounds) { if (variableBounds) {
grouped = false; grouped = false;
...@@ -113,12 +112,12 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -113,12 +112,12 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
if (unboundedFollowing) { if (unboundedFollowing) {
aggregateWholePartition(session, result, ordered, rowIdColumn); aggregateWholePartition(session, result, ordered, rowIdColumn);
} else { } else {
aggregateFastPartition(session, result, ordered, frameParametersOffset, rowIdColumn, grouped); aggregateFastPartition(session, result, ordered, rowIdColumn, grouped);
} }
return; return;
} }
if (unboundedFollowing) { if (unboundedFollowing) {
aggregateFastPartitionInReverse(session, result, ordered, frameParametersOffset, rowIdColumn, grouped); aggregateFastPartitionInReverse(session, result, ordered, rowIdColumn, grouped);
return; return;
} }
} }
...@@ -126,8 +125,8 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -126,8 +125,8 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
int size = ordered.size(); int size = ordered.size();
for (int i = 0; i < size;) { for (int i = 0; i < size;) {
Object aggregateData = createAggregateData(); Object aggregateData = createAggregateData();
for (Iterator<Value[]> iter = WindowFrame.iterator(over, session, ordered, getOverOrderBySort(), for (Iterator<Value[]> iter = WindowFrame.iterator(over, session, ordered, getOverOrderBySort(), i,
frameParametersOffset, i, false); iter.hasNext();) { false); iter.hasNext();) {
updateFromExpressions(session, aggregateData, iter.next()); updateFromExpressions(session, aggregateData, iter.next());
} }
Value r = getAggregatedValue(session, aggregateData); Value r = getAggregatedValue(session, aggregateData);
...@@ -135,20 +134,21 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -135,20 +134,21 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
} }
} }
private static boolean checkVariableBounds(WindowFrame frame, ArrayList<Value[]> ordered, private static boolean checkVariableBounds(WindowFrame frame, ArrayList<Value[]> ordered) {
int frameParametersOffset) {
int size = ordered.size(); int size = ordered.size();
int offset = frameParametersOffset; WindowFrameBound bound = frame.getStarting();
if (frame.getStarting().isVariable()) { if (bound.isVariable()) {
int offset = bound.getExpressionIndex();
Value v = ordered.get(0)[offset]; Value v = ordered.get(0)[offset];
for (int i = 1; i < size; i++) { for (int i = 1; i < size; i++) {
if (!v.equals(ordered.get(i)[offset])) { if (!v.equals(ordered.get(i)[offset])) {
return true; return true;
} }
} }
offset++;
} }
if (frame.getFollowing() != null && frame.getFollowing().isVariable()) { bound = frame.getFollowing();
if (bound != null && bound.isVariable()) {
int offset = bound.getExpressionIndex();
Value v = ordered.get(0)[offset]; Value v = ordered.get(0)[offset];
for (int i = 1; i < size; i++) { for (int i = 1; i < size; i++) {
if (!v.equals(ordered.get(i)[offset])) { if (!v.equals(ordered.get(i)[offset])) {
...@@ -160,14 +160,13 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -160,14 +160,13 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
} }
private void aggregateFastPartition(Session session, HashMap<Integer, Value> result, ArrayList<Value[]> ordered, private void aggregateFastPartition(Session session, HashMap<Integer, Value> result, ArrayList<Value[]> ordered,
int frameParametersOffset, int rowIdColumn, boolean grouped) { int rowIdColumn, boolean grouped) {
Object aggregateData = createAggregateData(); Object aggregateData = createAggregateData();
int size = ordered.size(); int size = ordered.size();
int lastIncludedRow = -1; int lastIncludedRow = -1;
Value r = null; Value r = null;
for (int i = 0; i < size;) { for (int i = 0; i < size;) {
int newLast = WindowFrame.getEndIndex(over, session, ordered, frameParametersOffset, getOverOrderBySort(), int newLast = WindowFrame.getEndIndex(over, session, ordered, getOverOrderBySort(), i);
i);
assert newLast >= lastIncludedRow; assert newLast >= lastIncludedRow;
if (newLast > lastIncludedRow) { if (newLast > lastIncludedRow) {
for (int j = lastIncludedRow + 1; j <= newLast; j++) { for (int j = lastIncludedRow + 1; j <= newLast; j++) {
...@@ -183,13 +182,12 @@ public abstract class AbstractAggregate extends DataAnalysisOperation { ...@@ -183,13 +182,12 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
} }
private void aggregateFastPartitionInReverse(Session session, HashMap<Integer, Value> result, private void aggregateFastPartitionInReverse(Session session, HashMap<Integer, Value> result,
ArrayList<Value[]> ordered, int frameParametersOffset, 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; Value r = null;
for (int i = firstIncludedRow - 1; i >= 0;) { for (int i = firstIncludedRow - 1; i >= 0;) {
int newLast = over.getWindowFrame().getStartIndex(session, ordered, frameParametersOffset, int newLast = over.getWindowFrame().getStartIndex(session, ordered, getOverOrderBySort(), i);
getOverOrderBySort(), i);
assert newLast <= firstIncludedRow; assert newLast <= firstIncludedRow;
if (newLast < firstIncludedRow) { if (newLast < firstIncludedRow) {
for (int j = firstIncludedRow - 1; j >= newLast; j--) { for (int j = firstIncludedRow - 1; j >= newLast; j--) {
......
...@@ -161,12 +161,19 @@ public abstract class DataAnalysisOperation extends Expression { ...@@ -161,12 +161,19 @@ public abstract class DataAnalysisOperation extends Expression {
} }
WindowFrame frame = over.getWindowFrame(); WindowFrame frame = over.getWindowFrame();
if (frame != null) { if (frame != null) {
int index = getNumExpressions();
if (orderBy != null) {
index += orderBy.size();
}
int n = 0; int n = 0;
if (frame.getStarting().isVariable()) { WindowFrameBound bound = frame.getStarting();
if (bound.isVariable()) {
bound.setExpressionIndex(index);
n++; n++;
} }
WindowFrameBound following = frame.getFollowing(); bound = frame.getFollowing();
if (following != null && following.isVariable()) { if (bound != null && bound.isVariable()) {
bound.setExpressionIndex(index + n);
n++; n++;
} }
numFrameExpressions = n; numFrameExpressions = n;
...@@ -358,20 +365,6 @@ public abstract class DataAnalysisOperation extends Expression { ...@@ -358,20 +365,6 @@ public abstract class DataAnalysisOperation extends Expression {
: getWindowResult(session, groupData); : getWindowResult(session, groupData);
} }
/**
* Returns offset of window frame parameters.
*
* @return offset of window frame parameters
*/
protected final int getWindowFrameParametersOffset() {
int frameParametersOffset = getNumExpressions();
ArrayList<SelectOrderBy> orderBy = over.getOrderBy();
if (orderBy != null) {
frameParametersOffset += orderBy.size();
}
return frameParametersOffset;
}
/** /**
* Returns result of this window function or window aggregate. This method * Returns result of this window function or window aggregate. This method
* is not used for plain aggregates. * is not used for plain aggregates.
......
...@@ -20,6 +20,8 @@ public class WindowFrameBound { ...@@ -20,6 +20,8 @@ public class WindowFrameBound {
private boolean isVariable; private boolean isVariable;
private int expressionIndex = -1;
/** /**
* Creates new instance of window frame bound. * Creates new instance of window frame bound.
* *
...@@ -65,6 +67,25 @@ public class WindowFrameBound { ...@@ -65,6 +67,25 @@ public class WindowFrameBound {
return isVariable; return isVariable;
} }
/**
* Returns the index of preserved expression.
*
* @return the index of preserved expression, or -1
*/
public int getExpressionIndex() {
return expressionIndex;
}
/**
* Sets the index of preserved expression.
*
* @param expressionIndex
* the index to set
*/
void setExpressionIndex(int expressionIndex) {
this.expressionIndex = expressionIndex;
}
/** /**
* Map the columns of the resolver to expression columns. * Map the columns of the resolver to expression columns.
* *
......
...@@ -349,19 +349,18 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -349,19 +349,18 @@ public class WindowFunction extends DataAnalysisOperation {
private void getNth(Session session, HashMap<Integer, Value> result, ArrayList<Value[]> ordered, int rowIdColumn) { private void getNth(Session session, HashMap<Integer, Value> result, ArrayList<Value[]> ordered, int rowIdColumn) {
int size = ordered.size(); int size = ordered.size();
int frameParametersOffset = getWindowFrameParametersOffset();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Value[] row = ordered.get(i); Value[] row = ordered.get(i);
int rowId = row[rowIdColumn].getInt(); int rowId = row[rowIdColumn].getInt();
Value v; Value v;
switch (type) { switch (type) {
case FIRST_VALUE: case FIRST_VALUE:
v = getNthValue(WindowFrame.iterator(over, session, ordered, getOverOrderBySort(), v = getNthValue(WindowFrame.iterator(over, session, ordered, getOverOrderBySort(), i, false), 0,
frameParametersOffset, i, false), 0, ignoreNulls); ignoreNulls);
break; break;
case LAST_VALUE: case LAST_VALUE:
v = getNthValue(WindowFrame.iterator(over, session, ordered, getOverOrderBySort(), v = getNthValue(WindowFrame.iterator(over, session, ordered, getOverOrderBySort(), i, true), 0,
frameParametersOffset, i, true), 0, ignoreNulls); ignoreNulls);
break; break;
case NTH_VALUE: { case NTH_VALUE: {
int n = row[1].getInt(); int n = row[1].getInt();
...@@ -369,8 +368,8 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -369,8 +368,8 @@ public class WindowFunction extends DataAnalysisOperation {
throw DbException.getInvalidValueException("nth row", n); throw DbException.getInvalidValueException("nth row", n);
} }
n--; n--;
Iterator<Value[]> iter = WindowFrame.iterator(over, session, ordered, getOverOrderBySort(), Iterator<Value[]> iter = WindowFrame.iterator(over, session, ordered, getOverOrderBySort(), i,
frameParametersOffset, i, fromLast); fromLast);
v = getNthValue(iter, n, ignoreNulls); v = getNthValue(iter, n, ignoreNulls);
break; break;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论