提交 820754cf authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Prevent incorrect optimizations for window aggregates too

上级 39ab2054
...@@ -15,6 +15,7 @@ import org.h2.command.dml.SelectGroups; ...@@ -15,6 +15,7 @@ import org.h2.command.dml.SelectGroups;
import org.h2.command.dml.SelectOrderBy; import org.h2.command.dml.SelectOrderBy;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
...@@ -292,6 +293,30 @@ public abstract class AbstractAggregate extends Expression { ...@@ -292,6 +293,30 @@ public abstract class AbstractAggregate extends Expression {
protected abstract Object createAggregateData(); protected abstract Object createAggregateData();
@Override
public boolean isEverything(ExpressionVisitor visitor) {
if (over == null) {
return true;
}
switch (visitor.getType()) {
case ExpressionVisitor.QUERY_COMPARABLE:
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.INDEPENDENT:
return false;
case ExpressionVisitor.EVALUATABLE:
case ExpressionVisitor.READONLY:
case ExpressionVisitor.NOT_FROM_RESOLVER:
case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
return true;
default:
throw DbException.throwInternalError("type=" + visitor.getType());
}
}
@Override @Override
public Value getValue(Session session) { public Value getValue(Session session) {
SelectGroups groupData = select.getGroupDataIfCurrent(over != null); SelectGroups groupData = select.getGroupDataIfCurrent(over != null);
......
...@@ -746,6 +746,9 @@ public class Aggregate extends AbstractAggregate { ...@@ -746,6 +746,9 @@ public class Aggregate extends AbstractAggregate {
@Override @Override
public boolean isEverything(ExpressionVisitor visitor) { public boolean isEverything(ExpressionVisitor visitor) {
if (!super.isEverything(visitor)) {
return false;
}
if (filterCondition != null && !filterCondition.isEverything(visitor)) { if (filterCondition != null && !filterCondition.isEverything(visitor)) {
return false; return false;
} }
......
...@@ -91,6 +91,9 @@ public class JavaAggregate extends AbstractAggregate { ...@@ -91,6 +91,9 @@ public class JavaAggregate extends AbstractAggregate {
@Override @Override
public boolean isEverything(ExpressionVisitor visitor) { public boolean isEverything(ExpressionVisitor visitor) {
if (!super.isEverything(visitor)) {
return false;
}
switch (visitor.getType()) { switch (visitor.getType()) {
case ExpressionVisitor.DETERMINISTIC: case ExpressionVisitor.DETERMINISTIC:
// TODO optimization: some functions are deterministic, but we don't // TODO optimization: some functions are deterministic, but we don't
......
...@@ -7,7 +7,6 @@ package org.h2.expression.aggregate; ...@@ -7,7 +7,6 @@ package org.h2.expression.aggregate;
import org.h2.command.dml.Select; import org.h2.command.dml.Select;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.ExpressionVisitor;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
...@@ -230,27 +229,6 @@ public class WindowFunction extends AbstractAggregate { ...@@ -230,27 +229,6 @@ public class WindowFunction extends AbstractAggregate {
return appendTailConditions(builder).toString(); return appendTailConditions(builder).toString();
} }
@Override
public boolean isEverything(ExpressionVisitor visitor) {
switch (visitor.getType()) {
case ExpressionVisitor.QUERY_COMPARABLE:
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.INDEPENDENT:
return false;
case ExpressionVisitor.EVALUATABLE:
case ExpressionVisitor.READONLY:
case ExpressionVisitor.NOT_FROM_RESOLVER:
case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
return true;
default:
throw DbException.throwInternalError("type="+visitor.getType());
}
}
@Override @Override
public int getCost() { public int getCost() {
int cost = 1; int cost = 1;
......
...@@ -47,3 +47,25 @@ select count(v), count(v) filter (where v >= 4) from test; ...@@ -47,3 +47,25 @@ select count(v), count(v) filter (where v >= 4) from test;
drop table test; drop table test;
> ok > ok
CREATE TABLE TEST (ID INT PRIMARY KEY, NAME VARCHAR);
> ok
INSERT INTO TEST VALUES (1, 'b'), (3, 'a');
> update count: 2
SELECT COUNT(ID) OVER (ORDER BY NAME) AS NR,
A.ID AS ID FROM (SELECT ID, NAME FROM TEST ORDER BY NAME) AS A;
> NR ID
> -- --
> 1 3
> 2 1
> rows (ordered): 2
SELECT NR FROM (SELECT COUNT(ID) OVER (ORDER BY NAME) AS NR,
A.ID AS ID FROM (SELECT ID, NAME FROM TEST ORDER BY NAME) AS A)
AS B WHERE B.ID = 1;
>> 2
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论