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