提交 f8128109 authored 作者: Thomas Mueller's avatar Thomas Mueller

The system property h2.optimizeInJoin did not work correctly.

上级 b8401436
......@@ -711,7 +711,7 @@ public class Select extends Query {
}
if (condition != null) {
condition = condition.optimize(session);
if (SysProperties.OPTIMIZE_IN_JOIN) {
if (SysProperties.optimizeInJoin) {
condition = condition.optimizeInJoin(session, this);
}
for (int j = 0; j < filters.size(); j++) {
......
......@@ -358,7 +358,7 @@ public class SysProperties {
* Optimize IN(...) comparisons by converting them to inner joins.
*/
// TODO change in version 1.1
public static final boolean OPTIMIZE_IN_JOIN = getBooleanSetting("h2.optimizeInJoin", false);
public static boolean optimizeInJoin = getBooleanSetting("h2.optimizeInJoin", false);
/**
* System property <code>h2.optimizeMinMax</code> (default: true).<br />
......
......@@ -217,9 +217,10 @@ public class ConditionIn extends Condition {
}
Database db = session.getDatabase();
Schema mainSchema = db.getSchema(Constants.SCHEMA_MAIN);
TableFunction function = new TableFunction(database, Function.getFunctionInfo("TABLE_DISTINCT"));
Expression[] array = new Expression[values.size()];
for (int i = 0; i < values.size(); i++) {
int rowCount = values.size();
TableFunction function = new TableFunction(database, Function.getFunctionInfo("TABLE_DISTINCT"), rowCount);
Expression[] array = new Expression[rowCount];
for (int i = 0; i < rowCount; i++) {
Expression e = (Expression) values.get(i);
array[i] = e;
}
......@@ -237,10 +238,10 @@ public class ConditionIn extends Condition {
TableFilter filter = new TableFilter(session, table, viewName, false, select);
select.addTableFilter(filter, true);
ExpressionColumn column = new ExpressionColumn(db, null, viewName, columnName);
Comparison on = new Comparison(session, Comparison.EQUAL, left, column);
Expression on = new Comparison(session, Comparison.EQUAL, left, column);
on.mapColumns(filter, 0);
filter.addFilterCondition(on, true);
return ValueExpression.get(ValueBoolean.get(true));
on = on.optimize(session);
return new ConditionAndOr(ConditionAndOr.AND, this, on);
}
}
......@@ -363,7 +363,7 @@ public class Function extends Expression implements FunctionCall {
switch(info.type) {
case TABLE:
case TABLE_DISTINCT:
return new TableFunction(database, info);
return new TableFunction(database, info, Long.MAX_VALUE);
default:
return new Function(database, info);
}
......
......@@ -27,12 +27,14 @@ import org.h2.value.ValueResultSet;
* Implementation of the functions TABLE(..) and TABLE_DISTINCT(..).
*/
public class TableFunction extends Function implements FunctionCall {
private boolean distinct;
private final boolean distinct;
private final long rowCount;
private Column[] columnList;
TableFunction(Database database, FunctionInfo info) {
TableFunction(Database database, FunctionInfo info, long rowCount) {
super(database, info);
distinct = info.type == Function.TABLE_DISTINCT;
this.rowCount = rowCount;
}
public Value getValue(Session session) throws SQLException {
......@@ -148,5 +150,9 @@ public class TableFunction extends Function implements FunctionCall {
}
return simple;
}
public long getRowCount() {
return rowCount;
}
}
......@@ -53,8 +53,7 @@ public class FunctionIndex extends BaseIndex {
if (masks != null) {
throw Message.getUnsupportedException();
}
return Integer.MAX_VALUE;
// return functionTable.getRowCount(session) * 10;
return functionTable.getRowCount(session) * 10;
}
public void remove(Session session) throws SQLException {
......
......@@ -14,6 +14,7 @@ import org.h2.constant.ErrorCode;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.expression.FunctionCall;
import org.h2.expression.TableFunction;
import org.h2.index.FunctionIndex;
import org.h2.index.Index;
import org.h2.index.IndexType;
......@@ -33,10 +34,16 @@ import org.h2.value.ValueResultSet;
public class FunctionTable extends Table {
private final FunctionCall function;
private final long rowCount;
public FunctionTable(Schema schema, Session session, FunctionCall function) throws SQLException {
super(schema, 0, function.getName(), false);
this.function = function;
if (function instanceof TableFunction) {
rowCount = ((TableFunction) function).getRowCount();
} else {
rowCount = Long.MAX_VALUE;
}
function.optimize(session);
int type = function.getType();
if (type != Value.RESULT_SET) {
......@@ -118,11 +125,11 @@ public class FunctionTable extends Table {
}
public boolean canGetRowCount() {
return false;
return rowCount != Long.MAX_VALUE;
}
public long getRowCount(Session session) {
throw Message.getInternalError();
return rowCount;
}
public String getCreateSQL() {
......
......@@ -827,7 +827,7 @@ public class MetaTable extends Table {
add(rows, new String[]{"h2.objectCacheSize", "" + SysProperties.OBJECT_CACHE_SIZE});
add(rows, new String[]{"h2.objectCacheMaxPerElementSize", "" + SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE});
add(rows, new String[]{"h2.optimizeIn", "" + SysProperties.OPTIMIZE_IN});
add(rows, new String[]{"h2.optimizeInJoin", "" + SysProperties.OPTIMIZE_IN_JOIN});
add(rows, new String[]{"h2.optimizeInJoin", "" + SysProperties.optimizeInJoin});
add(rows, new String[]{"h2.optimizeMinMax", "" + SysProperties.OPTIMIZE_MIN_MAX});
add(rows, new String[]{"h2.optimizeSubqueryCache", "" + SysProperties.OPTIMIZE_SUBQUERY_CACHE});
add(rows, new String[]{"h2.overflowExceptions", "" + SysProperties.OVERFLOW_EXCEPTIONS});
......
......@@ -272,6 +272,9 @@ java org.h2.test.TestAll timer
/*
Run benchmark with the newest versions of other databases.
documentation: use 'server mode' not 'remote mode'.
CREATE LINKED TABLE ... READONLY
CREATE FUNCTION? Function interface
main methods for the tests and make that work
......
......@@ -15,6 +15,7 @@ import java.util.HashMap;
import java.util.Random;
import java.util.TreeSet;
import org.h2.constant.SysProperties;
import org.h2.test.TestBase;
/**
......@@ -28,6 +29,7 @@ public class TestOptimizations extends TestBase {
if (config.networked) {
return;
}
testOptimizeInJoin();
testMultiColumnRangeQuery();
testDistinctOptimization();
testQueryCacheTimestamp();
......@@ -39,6 +41,27 @@ public class TestOptimizations extends TestBase {
testMinMaxCountOptimization(false);
}
private void testOptimizeInJoin() throws Exception {
boolean old = SysProperties.optimizeInJoin;
SysProperties.optimizeInJoin = true;
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key)");
stat.execute("insert into test select x from system_range(1, 1000)");
ResultSet rs = stat.executeQuery("explain select * from test where id in (400, 300)");
rs.next();
String plan = rs.getString(1);
if (plan.indexOf("/* PUBLIC.PRIMARY_KEY_") < 0) {
fail("Expected using the primary key, got: " + plan);
}
conn.close();
SysProperties.optimizeInJoin = old;
}
private void testMinMaxNullOptimization() throws Exception {
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论