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