提交 1c9a3212 authored 作者: Thomas Mueller's avatar Thomas Mueller

ROWNUM() did not work in combination with IN(..). The following query did not…

ROWNUM() did not work in combination with IN(..). The following query did not work as expected: select * from (select rownum r from test) where r in (1, 2).
上级 f33986e8
...@@ -1137,7 +1137,8 @@ public class Select extends Query { ...@@ -1137,7 +1137,8 @@ public class Select extends Query {
if (col.isEverything(ExpressionVisitor.QUERY_COMPARABLE_VISITOR)) { if (col.isEverything(ExpressionVisitor.QUERY_COMPARABLE_VISITOR)) {
comp = new Comparison(session, comparisonType, col, param); comp = new Comparison(session, comparisonType, col, param);
} else { } else {
// add the parameters, so they can be set later // this condition will always evaluate to true, but need to
// add the parameter, so it can be set later
comp = new Comparison(session, Comparison.EQUAL_NULL_SAFE, param, param); comp = new Comparison(session, Comparison.EQUAL_NULL_SAFE, param, param);
} }
comp = comp.optimize(session); comp = comp.optimize(session);
......
...@@ -19,13 +19,18 @@ import org.h2.value.ValueNull; ...@@ -19,13 +19,18 @@ import org.h2.value.ValueNull;
*/ */
public class ViewCursor implements Cursor { public class ViewCursor implements Cursor {
private Table table; private final Table table;
private ResultInterface result; private final Index index;
private final ResultInterface result;
private final SearchRow first, last;
private Row current; private Row current;
ViewCursor(Table table, ResultInterface result) { ViewCursor(Index index, ResultInterface result, SearchRow first, SearchRow last) {
this.table = table; this.table = index.getTable();
this.index = index;
this.result = result; this.result = result;
this.first = first;
this.last = last;
} }
public Row get() { public Row get() {
...@@ -37,19 +42,34 @@ public class ViewCursor implements Cursor { ...@@ -37,19 +42,34 @@ public class ViewCursor implements Cursor {
} }
public boolean next() { public boolean next() {
boolean res = result.next(); while (true) {
if (!res) { boolean res = result.next();
result.close(); if (!res) {
current = null; result.close();
return false; current = null;
return false;
}
current = table.getTemplateRow();
Value[] values = result.currentRow();
for (int i = 0, len = current.getColumnCount(); i < len; i++) {
Value v = i < values.length ? values[i] : ValueNull.INSTANCE;
current.setValue(i, v);
}
int comp;
if (first != null) {
comp = index.compareRows(current, first);
if (comp < 0) {
continue;
}
}
if (last != null) {
comp = index.compareRows(current, last);
if (comp > 0) {
continue;
}
}
return true;
} }
current = table.getTemplateRow();
Value[] values = result.currentRow();
for (int i = 0, len = current.getColumnCount(); i < len; i++) {
Value v = i < values.length ? values[i] : ValueNull.INSTANCE;
current.setValue(i, v);
}
return true;
} }
public boolean previous() { public boolean previous() {
......
...@@ -20,6 +20,7 @@ import org.h2.result.ResultInterface; ...@@ -20,6 +20,7 @@ import org.h2.result.ResultInterface;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.TableView; import org.h2.table.TableView;
import org.h2.util.IntArray; import org.h2.util.IntArray;
import org.h2.util.New; import org.h2.util.New;
...@@ -161,7 +162,7 @@ public class ViewIndex extends BaseIndex { ...@@ -161,7 +162,7 @@ public class ViewIndex extends BaseIndex {
ResultInterface recResult = view.getRecursiveResult(); ResultInterface recResult = view.getRecursiveResult();
if (recResult != null) { if (recResult != null) {
recResult.reset(); recResult.reset();
return new ViewCursor(table, recResult); return new ViewCursor(this, recResult, first, last);
} }
if (query == null) { if (query == null) {
query = (Query) createSession.prepare(querySQL, true); query = (Query) createSession.prepare(querySQL, true);
...@@ -200,7 +201,7 @@ public class ViewIndex extends BaseIndex { ...@@ -200,7 +201,7 @@ public class ViewIndex extends BaseIndex {
} }
view.setRecursiveResult(null); view.setRecursiveResult(null);
result.done(); result.done();
return new ViewCursor(table, result); return new ViewCursor(this, result, first, last);
} }
ArrayList<Parameter> paramList = query.getParameters(); ArrayList<Parameter> paramList = query.getParameters();
if (originalParameters != null) { if (originalParameters != null) {
...@@ -239,7 +240,7 @@ public class ViewIndex extends BaseIndex { ...@@ -239,7 +240,7 @@ public class ViewIndex extends BaseIndex {
} }
} }
ResultInterface result = query.query(0); ResultInterface result = query.query(0);
return new ViewCursor(table, result); return new ViewCursor(this, result, first, last);
} }
private static void setParameter(ArrayList<Parameter> paramList, int x, Value v) { private static void setParameter(ArrayList<Parameter> paramList, int x, Value v) {
...@@ -260,11 +261,13 @@ public class ViewIndex extends BaseIndex { ...@@ -260,11 +261,13 @@ public class ViewIndex extends BaseIndex {
int firstIndexParam = originalParameters == null ? 0 : originalParameters.size(); int firstIndexParam = originalParameters == null ? 0 : originalParameters.size();
firstIndexParam += view.getParameterOffset(); firstIndexParam += view.getParameterOffset();
IntArray paramIndex = new IntArray(); IntArray paramIndex = new IntArray();
int indexColumnCount = 0;
for (int i = 0; i < masks.length; i++) { for (int i = 0; i < masks.length; i++) {
int mask = masks[i]; int mask = masks[i];
if (mask == 0) { if (mask == 0) {
continue; continue;
} }
indexColumnCount++;
paramIndex.add(i); paramIndex.add(i);
if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) { if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) {
// two parameters for range queries: >= x AND <= y // two parameters for range queries: >= x AND <= y
...@@ -296,6 +299,35 @@ public class ViewIndex extends BaseIndex { ...@@ -296,6 +299,35 @@ public class ViewIndex extends BaseIndex {
} }
columns = new Column[columnList.size()]; columns = new Column[columnList.size()];
columnList.toArray(columns); columnList.toArray(columns);
// reconstruct the index columns from the masks
this.indexColumns = new IndexColumn[indexColumnCount];
this.columnIds = new int[indexColumnCount];
for (int type = 0, indexColumnId = 0; type < 2; type++) {
for (int i = 0; i < masks.length; i++) {
int mask = masks[i];
if (mask == 0) {
continue;
}
if (type == 0) {
if ((mask & IndexCondition.EQUALITY) != IndexCondition.EQUALITY) {
// the first columns need to be equality conditions
continue;
}
} else {
if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) {
// then only range conditions
continue;
}
}
IndexColumn c = new IndexColumn();
c.column = table.getColumn(i);
indexColumns[indexColumnId] = c;
columnIds[indexColumnId] = c.column.getColumnId();
indexColumnId++;
}
}
String sql = q.getPlanSQL(); String sql = q.getPlanSQL();
q = (Query) session.prepare(sql, true); q = (Query) session.prepare(sql, true);
return q; return q;
......
--- special grammar and test cases --------------------------------------------------------------------------------------------- --- special grammar and test cases ---------------------------------------------------------------------------------------------
create table test(x int) as select x from system_range(1, 2);
> ok
select * from (select rownum r from test) where r in (1, 2);
> R
> -
> 1
> 2
> rows: 2
select * from (select rownum r from test) where r = 1 or r = 2;
> R
> -
> 1
> 2
> rows: 2
drop table test;
> ok
select 2^2; select 2^2;
> exception > exception
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论