Unverified 提交 04415644 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1484 from katzyn/misc

New tests, reimplemented EXCLUDE clause, and assorted changes
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
package org.h2.expression; package org.h2.expression;
import static org.h2.util.DateTimeUtils.NANOS_PER_DAY; import static org.h2.util.DateTimeUtils.NANOS_PER_DAY;
import static org.h2.util.DateTimeUtils.NANOS_PER_HOUR;
import static org.h2.util.DateTimeUtils.NANOS_PER_MINUTE;
import static org.h2.util.DateTimeUtils.absoluteDayFromDateValue; import static org.h2.util.DateTimeUtils.absoluteDayFromDateValue;
import static org.h2.util.DateTimeUtils.dateAndTimeFromValue; import static org.h2.util.DateTimeUtils.dateAndTimeFromValue;
import static org.h2.util.DateTimeUtils.dateTimeToValue; import static org.h2.util.DateTimeUtils.dateTimeToValue;
...@@ -168,8 +170,8 @@ public class IntervalOperation extends Expression { ...@@ -168,8 +170,8 @@ public class IntervalOperation extends Expression {
if (negative) { if (negative) {
diff = -diff; diff = -diff;
} }
return ValueInterval.from(IntervalQualifier.HOUR_TO_SECOND, negative, diff / 3_600_000_000_000L, return ValueInterval.from(IntervalQualifier.HOUR_TO_SECOND, negative, diff / NANOS_PER_HOUR,
diff % 3_600_000_000_000L); diff % NANOS_PER_HOUR);
} else if (lType == Value.DATE && rType == Value.DATE) { } else if (lType == Value.DATE && rType == Value.DATE) {
long diff = absoluteDayFromDateValue(((ValueDate) l).getDateValue()) long diff = absoluteDayFromDateValue(((ValueDate) l).getDateValue())
- absoluteDayFromDateValue(((ValueDate) r).getDateValue()); - absoluteDayFromDateValue(((ValueDate) r).getDateValue());
...@@ -184,7 +186,7 @@ public class IntervalOperation extends Expression { ...@@ -184,7 +186,7 @@ public class IntervalOperation extends Expression {
l = l.convertTo(Value.TIMESTAMP_TZ); l = l.convertTo(Value.TIMESTAMP_TZ);
r = r.convertTo(Value.TIMESTAMP_TZ); r = r.convertTo(Value.TIMESTAMP_TZ);
diff = diff.add(BigInteger.valueOf((((ValueTimestampTimeZone) r).getTimeZoneOffsetMins() diff = diff.add(BigInteger.valueOf((((ValueTimestampTimeZone) r).getTimeZoneOffsetMins()
- ((ValueTimestampTimeZone) l).getTimeZoneOffsetMins()) * 60_000_000_000L)); - ((ValueTimestampTimeZone) l).getTimeZoneOffsetMins()) * NANOS_PER_MINUTE));
} }
return IntervalUtils.intervalFromAbsolute(IntervalQualifier.DAY_TO_SECOND, diff); return IntervalUtils.intervalFromAbsolute(IntervalQualifier.DAY_TO_SECOND, diff);
} }
......
...@@ -25,10 +25,10 @@ abstract class AggregateData { ...@@ -25,10 +25,10 @@ abstract class AggregateData {
static AggregateData create(AggregateType aggregateType, boolean distinct) { static AggregateData create(AggregateType aggregateType, boolean distinct) {
switch (aggregateType) { switch (aggregateType) {
case COUNT_ALL: case COUNT_ALL:
return new AggregateDataCountAll(); return new AggregateDataCount(true);
case COUNT: case COUNT:
if (!distinct) { if (!distinct) {
return new AggregateDataCount(); return new AggregateDataCount(false);
} }
break; break;
case GROUP_CONCAT: case GROUP_CONCAT:
......
...@@ -11,14 +11,21 @@ import org.h2.value.ValueLong; ...@@ -11,14 +11,21 @@ import org.h2.value.ValueLong;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
/** /**
* Data stored while calculating an aggregate. * Data stored while calculating a COUNT aggregate.
*/ */
class AggregateDataCount extends AggregateData { class AggregateDataCount extends AggregateData {
private final boolean all;
private long count; private long count;
AggregateDataCount(boolean all) {
this.all = all;
}
@Override @Override
void add(Database database, int dataType, Value v) { void add(Database database, int dataType, Value v) {
if (v != ValueNull.INSTANCE) { if (all || v != ValueNull.INSTANCE) {
count++; count++;
} }
} }
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression.aggregate;
import org.h2.engine.Database;
import org.h2.value.Value;
import org.h2.value.ValueLong;
/**
* Data stored while calculating a COUNT(*) aggregate.
*/
class AggregateDataCountAll extends AggregateData {
private long count;
@Override
void add(Database database, int dataType, Value v) {
count++;
}
@Override
Value getValue(Database database, int dataType) {
return ValueLong.get(count).convertTo(dataType);
}
}
...@@ -653,7 +653,9 @@ public class TestScript extends TestDb { ...@@ -653,7 +653,9 @@ public class TestScript extends TestDb {
} }
} else { } else {
addWriteResultError("<nothing>", s); addWriteResultError("<nothing>", s);
putBack(compare); if (compare != null) {
putBack(compare);
}
} }
write(s); write(s);
} }
......
...@@ -350,6 +350,23 @@ SELECT *, ARRAY_AGG(ID) OVER (ORDER BY ID RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOW ...@@ -350,6 +350,23 @@ SELECT *, ARRAY_AGG(ID) OVER (ORDER BY ID RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOW
> 8 9 null > 8 9 null
> rows: 4 > rows: 4
SELECT *,
ARRAY_AGG(ID) OVER (ORDER BY VALUE GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING) N,
ARRAY_AGG(ID) OVER (ORDER BY VALUE GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES) T,
ARRAY_AGG(ID) OVER (ORDER BY VALUE GROUPS BETWEEN 1 PRECEDING AND 0 FOLLOWING EXCLUDE TIES) T1
FROM TEST;
> ID VALUE N T T1
> -- ----- --------- --- ------------
> 1 1 (1, 2) (1) (1)
> 2 1 (1, 2) (2) (2)
> 3 5 (3) (3) (1, 2, 3)
> 4 8 (4, 5, 6) (4) (3, 4)
> 5 8 (4, 5, 6) (5) (3, 5)
> 6 8 (4, 5, 6) (6) (3, 6)
> 7 9 (7, 8) (7) (4, 5, 6, 7)
> 8 9 (7, 8) (8) (4, 5, 6, 8)
> rows: 8
SELECT *, SELECT *,
ARRAY_AGG(ID) OVER (ORDER BY VALUE GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) U_P, ARRAY_AGG(ID) OVER (ORDER BY VALUE GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) U_P,
ARRAY_AGG(ID) OVER (ORDER BY VALUE GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING) P, ARRAY_AGG(ID) OVER (ORDER BY VALUE GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING) P,
...@@ -384,6 +401,54 @@ SELECT *, ...@@ -384,6 +401,54 @@ SELECT *,
> 8 9 (4, 5, 6, 7, 8) (7, 8) > 8 9 (4, 5, 6, 7, 8) (7, 8)
> rows: 8 > rows: 8
SELECT ID, VALUE,
ARRAY_AGG(ID) OVER (ORDER BY VALUE ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING EXCLUDE GROUP) G,
ARRAY_AGG(ID) OVER (ORDER BY VALUE ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING EXCLUDE TIES) T
FROM TEST;
> ID VALUE G T
> -- ----- ------------ ---------------
> 1 1 (3) (1, 3)
> 2 1 (3, 4) (2, 3, 4)
> 3 5 (1, 2, 4, 5) (1, 2, 3, 4, 5)
> 4 8 (2, 3) (2, 3, 4)
> 5 8 (3, 7) (3, 5, 7)
> 6 8 (7, 8) (6, 7, 8)
> 7 9 (5, 6) (5, 6, 7)
> 8 9 (6) (6, 8)
> rows: 8
SELECT ID, VALUE, ARRAY_AGG(ID) OVER(ORDER BY VALUE ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING EXCLUDE GROUP) G
FROM TEST ORDER BY ID FETCH FIRST 3 ROWS ONLY;
> ID VALUE G
> -- ----- ------
> 1 1 (3)
> 2 1 (3, 4)
> 3 5 (4, 5)
> rows (ordered): 3
SELECT ID, VALUE, ARRAY_AGG(ID) OVER(ORDER BY VALUE ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING EXCLUDE GROUP) G
FROM TEST ORDER BY ID FETCH FIRST 3 ROWS ONLY;
> ID VALUE G
> -- ----- ------
> 1 1 null
> 2 1 null
> 3 5 (1, 2)
> rows (ordered): 3
SELECT ID, VALUE, ARRAY_AGG(ID) OVER (ORDER BY VALUE RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING) A
FROM TEST;
> ID VALUE A
> -- ----- ---------
> 1 1 null
> 2 1 null
> 3 5 null
> 4 8 null
> 5 8 null
> 6 8 null
> 7 9 (4, 5, 6)
> 8 9 (4, 5, 6)
> rows: 8
SELECT *, ARRAY_AGG(ID) OVER (ORDER BY ID RANGE BETWEEN CURRENT ROW AND 1 PRECEDING) FROM TEST; SELECT *, ARRAY_AGG(ID) OVER (ORDER BY ID RANGE BETWEEN CURRENT ROW AND 1 PRECEDING) FROM TEST;
> exception SYNTAX_ERROR_1 > exception SYNTAX_ERROR_1
...@@ -430,5 +495,33 @@ SELECT *, ARRAY_AGG(ID) OVER (ORDER BY VALUE RANGE BETWEEN 1 FOLLOWING AND 2 FOL ...@@ -430,5 +495,33 @@ SELECT *, ARRAY_AGG(ID) OVER (ORDER BY VALUE RANGE BETWEEN 1 FOLLOWING AND 2 FOL
> 8 4 null > 8 4 null
> rows: 8 > 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; DROP TABLE TEST;
> ok > ok
...@@ -146,5 +146,76 @@ SELECT ID, CATEGORY, ...@@ -146,5 +146,76 @@ SELECT ID, CATEGORY,
> 3 1 1 1 > 3 1 1 1
> rows: 3 > 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
SELECT ID, CATEGORY,
NTH_VALUE(CATEGORY, 1) OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP) F1,
NTH_VALUE(CATEGORY, 2) OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP) F2,
NTH_VALUE(CATEGORY, 5) OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP) F5,
NTH_VALUE(CATEGORY, 5) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP) L5,
NTH_VALUE(CATEGORY, 2) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP) L2,
NTH_VALUE(CATEGORY, 1) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP) L1
FROM TEST ORDER BY ID;
> ID CATEGORY F1 F2 F5 L5 L2 L1
> -- -------- -- -- -- -- -- --
> 1 1 2 2 3 3 4 4
> 2 1 2 2 3 3 4 4
> 3 1 2 2 3 3 4 4
> 4 1 2 2 3 3 4 4
> 5 1 2 2 3 3 4 4
> 6 1 2 2 3 3 4 4
> 7 2 1 1 1 3 4 4
> 8 2 1 1 1 3 4 4
> 9 3 1 1 1 1 4 4
> 10 3 1 1 1 1 4 4
> 11 3 1 1 1 1 4 4
> 12 4 1 1 1 2 3 3
> 13 4 1 1 1 2 3 3
> rows (ordered): 13
SELECT ID, CATEGORY,
NTH_VALUE(CATEGORY, 1) OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES) F1,
NTH_VALUE(CATEGORY, 2) OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES) F2,
NTH_VALUE(CATEGORY, 5) OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES) F5,
NTH_VALUE(CATEGORY, 5) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES) L5,
NTH_VALUE(CATEGORY, 2) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES) L2,
NTH_VALUE(CATEGORY, 1) FROM LAST OVER (ORDER BY CATEGORY RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES) L1
FROM TEST ORDER BY ID;
> ID CATEGORY F1 F2 F5 L5 L2 L1
> -- -------- -- -- -- -- -- --
> 1 1 1 2 3 3 4 4
> 2 1 1 2 3 3 4 4
> 3 1 1 2 3 3 4 4
> 4 1 1 2 3 3 4 4
> 5 1 1 2 3 3 4 4
> 6 1 1 2 3 3 4 4
> 7 2 1 1 1 3 4 4
> 8 2 1 1 1 3 4 4
> 9 3 1 1 1 2 4 4
> 10 3 1 1 1 2 4 4
> 11 3 1 1 1 2 4 4
> 12 4 1 1 1 2 3 4
> 13 4 1 1 1 2 3 4
> rows (ordered): 13
DROP TABLE TEST; DROP TABLE TEST;
> ok > ok
...@@ -797,6 +797,6 @@ xym normalizes coord setz xyzm geometrycollection multipolygon mixup rings polyg ...@@ -797,6 +797,6 @@ xym normalizes coord setz xyzm geometrycollection multipolygon mixup rings polyg
pointzm pointz pointm dimensionality redefine forum measures pointzm pointz pointm dimensionality redefine forum measures
mpg casted pzm mls constrained subtypes complains mpg casted pzm mls constrained subtypes complains
ranks rno dro rko precede cume reopens preceding unbounded rightly itr lag maximal tiles tile ntile signify ranks rno dro rko precede cume reopens preceding unbounded rightly itr lag maximal tiles tile ntile signify
partitioned partitioned tri
discard enhancements nolock discard enhancements nolock
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论