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

Optimize EXCLUDE CURRENT ROW

上级 c970bb05
......@@ -39,11 +39,11 @@ public final class WindowFrame {
}
private static final class PlainItr extends Itr {
private static class PlainItr extends Itr {
private final int endIndex;
final int endIndex;
private int cursor;
int cursor;
PlainItr(ArrayList<Value[]> orderedRows, int startIndex, int endIndex) {
super(orderedRows);
......@@ -66,11 +66,11 @@ public final class WindowFrame {
}
private static final class PlainReverseItr extends Itr {
private static class PlainReverseItr extends Itr {
private final int startIndex;
final int startIndex;
private int cursor;
int cursor;
PlainReverseItr(ArrayList<Value[]> orderedRows, int startIndex, int endIndex) {
super(orderedRows);
......@@ -93,6 +93,50 @@ public final class WindowFrame {
}
private static final class BiItr extends PlainItr {
private final int endIndex1, startIndex2;
BiItr(ArrayList<Value[]> orderedRows, int startIndex1, int endIndex1, int startIndex2, int endIndex2) {
super(orderedRows, startIndex1, endIndex2);
this.endIndex1 = endIndex1;
this.startIndex2 = startIndex2;
}
@Override
public Value[] next() {
if (cursor > endIndex) {
throw new NoSuchElementException();
}
Value[] r = orderedRows.get(cursor);
cursor = cursor != endIndex1 ? cursor + 1 : startIndex2;
return r;
}
}
private static final class BiReverseItr extends PlainReverseItr {
private final int endIndex1, startIndex2;
BiReverseItr(ArrayList<Value[]> orderedRows, int startIndex1, int endIndex1, int startIndex2, int endIndex2) {
super(orderedRows, startIndex1, endIndex2);
this.endIndex1 = endIndex1;
this.startIndex2 = startIndex2;
}
@Override
public Value[] next() {
if (cursor < startIndex) {
throw new NoSuchElementException();
}
Value[] r = orderedRows.get(cursor);
cursor = cursor != startIndex2 ? cursor - 1 : endIndex1;
return r;
}
}
private static abstract class AbstractBitSetItr extends Itr {
final BitSet set;
......@@ -182,11 +226,21 @@ public final class WindowFrame {
: plainIterator(orderedRows, 0, currentRow, reverse);
}
private static Itr plainIterator(ArrayList<Value[]> orderedRows, int startIndex, int endIndex, boolean reverse) {
private static Iterator<Value[]> plainIterator(ArrayList<Value[]> orderedRows, int startIndex, int endIndex,
boolean reverse) {
if (endIndex < startIndex) {
return Collections.emptyIterator();
}
return reverse ? new PlainReverseItr(orderedRows, startIndex, endIndex)
: new PlainItr(orderedRows, startIndex, endIndex);
}
private static Iterator<Value[]> biIterator(ArrayList<Value[]> orderedRows, int startIndex1, int endIndex1,
int startIndex2, int endIndex2, boolean reverse) {
return reverse ? new BiReverseItr(orderedRows, startIndex1, endIndex1, startIndex2, endIndex2)
: new BiItr(orderedRows, startIndex1, endIndex1, startIndex2, endIndex2);
}
private static int toGroupStart(ArrayList<Value[]> orderedRows, SortOrder sortOrder, int offset, int minOffset) {
Value[] row = orderedRows.get(offset);
while (offset > minOffset && sortOrder.compare(row, orderedRows.get(offset - 1)) == 0) {
......@@ -471,22 +525,31 @@ public final class WindowFrame {
private Iterator<Value[]> complexIterator(ArrayList<Value[]> orderedRows, SortOrder sortOrder, int currentRow,
int startIndex, int endIndex, boolean reverse) {
BitSet set = new BitSet(endIndex + 1);
set.set(startIndex, endIndex + 1);
if (exclusion == WindowFrameExclusion.EXCLUDE_CURRENT_ROW) {
set.clear(currentRow);
if (currentRow < startIndex || currentRow > endIndex) {
// Nothing to do
} else if (currentRow == startIndex) {
startIndex++;
} else if (currentRow == endIndex) {
endIndex--;
} else {
return biIterator(orderedRows, startIndex, currentRow - 1, currentRow + 1, endIndex, reverse);
}
return plainIterator(orderedRows, startIndex, endIndex, reverse);
} else {
BitSet set = new BitSet(endIndex + 1);
set.set(startIndex, endIndex + 1);
int exStart = toGroupStart(orderedRows, sortOrder, currentRow, startIndex);
int exEnd = toGroupEnd(orderedRows, sortOrder, currentRow, endIndex);
set.clear(exStart, exEnd + 1);
if (exclusion == WindowFrameExclusion.EXCLUDE_TIES) {
set.set(currentRow);
}
if (set.isEmpty()) {
return Collections.emptyIterator();
}
return reverse ? new BitSetReverseItr(orderedRows, set) : new BitSetItr(orderedRows, set);
}
if (set.isEmpty()) {
return Collections.emptyIterator();
}
return reverse ? new BitSetReverseItr(orderedRows, set) : new BitSetItr(orderedRows, set);
}
/**
......
......@@ -653,7 +653,9 @@ public class TestScript extends TestDb {
}
} else {
addWriteResultError("<nothing>", s);
putBack(compare);
if (compare != null) {
putBack(compare);
}
}
write(s);
}
......
......@@ -430,5 +430,33 @@ SELECT *, ARRAY_AGG(ID) OVER (ORDER BY VALUE RANGE BETWEEN 1 FOLLOWING AND 2 FOL
> 8 4 null
> rows: 8
SELECT ID, VALUE, ARRAY_AGG(ID) OVER (ORDER BY VALUE RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING EXCLUDE CURRENT ROW) A
FROM TEST;
> ID VALUE A
> -- ----- ------------
> 1 1 null
> 2 1 null
> 3 2 (1, 2)
> 4 2 (1, 2)
> 5 3 (1, 2, 3, 4)
> 6 3 (1, 2, 3, 4)
> 7 4 (3, 4, 5, 6)
> 8 4 (3, 4, 5, 6)
> rows: 8
SELECT ID, VALUE, ARRAY_AGG(ID) OVER (ORDER BY VALUE RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING EXCLUDE CURRENT ROW) A
FROM TEST;
> ID VALUE A
> -- ----- ------
> 1 1 (3, 4)
> 2 1 (3, 4)
> 3 2 (5, 6)
> 4 2 (5, 6)
> 5 3 (7, 8)
> 6 3 (7, 8)
> 7 4 null
> 8 4 null
> rows: 8
DROP TABLE TEST;
> ok
......@@ -146,5 +146,26 @@ SELECT ID, CATEGORY,
> 3 1 1 1
> rows: 3
SELECT ID, CATEGORY,
NTH_VALUE(CATEGORY, 2) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) C,
NTH_VALUE(CATEGORY, 2) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW)
FROM TEST OFFSET 10 ROWS;
> ID CATEGORY C NTH_VALUE(CATEGORY, 2) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN CURRENT_ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW)
> -- -------- ---- -------------------------------------------------------------------------------------------------------------------------------
> 11 3 4 4
> 12 4 4 null
> 13 4 null null
> rows: 3
SELECT ID, CATEGORY,
NTH_VALUE(CATEGORY, 2) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW) C
FROM TEST OFFSET 10 ROWS;
> ID CATEGORY C
> -- -------- -
> 11 3 4
> 12 4 3
> 13 4 3
> rows: 3
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论