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

Merge pull request #1720 from katzyn/window

Fix issue with window query with VALUES and move QUALIFY after WINDOW
...@@ -11,8 +11,8 @@ selectExpression [,...] ...@@ -11,8 +11,8 @@ selectExpression [,...]
[ FROM tableExpression [,...] ] [ FROM tableExpression [,...] ]
[ WHERE expression ] [ WHERE expression ]
[ GROUP BY expression [,...] ] [ HAVING expression ] [ GROUP BY expression [,...] ] [ HAVING expression ]
[ QUALIFY expression ]
[ WINDOW { { windowName AS windowSpecification } [,...] } ] [ WINDOW { { windowName AS windowSpecification } [,...] } ]
[ QUALIFY expression ]
[ { UNION [ ALL ] | EXCEPT | MINUS | INTERSECT } select ] [ { UNION [ ALL ] | EXCEPT | MINUS | INTERSECT } select ]
[ ORDER BY order [,...] ] [ ORDER BY order [,...] ]
[ LIMIT expression [ OFFSET expression ] [ SAMPLE_SIZE rowCountInt ] ] [ LIMIT expression [ OFFSET expression ] [ SAMPLE_SIZE rowCountInt ] ]
......
...@@ -21,6 +21,12 @@ Change Log ...@@ -21,6 +21,12 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #1718: Window function and values clause don't work well together
</li>
<li>PR #1717: Backward compatibility patch for #1592
</li>
<li>PR #1716: Improve documentation of some DML commands
</li>
<li>Issue #1715: Postgres mode: Domain "regproc" already exists <li>Issue #1715: Postgres mode: Domain "regproc" already exists
</li> </li>
<li>PR #1714: Assorted changes <li>PR #1714: Assorted changes
......
...@@ -2750,11 +2750,6 @@ public class Parser { ...@@ -2750,11 +2750,6 @@ public class Parser {
Expression condition = readExpression(); Expression condition = readExpression();
command.setHaving(condition); command.setHaving(condition);
} }
if (readIf(QUALIFY)) {
command.setWindowQuery();
Expression condition = readExpression();
command.setQualify(condition);
}
if (readIf(WINDOW)) { if (readIf(WINDOW)) {
do { do {
int index = parseIndex; int index = parseIndex;
...@@ -2766,6 +2761,11 @@ public class Parser { ...@@ -2766,6 +2761,11 @@ public class Parser {
} }
} while (readIf(COMMA)); } while (readIf(COMMA));
} }
if (readIf(QUALIFY)) {
command.setWindowQuery();
Expression condition = readExpression();
command.setQualify(condition);
}
command.setParameterList(parameters); command.setParameterList(parameters);
currentSelect = oldSelect; currentSelect = oldSelect;
currentPrepared = oldPrepared; currentPrepared = oldPrepared;
......
...@@ -44,6 +44,7 @@ import org.h2.table.IndexColumn; ...@@ -44,6 +44,7 @@ import org.h2.table.IndexColumn;
import org.h2.table.JoinBatch; import org.h2.table.JoinBatch;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.table.TableFilter.TableFilterVisitor;
import org.h2.table.TableType; import org.h2.table.TableType;
import org.h2.table.TableView; import org.h2.table.TableView;
import org.h2.util.ColumnNamer; import org.h2.util.ColumnNamer;
...@@ -117,6 +118,11 @@ public class Select extends Query { ...@@ -117,6 +118,11 @@ public class Select extends Query {
*/ */
boolean[] groupByExpression; boolean[] groupByExpression;
/**
* Select with grouped data for aggregates.
*/
private Select groupSelect;
/** /**
* Grouped data for aggregates. * Grouped data for aggregates.
*/ */
...@@ -213,6 +219,10 @@ public class Select extends Query { ...@@ -213,6 +219,10 @@ public class Select extends Query {
return group; return group;
} }
void setGroupSelect(Select groupSelect) {
this.groupSelect = groupSelect;
}
/** /**
* Get the group data if there is currently a group-by active. * Get the group data if there is currently a group-by active.
* *
...@@ -220,6 +230,9 @@ public class Select extends Query { ...@@ -220,6 +230,9 @@ public class Select extends Query {
* @return the grouped data * @return the grouped data
*/ */
public SelectGroups getGroupDataIfCurrent(boolean window) { public SelectGroups getGroupDataIfCurrent(boolean window) {
if (groupSelect != null) {
return groupSelect.getGroupDataIfCurrent(window);
}
return groupData != null && (window || groupData.isCurrentGroup()) ? groupData : null; return groupData != null && (window || groupData.isCurrentGroup()) ? groupData : null;
} }
...@@ -1333,6 +1346,15 @@ public class Select extends Query { ...@@ -1333,6 +1346,15 @@ public class Select extends Query {
isGroupSortedQuery = true; isGroupSortedQuery = true;
} }
} }
topTableFilter.visit(new TableFilterVisitor() {
@Override
public void accept(TableFilter f) {
Select s = f.getSelect();
if (s != null && s != Select.this) {
s.setGroupSelect(Select.this);
}
}
});
expressionArray = expressions.toArray(new Expression[0]); expressionArray = expressions.toArray(new Expression[0]);
isPrepared = true; isPrepared = true;
} }
......
...@@ -1306,7 +1306,7 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1306,7 +1306,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
int unsavedMemory = replacement.getMemory(); int unsavedMemory = replacement.getMemory();
while (path != null) { while (path != null) {
Page parent = path.page; Page parent = path.page;
// condition below sould always be true, but older versions (up to 1.4.197) // condition below should always be true, but older versions (up to 1.4.197)
// may create single-childed (with no keys) internal nodes, which we skip here // may create single-childed (with no keys) internal nodes, which we skip here
if (parent.getKeyCount() > 0) { if (parent.getKeyCount() > 0) {
Page child = replacement; Page child = replacement;
...@@ -1717,8 +1717,10 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1717,8 +1717,10 @@ public class MVMap<K, V> extends AbstractMap<K, V>
index = pos.index; index = pos.index;
pos = pos.parent; pos = pos.parent;
keyCount = p.getKeyCount(); keyCount = p.getKeyCount();
// condition below sould always be false, but older versions (up to 1.4.197) // condition below should always be false, but older
// may create single-childed (with no keys) internal nodes, which we skip here // versions (up to 1.4.197) may create
// single-childed (with no keys) internal nodes,
// which we skip here
} while (keyCount == 0 && pos != null); } while (keyCount == 0 && pos != null);
if (keyCount <= 1) { if (keyCount <= 1) {
...@@ -1726,8 +1728,9 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1726,8 +1728,9 @@ public class MVMap<K, V> extends AbstractMap<K, V>
assert index <= 1; assert index <= 1;
p = p.getChildPage(1 - index); p = p.getChildPage(1 - index);
} else { } else {
// if root happens to be such single-childed (with no keys) internal node, // if root happens to be such single-childed
// then just replace it with empty leaf // (with no keys) internal node, then just
// replace it with empty leaf
p = Page.createEmptyLeaf(this); p = Page.createEmptyLeaf(this);
} }
break; break;
......
...@@ -584,3 +584,21 @@ SELECT COUNT(*) C FROM TEST QUALIFY C < 1; ...@@ -584,3 +584,21 @@ SELECT COUNT(*) C FROM TEST QUALIFY C < 1;
DROP TABLE TEST; DROP TABLE TEST;
> ok > ok
SELECT A, ROW_NUMBER() OVER (ORDER BY B) R
FROM (VALUES (1, 2), (2, 1), (3, 3)) T(A, B);
> A R
> - -
> 1 2
> 2 1
> 3 3
> rows: 3
SELECT X, A, ROW_NUMBER() OVER (ORDER BY B) R
FROM (SELECT 1 X), (VALUES (1, 2), (2, 1), (3, 3)) T(A, B);
> X A R
> - - -
> 1 1 2
> 1 2 1
> 1 3 3
> rows: 3
...@@ -84,12 +84,12 @@ SELECT *, ...@@ -84,12 +84,12 @@ SELECT *,
> rows: 9 > rows: 9
SELECT *, SELECT *,
ROW_NUMBER() OVER (PARTITION BY CATEGORY ORDER BY ID) RN, ROW_NUMBER() OVER W RN,
RANK() OVER (PARTITION BY CATEGORY ORDER BY ID) RK, RANK() OVER W RK,
DENSE_RANK() OVER (PARTITION BY CATEGORY ORDER BY ID) DR, DENSE_RANK() OVER W DR,
ROUND(PERCENT_RANK() OVER (PARTITION BY CATEGORY ORDER BY ID), 2) PR, ROUND(PERCENT_RANK() OVER W, 2) PR,
ROUND(CUME_DIST() OVER (PARTITION BY CATEGORY ORDER BY ID), 2) CD ROUND(CUME_DIST() OVER W, 2) CD
FROM TEST QUALIFY ROW_NUMBER() OVER (PARTITION BY CATEGORY ORDER BY ID) = 2; FROM TEST WINDOW W AS (PARTITION BY CATEGORY ORDER BY ID) QUALIFY ROW_NUMBER() OVER W = 2;
> ID CATEGORY VALUE RN RK DR PR CD > ID CATEGORY VALUE RN RK DR PR CD
> -- -------- ----- -- -- -- --- ---- > -- -------- ----- -- -- -- --- ----
> 2 1 12 2 2 2 0.5 0.67 > 2 1 12 2 2 2 0.5 0.67
......
...@@ -806,4 +806,4 @@ econd irst bcef ordinality nord unnest ...@@ -806,4 +806,4 @@ econd irst bcef ordinality nord unnest
analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan
corrupts splitted disruption unintentional octets preconditions predicates subq objectweb insn opcodes corrupts splitted disruption unintentional octets preconditions predicates subq objectweb insn opcodes
preserves masking holder unboxing avert iae transformed subtle reevaluate exclusions subclause ftbl rgr preserves masking holder unboxing avert iae transformed subtle reevaluate exclusions subclause ftbl rgr
presorted inclusion contexts aax mwd percentile cont interpolate mwa hypothetical regproc presorted inclusion contexts aax mwd percentile cont interpolate mwa hypothetical regproc childed
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论