提交 387316e1 authored 作者: Thomas Mueller's avatar Thomas Mueller

ROWNUM could not be used for pagination. The follow query returned no rows:…

ROWNUM could not be used for pagination. The follow query returned no rows: select x from (select *, rownum as r from system_range(1, 3)) where r=2;
上级 2011d637
......@@ -997,9 +997,15 @@ public class Select extends Query {
public void addGlobalCondition(Parameter param, int columnId, int comparisonType) {
addParameter(param);
Expression comp;
Expression col = expressions.get(columnId);
col = col.getNonAliasExpression();
Expression comp = new Comparison(session, comparisonType, col, param);
if (col.isEverything(ExpressionVisitor.QUERY_COMPARABLE)) {
comp = new Comparison(session, comparisonType, col, param);
} else {
// add the parameters, so they can be set later
comp = new Comparison(session, Comparison.EQUAL, param, param);
}
comp = comp.optimize(session);
boolean addToCondition = true;
if (isGroupQuery) {
......
......@@ -236,6 +236,7 @@ public class ExpressionColumn extends Expression {
return false;
case ExpressionVisitor.READONLY:
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.QUERY_COMPARABLE:
return true;
case ExpressionVisitor.INDEPENDENT:
return this.queryLevel < visitor.getQueryLevel();
......
......@@ -63,6 +63,14 @@ public class ExpressionVisitor {
*/
public static final int GET_DEPENDENCIES = 7;
/**
* Can the expression be added to a condition of an outer query.
* Example: ROWNUM() can't be added as a condition to the inner query of
* select id from (select t.*, rownum as r from test t) where r between 2 and 3;
* Also a sequence expression must not be used.
*/
public static final int QUERY_COMPARABLE = 8;
private int queryLevel;
private Table table;
private int type;
......
......@@ -82,13 +82,12 @@ public class JavaAggregate extends Expression {
case ExpressionVisitor.DETERMINISTIC:
// TODO optimization: some functions are deterministic, but we don't
// know (no setting for that)
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
// user defined aggregate functions can not be optimized
return false;
case ExpressionVisitor.GET_DEPENDENCIES:
visitor.addDependency(userAggregate);
break;
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
// user defined aggregate functions can not be optimized
return false;
default:
}
for (Expression e : args) {
......
......@@ -126,23 +126,19 @@ public class Parameter extends Expression implements ParameterInterface {
public boolean isEverything(ExpressionVisitor visitor) {
switch(visitor.getType()) {
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
return true;
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY:
return true;
case ExpressionVisitor.INDEPENDENT:
return value != null;
case ExpressionVisitor.EVALUATABLE:
// the parameter _will_be_ evaluatable at execute time
return true;
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
// it is checked independently if the value is the same as the last time
return true;
case ExpressionVisitor.NOT_FROM_RESOLVER:
return true;
case ExpressionVisitor.QUERY_COMPARABLE:
case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY:
return true;
case ExpressionVisitor.INDEPENDENT:
return value != null;
default:
throw DbException.throwInternalError("type="+visitor.getType());
}
......
......@@ -67,22 +67,17 @@ public class Rownum extends Expression {
public boolean isEverything(ExpressionVisitor visitor) {
switch(visitor.getType()) {
case ExpressionVisitor.QUERY_COMPARABLE:
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
return false;
case ExpressionVisitor.DETERMINISTIC:
return false;
case ExpressionVisitor.INDEPENDENT:
return false;
case ExpressionVisitor.EVALUATABLE:
return true;
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
// if everything else is the same, the rownum is the same
return true;
case ExpressionVisitor.READONLY:
return true;
case ExpressionVisitor.NOT_FROM_RESOLVER:
return true;
case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
// if everything else is the same, the rownum is the same
return true;
default:
throw DbException.throwInternalError("type="+visitor.getType());
......
......@@ -70,20 +70,18 @@ public class SequenceValue extends Expression {
public boolean isEverything(ExpressionVisitor visitor) {
switch(visitor.getType()) {
case ExpressionVisitor.EVALUATABLE:
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
case ExpressionVisitor.NOT_FROM_RESOLVER:
return true;
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY:
return false;
case ExpressionVisitor.INDEPENDENT:
case ExpressionVisitor.QUERY_COMPARABLE:
return false;
case ExpressionVisitor.EVALUATABLE:
return true;
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
visitor.addDataModificationId(sequence.getModificationId());
return true;
case ExpressionVisitor.NOT_FROM_RESOLVER:
return true;
case ExpressionVisitor.GET_DEPENDENCIES:
visitor.addDependency(sequence);
return true;
......
......@@ -135,19 +135,14 @@ public class ValueExpression extends Expression {
public boolean isEverything(ExpressionVisitor visitor) {
switch (visitor.getType()) {
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
return true;
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY:
return true;
case ExpressionVisitor.INDEPENDENT:
return true;
case ExpressionVisitor.EVALUATABLE:
return true;
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
return true;
case ExpressionVisitor.NOT_FROM_RESOLVER:
return true;
case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.QUERY_COMPARABLE:
return true;
default:
throw DbException.throwInternalError("type=" + visitor.getType());
......
......@@ -57,24 +57,19 @@ public class Variable extends Expression {
public boolean isEverything(ExpressionVisitor visitor) {
switch(visitor.getType()) {
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
return true;
case ExpressionVisitor.DETERMINISTIC:
return false;
case ExpressionVisitor.READONLY:
return true;
case ExpressionVisitor.INDEPENDENT:
return true;
case ExpressionVisitor.EVALUATABLE:
// the value will be evaluated at execute time
return true;
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
// it is checked independently if the value is the same as the last time
return true;
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
case ExpressionVisitor.READONLY:
case ExpressionVisitor.INDEPENDENT:
case ExpressionVisitor.NOT_FROM_RESOLVER:
return true;
case ExpressionVisitor.QUERY_COMPARABLE:
case ExpressionVisitor.GET_DEPENDENCIES:
return true;
case ExpressionVisitor.DETERMINISTIC:
return false;
default:
throw DbException.throwInternalError("type="+visitor.getType());
}
......
select x from (select *, rownum as r from system_range(1, 3)) where r=2;
> 2;
select cast(cast('01020304-0506-0708-090a-0b0c0d0e0f00' as uuid) as binary);
> 0102030405060708090a0b0c0d0e0f00;
create table test(name varchar(255)) as select 'Hello+World+';
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论