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

Fix commit 122fa953

上级 7c87be33
...@@ -23,6 +23,8 @@ Change Log ...@@ -23,6 +23,8 @@ Change Log
<ul> <ul>
<li>Issue #1604: TestCrashAPI: PreparedStatement.getGeneratedKeys() is already closed <li>Issue #1604: TestCrashAPI: PreparedStatement.getGeneratedKeys() is already closed
</li> </li>
<li>PR #1667: Detect NULL values and overflow in window frame bounds
</li>
<li>PR #1664: Allow any expressions in window frames <li>PR #1664: Allow any expressions in window frames
</li> </li>
<li>Issue #1576: H2 Console should not display precision and scale for data types that don't have them <li>Issue #1576: H2 Console should not display precision and scale for data types that don't have them
......
...@@ -323,7 +323,12 @@ public final class WindowFrame { ...@@ -323,7 +323,12 @@ public final class WindowFrame {
Value[] row = orderedRows.get(currentRow); Value[] row = orderedRows.get(currentRow);
Value currentValue = row[sortIndex]; Value currentValue = row[sortIndex];
int type = currentValue.getType(); int type = currentValue.getType();
Value newValue;
Value range = getValueOffset(bound, orderedRows.get(currentRow), session);
switch (type) { switch (type) {
case Value.NULL:
newValue = ValueNull.INSTANCE;
break;
case Value.BYTE: case Value.BYTE:
case Value.SHORT: case Value.SHORT:
case Value.INT: case Value.INT:
...@@ -348,24 +353,23 @@ public final class WindowFrame { ...@@ -348,24 +353,23 @@ public final class WindowFrame {
case Value.INTERVAL_HOUR_TO_MINUTE: case Value.INTERVAL_HOUR_TO_MINUTE:
case Value.INTERVAL_HOUR_TO_SECOND: case Value.INTERVAL_HOUR_TO_SECOND:
case Value.INTERVAL_MINUTE_TO_SECOND: case Value.INTERVAL_MINUTE_TO_SECOND:
OpType opType = add ^ (sortOrder.getSortTypes()[0] & SortOrder.DESCENDING) != 0 ? OpType.PLUS
: OpType.MINUS;
try {
newValue = new BinaryOperation(opType, ValueExpression.get(currentValue), ValueExpression.get(range))
.optimize(session).getValue(session).convertTo(type);
} catch (DbException ex) {
switch (ex.getErrorCode()) {
case ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1:
case ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_2:
return null;
}
throw ex;
}
break; break;
default: default:
throw DbException.getInvalidValueException("ORDER BY value for RANGE frame", currentValue.getTraceSQL()); throw DbException.getInvalidValueException("ORDER BY value for RANGE frame", currentValue.getTraceSQL());
} }
Value range = getValueOffset(bound, orderedRows.get(currentRow), session);
OpType opType = add ^ (sortOrder.getSortTypes()[0] & SortOrder.DESCENDING) != 0 ? OpType.PLUS : OpType.MINUS;
Value newValue;
try {
newValue = new BinaryOperation(opType, ValueExpression.get(currentValue), ValueExpression.get(range))
.optimize(session).getValue(session).convertTo(type);
} catch (DbException ex) {
switch (ex.getErrorCode()) {
case ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1:
case ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_2:
return null;
}
throw ex;
}
Value[] newRow = row.clone(); Value[] newRow = row.clone();
newRow[sortIndex] = newValue; newRow[sortIndex] = newValue;
return newRow; return newRow;
......
...@@ -115,8 +115,77 @@ SELECT SUM(ID) OVER (ORDER BY ID ROWS NULL PRECEDING) P FROM TEST; ...@@ -115,8 +115,77 @@ SELECT SUM(ID) OVER (ORDER BY ID ROWS NULL PRECEDING) P FROM TEST;
SELECT SUM(ID) OVER (ORDER BY ID RANGE NULL PRECEDING) P FROM TEST; SELECT SUM(ID) OVER (ORDER BY ID RANGE NULL PRECEDING) P FROM TEST;
> exception INVALID_VALUE_2 > exception INVALID_VALUE_2
SELECT SUM(V) OVER (ORDER BY V RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM VALUES (1), (NULL), (2) T(V); SELECT ARRAY_AGG(ID) OVER (ORDER BY V NULLS FIRST RANGE BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) A,
> exception INVALID_VALUE_2 ID, V FROM VALUES (1, 1), (2, NULL), (3, 2) T(ID, V) ORDER BY V NULLS FIRST;
> A ID V
> --------- -- ----
> [3, 1, 2] 2 null
> [3, 1] 1 1
> [3, 1] 3 2
> rows (ordered): 3
SELECT ARRAY_AGG(ID) OVER (ORDER BY V NULLS LAST RANGE BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) A,
ID, V FROM VALUES (1, 1), (2, NULL), (3, 2) T(ID, V) ORDER BY V NULLS LAST;
> A ID V
> --------- -- ----
> [2, 3, 1] 1 1
> [2, 3, 1] 3 2
> [2] 2 null
> rows (ordered): 3
SELECT ARRAY_AGG(ID) OVER (ORDER BY V NULLS FIRST RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) A,
ID, V FROM VALUES (1, 1), (2, NULL), (3, 2) T(ID, V) ORDER BY V NULLS FIRST;
> A ID V
> --------- -- ----
> [3, 1, 2] 2 null
> [3] 1 1
> null 3 2
> rows (ordered): 3
SELECT ARRAY_AGG(ID) OVER (ORDER BY V NULLS LAST RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) A,
ID, V FROM VALUES (1, 1), (2, NULL), (3, 2) T(ID, V) ORDER BY V NULLS LAST;
> A ID V
> ------ -- ----
> [2, 3] 1 1
> [2] 3 2
> [2] 2 null
> rows (ordered): 3
SELECT ARRAY_AGG(ID) OVER (ORDER BY V NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) A,
ID, V FROM VALUES (1, 1), (2, NULL), (3, 2) T(ID, V) ORDER BY V NULLS FIRST;
> A ID V
> --------- -- ----
> [2] 2 null
> [2, 1, 3] 1 1
> [2, 1, 3] 3 2
> rows (ordered): 3
SELECT ARRAY_AGG(ID) OVER (ORDER BY V NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) A,
ID, V FROM VALUES (1, 1), (2, NULL), (3, 2) T(ID, V) ORDER BY V NULLS LAST;
> A ID V
> --------- -- ----
> [1, 3] 1 1
> [1, 3] 3 2
> [1, 3, 2] 2 null
> rows (ordered): 3
SELECT ARRAY_AGG(ID) OVER (ORDER BY V NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) A,
ID, V FROM VALUES (1, 1), (2, NULL), (3, 2) T(ID, V) ORDER BY V NULLS FIRST;
> A ID V
> ------ -- ----
> [2] 2 null
> [2] 1 1
> [2, 1] 3 2
> rows (ordered): 3
SELECT ARRAY_AGG(ID) OVER (ORDER BY V NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) A,
ID, V FROM VALUES (1, 1), (2, NULL), (3, 2) T(ID, V) ORDER BY V NULLS LAST;
> A ID V
> --------- -- ----
> null 1 1
> [1] 3 2
> [1, 3, 2] 2 null
> rows (ordered): 3
SELECT SUM(V) OVER (ORDER BY V RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM VALUES (TRUE) T(V); SELECT SUM(V) OVER (ORDER BY V RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM VALUES (TRUE) T(V);
> exception INVALID_VALUE_2 > exception INVALID_VALUE_2
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论