提交 04e8cbad authored 作者: Thomas Mueller's avatar Thomas Mueller

The optimization for IN(...) is now only used if comparing a column with an index.

上级 b0b00641
......@@ -13,6 +13,7 @@ import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.index.Index;
import org.h2.index.IndexCondition;
import org.h2.schema.Schema;
import org.h2.table.Column;
......@@ -215,6 +216,14 @@ public class ConditionIn extends Condition {
if (!areAllValues(ExpressionVisitor.get(ExpressionVisitor.EVALUATABLE))) {
return this;
}
if (!(left instanceof ExpressionColumn)) {
return this;
}
ExpressionColumn ec = (ExpressionColumn) left;
Index index = ec.getTableFilter().getTable().getIndexForColumn(ec.getColumn(), false);
if (index == null) {
return this;
}
Database db = session.getDatabase();
Schema mainSchema = db.getSchema(Constants.SCHEMA_MAIN);
int rowCount = values.size();
......@@ -233,7 +242,7 @@ public class ConditionIn extends Condition {
Column col = new Column(columnName, dataType);
columns.add(col);
function.setColumns(columns);
FunctionTable table = new FunctionTable(mainSchema, session, function);
FunctionTable table = new FunctionTable(mainSchema, session, function, function);
String viewName = session.getNextSystemIdentifier(select.getSQL());
TableFilter filter = new TableFilter(session, table, viewName, false, select);
select.addTableFilter(filter, true);
......
......@@ -13,6 +13,7 @@ import org.h2.command.dml.Select;
import org.h2.constant.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.index.Index;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.table.ColumnResolver;
......@@ -128,6 +129,7 @@ public class ConditionInSelect extends Condition {
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
query.setDistinct(true);
if (all || compareType != Comparison.EQUAL) {
return this;
}
......@@ -135,10 +137,17 @@ public class ConditionInSelect extends Condition {
return this;
}
String alias = query.getFirstColumnAlias(session);
query.setDistinct(true);
if (alias == null) {
return this;
}
if (!(left instanceof ExpressionColumn)) {
return this;
}
ExpressionColumn ec = (ExpressionColumn) left;
Index index = ec.getTableFilter().getTable().getIndexForColumn(ec.getColumn(), false);
if (index == null) {
return this;
}
String name = session.getNextSystemIdentifier(select.getSQL());
TableView view = TableView.createTempView(session, session.getUser(), name, query, select);
TableFilter filter = new TableFilter(session, view, name, false, select);
......
......@@ -12,6 +12,7 @@ import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.value.Value;
/**
* A cursor for a function that returns a result set.
......@@ -19,6 +20,7 @@ import org.h2.result.SearchRow;
public class FunctionCursor implements Cursor {
private LocalResult result;
private Value[] values;
private Row row;
FunctionCursor(LocalResult result) {
......@@ -26,11 +28,17 @@ public class FunctionCursor implements Cursor {
}
public Row get() {
if (values == null) {
return null;
}
if (row == null) {
row = new Row(values, 0);
}
return row;
}
public SearchRow getSearchRow() {
return row;
return get();
}
public int getPos() {
......@@ -38,12 +46,13 @@ public class FunctionCursor implements Cursor {
}
public boolean next() throws SQLException {
row = null;
if (result.next()) {
row = new Row(result.currentRow(), 0);
values = result.currentRow();
} else {
row = null;
values = null;
}
return row != null;
return values != null;
}
public boolean previous() {
......
......@@ -35,9 +35,13 @@ public class FunctionTable extends Table {
private final FunctionCall function;
private final long rowCount;
private Expression functionExpr;
private LocalResult cachedResult;
private Value cachedValue;
public FunctionTable(Schema schema, Session session, FunctionCall function) throws SQLException {
public FunctionTable(Schema schema, Session session, Expression functionExpr, FunctionCall function) throws SQLException {
super(schema, 0, function.getName(), false);
this.functionExpr = functionExpr;
this.function = function;
if (function instanceof TableFunction) {
rowCount = ((TableFunction) function).getRowCount();
......@@ -151,14 +155,23 @@ public class FunctionTable extends Table {
* @return the result set
*/
public LocalResult getResult(Session session) throws SQLException {
function.optimize(session);
Value v = function.getValue(session);
functionExpr = functionExpr.optimize(session);
Value v = functionExpr.getValue(session);
if (cachedResult != null && cachedValue == v) {
cachedResult.reset();
return cachedResult;
}
if (v == ValueNull.INSTANCE) {
return new LocalResult();
}
ValueResultSet value = (ValueResultSet) v;
ResultSet rs = value.getResultSet();
return LocalResult.read(session, rs, 0);
LocalResult result = LocalResult.read(session, rs, 0);
if (function.isDeterministic()) {
cachedResult = result;
cachedValue = v;
}
return result;
}
public long getMaxDataModificationId() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论