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

Merge pull request #1721 from katzyn/dml

Fix derived column list in complex queries
...@@ -118,11 +118,6 @@ public class Select extends Query { ...@@ -118,11 +118,6 @@ 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.
*/ */
...@@ -219,10 +214,6 @@ public class Select extends Query { ...@@ -219,10 +214,6 @@ 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.
* *
...@@ -230,9 +221,6 @@ public class Select extends Query { ...@@ -230,9 +221,6 @@ 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;
} }
...@@ -481,13 +469,26 @@ public class Select extends Query { ...@@ -481,13 +469,26 @@ public class Select extends Query {
private void initGroupData(int columnCount) { private void initGroupData(int columnCount) {
if (groupData == null) { if (groupData == null) {
groupData = SelectGroups.getInstance(session, expressions, isGroupQuery, groupIndex); setGroupData(SelectGroups.getInstance(session, expressions, isGroupQuery, groupIndex));
} else { } else {
updateAgg(columnCount, DataAnalysisOperation.STAGE_RESET); updateAgg(columnCount, DataAnalysisOperation.STAGE_RESET);
} }
groupData.reset(); groupData.reset();
} }
void setGroupData(final SelectGroups groupData) {
this.groupData = groupData;
topTableFilter.visit(new TableFilterVisitor() {
@Override
public void accept(TableFilter f) {
Select s = f.getSelect();
if (s != null) {
s.groupData = groupData;
}
}
});
}
private void gatherGroup(int columnCount, int stage) { private void gatherGroup(int columnCount, int stage) {
long rowNumber = 0; long rowNumber = 0;
setCurrentRowNumber(0); setCurrentRowNumber(0);
...@@ -1346,15 +1347,6 @@ public class Select extends Query { ...@@ -1346,15 +1347,6 @@ 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;
} }
...@@ -1910,7 +1902,8 @@ public class Select extends Query { ...@@ -1910,7 +1902,8 @@ public class Select extends Query {
LazyResultGroupSorted(Expression[] expressions, int columnCount) { LazyResultGroupSorted(Expression[] expressions, int columnCount) {
super(expressions, columnCount); super(expressions, columnCount);
if (groupData == null) { if (groupData == null) {
groupData = SelectGroups.getInstance(getSession(), Select.this.expressions, isGroupQuery, groupIndex); setGroupData(SelectGroups.getInstance(getSession(), Select.this.expressions, isGroupQuery,
groupIndex));
} else { } else {
// TODO is this branch possible? // TODO is this branch possible?
updateAgg(columnCount, DataAnalysisOperation.STAGE_RESET); updateAgg(columnCount, DataAnalysisOperation.STAGE_RESET);
......
...@@ -39,6 +39,7 @@ public class ExpressionColumn extends Expression { ...@@ -39,6 +39,7 @@ public class ExpressionColumn extends Expression {
private ColumnResolver columnResolver; private ColumnResolver columnResolver;
private int queryLevel; private int queryLevel;
private Column column; private Column column;
private String derivedName;
public ExpressionColumn(Database database, Column column) { public ExpressionColumn(Database database, Column column) {
this.database = database; this.database = database;
...@@ -76,7 +77,11 @@ public class ExpressionColumn extends Expression { ...@@ -76,7 +77,11 @@ public class ExpressionColumn extends Expression {
builder.append('.'); builder.append('.');
} }
if (column != null) { if (column != null) {
builder.append(column.getSQL()); if (derivedName != null) {
Parser.quoteIdentifier(builder, derivedName);
} else {
builder.append(column.getSQL());
}
} else if (quote) { } else if (quote) {
Parser.quoteIdentifier(builder, columnName); Parser.quoteIdentifier(builder, columnName);
} else { } else {
...@@ -101,11 +106,18 @@ public class ExpressionColumn extends Expression { ...@@ -101,11 +106,18 @@ public class ExpressionColumn extends Expression {
} }
for (Column col : resolver.getColumns()) { for (Column col : resolver.getColumns()) {
String n = resolver.getDerivedColumnName(col); String n = resolver.getDerivedColumnName(col);
boolean derived;
if (n == null) { if (n == null) {
n = col.getName(); n = col.getName();
derived = false;
} else {
derived = true;
} }
if (database.equalsIdentifiers(columnName, n)) { if (database.equalsIdentifiers(columnName, n)) {
mapColumn(resolver, col, level); mapColumn(resolver, col, level);
if (derived) {
derivedName = n;
}
return; return;
} }
} }
......
...@@ -7,6 +7,7 @@ package org.h2.table; ...@@ -7,6 +7,7 @@ package org.h2.table;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Parser; import org.h2.command.Parser;
...@@ -122,7 +123,7 @@ public class TableFilter implements ColumnResolver { ...@@ -122,7 +123,7 @@ public class TableFilter implements ColumnResolver {
private final int hashCode; private final int hashCode;
private final int orderInFrom; private final int orderInFrom;
private HashMap<Column, String> derivedColumnMap; private LinkedHashMap<Column, String> derivedColumnMap;
/** /**
* Create a new table filter object. * Create a new table filter object.
...@@ -801,6 +802,18 @@ public class TableFilter implements ColumnResolver { ...@@ -801,6 +802,18 @@ public class TableFilter implements ColumnResolver {
if (alias != null) { if (alias != null) {
builder.append(' '); builder.append(' ');
Parser.quoteIdentifier(builder, alias); Parser.quoteIdentifier(builder, alias);
if (derivedColumnMap != null) {
builder.append('(');
boolean f = false;
for (String name : derivedColumnMap.values()) {
if (f) {
builder.append(", ");
}
f = true;
Parser.quoteIdentifier(builder, name);
}
builder.append(')');
}
} }
if (indexHints != null) { if (indexHints != null) {
builder.append(" USE INDEX ("); builder.append(" USE INDEX (");
...@@ -1091,7 +1104,7 @@ public class TableFilter implements ColumnResolver { ...@@ -1091,7 +1104,7 @@ public class TableFilter implements ColumnResolver {
if (count != derivedColumnNames.size()) { if (count != derivedColumnNames.size()) {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
} }
HashMap<Column, String> map = new HashMap<>(); LinkedHashMap<Column, String> map = new LinkedHashMap<>();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
String alias = derivedColumnNames.get(i); String alias = derivedColumnNames.get(i);
for (int j = 0; j < i; j++) { for (int j = 0; j < i; j++) {
......
...@@ -602,3 +602,34 @@ FROM (SELECT 1 X), (VALUES (1, 2), (2, 1), (3, 3)) T(A, B); ...@@ -602,3 +602,34 @@ FROM (SELECT 1 X), (VALUES (1, 2), (2, 1), (3, 3)) T(A, B);
> 1 2 1 > 1 2 1
> 1 3 3 > 1 3 3
> rows: 3 > rows: 3
SELECT A, SUM(S) OVER (ORDER BY S) FROM
(SELECT A, SUM(B) FROM (VALUES (1, 2), (1, 3), (3, 5), (3, 10)) V(A, B) GROUP BY A) S(A, S);
> A SUM(S) OVER (ORDER BY S)
> - ------------------------
> 1 5
> 3 20
> rows: 2
SELECT A, B, C FROM (SELECT A, B, C FROM (VALUES (1, 2, 3)) V(A, B, C));
> A B C
> - - -
> 1 2 3
> rows: 1
SELECT * FROM (SELECT * FROM (VALUES (1, 2, 3)) V(A, B, C));
> A B C
> - - -
> 1 2 3
> rows: 1
SELECT * FROM
(SELECT X * X, Y FROM
(SELECT A + 5, B FROM
(VALUES (1, 2)) V(A, B)
) T(X, Y)
);
> X * X Y
> ----- -
> 36 2
> rows: 1
...@@ -4,20 +4,20 @@ ...@@ -4,20 +4,20 @@
-- --
SELECT HISTOGRAM(X), HISTOGRAM(DISTINCT X) FROM VALUES (1), (2), (3), (1), (2), (NULL), (5) T(X); SELECT HISTOGRAM(X), HISTOGRAM(DISTINCT X) FROM VALUES (1), (2), (3), (1), (2), (NULL), (5) T(X);
> HISTOGRAM(C1) HISTOGRAM(DISTINCT C1) > HISTOGRAM(X) HISTOGRAM(DISTINCT X)
> ------------------------------------------- ------------------------------------------- > ------------------------------------------- -------------------------------------------
> [[null, 1], [1, 2], [2, 2], [3, 1], [5, 1]] [[null, 1], [1, 1], [2, 1], [3, 1], [5, 1]] > [[null, 1], [1, 2], [2, 2], [3, 1], [5, 1]] [[null, 1], [1, 1], [2, 1], [3, 1], [5, 1]]
> rows: 1 > rows: 1
SELECT HISTOGRAM(X) FILTER (WHERE X > 1), HISTOGRAM(DISTINCT X) FILTER (WHERE X > 1) SELECT HISTOGRAM(X) FILTER (WHERE X > 1), HISTOGRAM(DISTINCT X) FILTER (WHERE X > 1)
FROM VALUES (1), (2), (3), (1), (2), (NULL), (5) T(X); FROM VALUES (1), (2), (3), (1), (2), (NULL), (5) T(X);
> HISTOGRAM(C1) FILTER (WHERE (C1 > 1)) HISTOGRAM(DISTINCT C1) FILTER (WHERE (C1 > 1)) > HISTOGRAM(X) FILTER (WHERE (X > 1)) HISTOGRAM(DISTINCT X) FILTER (WHERE (X > 1))
> ------------------------------------- ---------------------------------------------- > ----------------------------------- --------------------------------------------
> [[2, 2], [3, 1], [5, 1]] [[2, 1], [3, 1], [5, 1]] > [[2, 2], [3, 1], [5, 1]] [[2, 1], [3, 1], [5, 1]]
> rows: 1 > rows: 1
SELECT HISTOGRAM(X) FILTER (WHERE X > 0), HISTOGRAM(DISTINCT X) FILTER (WHERE X > 0) FROM VALUES (0) T(X); SELECT HISTOGRAM(X) FILTER (WHERE X > 0), HISTOGRAM(DISTINCT X) FILTER (WHERE X > 0) FROM VALUES (0) T(X);
> HISTOGRAM(C1) FILTER (WHERE (C1 > 0)) HISTOGRAM(DISTINCT C1) FILTER (WHERE (C1 > 0)) > HISTOGRAM(X) FILTER (WHERE (X > 0)) HISTOGRAM(DISTINCT X) FILTER (WHERE (X > 0))
> ------------------------------------- ---------------------------------------------- > ----------------------------------- --------------------------------------------
> [] [] > [] []
> rows: 1 > rows: 1
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论