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 [,...]
[ FROM tableExpression [,...] ]
[ WHERE expression ]
[ GROUP BY expression [,...] ] [ HAVING expression ]
[ QUALIFY expression ]
[ WINDOW { { windowName AS windowSpecification } [,...] } ]
[ QUALIFY expression ]
[ { UNION [ ALL ] | EXCEPT | MINUS | INTERSECT } select ]
[ ORDER BY order [,...] ]
[ LIMIT expression [ OFFSET expression ] [ SAMPLE_SIZE rowCountInt ] ]
......
......@@ -21,6 +21,12 @@ Change Log
<h2>Next Version (unreleased)</h2>
<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>
<li>PR #1714: Assorted changes
......
......@@ -2750,11 +2750,6 @@ public class Parser {
Expression condition = readExpression();
command.setHaving(condition);
}
if (readIf(QUALIFY)) {
command.setWindowQuery();
Expression condition = readExpression();
command.setQualify(condition);
}
if (readIf(WINDOW)) {
do {
int index = parseIndex;
......@@ -2766,6 +2761,11 @@ public class Parser {
}
} while (readIf(COMMA));
}
if (readIf(QUALIFY)) {
command.setWindowQuery();
Expression condition = readExpression();
command.setQualify(condition);
}
command.setParameterList(parameters);
currentSelect = oldSelect;
currentPrepared = oldPrepared;
......
......@@ -44,6 +44,7 @@ import org.h2.table.IndexColumn;
import org.h2.table.JoinBatch;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.table.TableFilter.TableFilterVisitor;
import org.h2.table.TableType;
import org.h2.table.TableView;
import org.h2.util.ColumnNamer;
......@@ -117,6 +118,11 @@ public class Select extends Query {
*/
boolean[] groupByExpression;
/**
* Select with grouped data for aggregates.
*/
private Select groupSelect;
/**
* Grouped data for aggregates.
*/
......@@ -213,6 +219,10 @@ public class Select extends Query {
return group;
}
void setGroupSelect(Select groupSelect) {
this.groupSelect = groupSelect;
}
/**
* Get the group data if there is currently a group-by active.
*
......@@ -220,6 +230,9 @@ public class Select extends Query {
* @return the grouped data
*/
public SelectGroups getGroupDataIfCurrent(boolean window) {
if (groupSelect != null) {
return groupSelect.getGroupDataIfCurrent(window);
}
return groupData != null && (window || groupData.isCurrentGroup()) ? groupData : null;
}
......@@ -1333,6 +1346,15 @@ public class Select extends Query {
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]);
isPrepared = true;
}
......
......@@ -1306,7 +1306,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
int unsavedMemory = replacement.getMemory();
while (path != null) {
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
if (parent.getKeyCount() > 0) {
Page child = replacement;
......@@ -1717,8 +1717,10 @@ public class MVMap<K, V> extends AbstractMap<K, V>
index = pos.index;
pos = pos.parent;
keyCount = p.getKeyCount();
// condition below sould always be false, but older versions (up to 1.4.197)
// may create single-childed (with no keys) internal nodes, which we skip here
// condition below should always be false, but older
// versions (up to 1.4.197) may create
// single-childed (with no keys) internal nodes,
// which we skip here
} while (keyCount == 0 && pos != null);
if (keyCount <= 1) {
......@@ -1726,8 +1728,9 @@ public class MVMap<K, V> extends AbstractMap<K, V>
assert index <= 1;
p = p.getChildPage(1 - index);
} else {
// if root happens to be such single-childed (with no keys) internal node,
// then just replace it with empty leaf
// if root happens to be such single-childed
// (with no keys) internal node, then just
// replace it with empty leaf
p = Page.createEmptyLeaf(this);
}
break;
......
......@@ -584,3 +584,21 @@ SELECT COUNT(*) C FROM TEST QUALIFY C < 1;
DROP TABLE TEST;
> 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 *,
> rows: 9
SELECT *,
ROW_NUMBER() OVER (PARTITION BY CATEGORY ORDER BY ID) RN,
RANK() OVER (PARTITION BY CATEGORY ORDER BY ID) RK,
DENSE_RANK() OVER (PARTITION BY CATEGORY ORDER BY ID) DR,
ROUND(PERCENT_RANK() OVER (PARTITION BY CATEGORY ORDER BY ID), 2) PR,
ROUND(CUME_DIST() OVER (PARTITION BY CATEGORY ORDER BY ID), 2) CD
FROM TEST QUALIFY ROW_NUMBER() OVER (PARTITION BY CATEGORY ORDER BY ID) = 2;
ROW_NUMBER() OVER W RN,
RANK() OVER W RK,
DENSE_RANK() OVER W DR,
ROUND(PERCENT_RANK() OVER W, 2) PR,
ROUND(CUME_DIST() OVER W, 2) CD
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
> -- -------- ----- -- -- -- --- ----
> 2 1 12 2 2 2 0.5 0.67
......
......@@ -806,4 +806,4 @@ econd irst bcef ordinality nord unnest
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
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论