提交 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 { ...@@ -711,7 +711,7 @@ public class Select extends Query {
} }
if (condition != null) { if (condition != null) {
condition = condition.optimize(session); condition = condition.optimize(session);
if (SysProperties.OPTIMIZE_IN_JOIN) { if (SysProperties.optimizeInJoin) {
condition = condition.optimizeInJoin(session, this); condition = condition.optimizeInJoin(session, this);
} }
for (int j = 0; j < filters.size(); j++) { for (int j = 0; j < filters.size(); j++) {
......
...@@ -358,7 +358,7 @@ public class SysProperties { ...@@ -358,7 +358,7 @@ public class SysProperties {
* Optimize IN(...) comparisons by converting them to inner joins. * Optimize IN(...) comparisons by converting them to inner joins.
*/ */
// TODO change in version 1.1 // 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 /> * System property <code>h2.optimizeMinMax</code> (default: true).<br />
......
...@@ -217,9 +217,10 @@ public class ConditionIn extends Condition { ...@@ -217,9 +217,10 @@ public class ConditionIn extends Condition {
} }
Database db = session.getDatabase(); Database db = session.getDatabase();
Schema mainSchema = db.getSchema(Constants.SCHEMA_MAIN); Schema mainSchema = db.getSchema(Constants.SCHEMA_MAIN);
TableFunction function = new TableFunction(database, Function.getFunctionInfo("TABLE_DISTINCT")); int rowCount = values.size();
Expression[] array = new Expression[values.size()]; TableFunction function = new TableFunction(database, Function.getFunctionInfo("TABLE_DISTINCT"), rowCount);
for (int i = 0; i < values.size(); i++) { Expression[] array = new Expression[rowCount];
for (int i = 0; i < rowCount; i++) {
Expression e = (Expression) values.get(i); Expression e = (Expression) values.get(i);
array[i] = e; array[i] = e;
} }
...@@ -237,10 +238,10 @@ public class ConditionIn extends Condition { ...@@ -237,10 +238,10 @@ public class ConditionIn extends Condition {
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);
ExpressionColumn column = new ExpressionColumn(db, null, viewName, columnName); 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); on.mapColumns(filter, 0);
filter.addFilterCondition(on, true); on = on.optimize(session);
return ValueExpression.get(ValueBoolean.get(true)); return new ConditionAndOr(ConditionAndOr.AND, this, on);
} }
} }
...@@ -363,7 +363,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -363,7 +363,7 @@ public class Function extends Expression implements FunctionCall {
switch(info.type) { switch(info.type) {
case TABLE: case TABLE:
case TABLE_DISTINCT: case TABLE_DISTINCT:
return new TableFunction(database, info); return new TableFunction(database, info, Long.MAX_VALUE);
default: default:
return new Function(database, info); return new Function(database, info);
} }
......
...@@ -27,12 +27,14 @@ import org.h2.value.ValueResultSet; ...@@ -27,12 +27,14 @@ import org.h2.value.ValueResultSet;
* Implementation of the functions TABLE(..) and TABLE_DISTINCT(..). * Implementation of the functions TABLE(..) and TABLE_DISTINCT(..).
*/ */
public class TableFunction extends Function implements FunctionCall { public class TableFunction extends Function implements FunctionCall {
private boolean distinct; private final boolean distinct;
private final long rowCount;
private Column[] columnList; private Column[] columnList;
TableFunction(Database database, FunctionInfo info) { TableFunction(Database database, FunctionInfo info, long rowCount) {
super(database, info); super(database, info);
distinct = info.type == Function.TABLE_DISTINCT; distinct = info.type == Function.TABLE_DISTINCT;
this.rowCount = rowCount;
} }
public Value getValue(Session session) throws SQLException { public Value getValue(Session session) throws SQLException {
...@@ -149,4 +151,8 @@ public class TableFunction extends Function implements FunctionCall { ...@@ -149,4 +151,8 @@ public class TableFunction extends Function implements FunctionCall {
return simple; return simple;
} }
public long getRowCount() {
return rowCount;
}
} }
...@@ -53,8 +53,7 @@ public class FunctionIndex extends BaseIndex { ...@@ -53,8 +53,7 @@ public class FunctionIndex extends BaseIndex {
if (masks != null) { if (masks != null) {
throw Message.getUnsupportedException(); throw Message.getUnsupportedException();
} }
return Integer.MAX_VALUE; return functionTable.getRowCount(session) * 10;
// return functionTable.getRowCount(session) * 10;
} }
public void remove(Session session) throws SQLException { public void remove(Session session) throws SQLException {
......
...@@ -14,6 +14,7 @@ import org.h2.constant.ErrorCode; ...@@ -14,6 +14,7 @@ import org.h2.constant.ErrorCode;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.FunctionCall; import org.h2.expression.FunctionCall;
import org.h2.expression.TableFunction;
import org.h2.index.FunctionIndex; import org.h2.index.FunctionIndex;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
...@@ -33,10 +34,16 @@ import org.h2.value.ValueResultSet; ...@@ -33,10 +34,16 @@ import org.h2.value.ValueResultSet;
public class FunctionTable extends Table { public class FunctionTable extends Table {
private final FunctionCall function; private final FunctionCall function;
private final long rowCount;
public FunctionTable(Schema schema, Session session, FunctionCall function) throws SQLException { public FunctionTable(Schema schema, Session session, FunctionCall function) throws SQLException {
super(schema, 0, function.getName(), false); super(schema, 0, function.getName(), false);
this.function = function; this.function = function;
if (function instanceof TableFunction) {
rowCount = ((TableFunction) function).getRowCount();
} else {
rowCount = Long.MAX_VALUE;
}
function.optimize(session); function.optimize(session);
int type = function.getType(); int type = function.getType();
if (type != Value.RESULT_SET) { if (type != Value.RESULT_SET) {
...@@ -118,11 +125,11 @@ public class FunctionTable extends Table { ...@@ -118,11 +125,11 @@ public class FunctionTable extends Table {
} }
public boolean canGetRowCount() { public boolean canGetRowCount() {
return false; return rowCount != Long.MAX_VALUE;
} }
public long getRowCount(Session session) { public long getRowCount(Session session) {
throw Message.getInternalError(); return rowCount;
} }
public String getCreateSQL() { public String getCreateSQL() {
......
...@@ -827,7 +827,7 @@ public class MetaTable extends Table { ...@@ -827,7 +827,7 @@ public class MetaTable extends Table {
add(rows, new String[]{"h2.objectCacheSize", "" + SysProperties.OBJECT_CACHE_SIZE}); 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.objectCacheMaxPerElementSize", "" + SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE});
add(rows, new String[]{"h2.optimizeIn", "" + SysProperties.OPTIMIZE_IN}); 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.optimizeMinMax", "" + SysProperties.OPTIMIZE_MIN_MAX});
add(rows, new String[]{"h2.optimizeSubqueryCache", "" + SysProperties.OPTIMIZE_SUBQUERY_CACHE}); add(rows, new String[]{"h2.optimizeSubqueryCache", "" + SysProperties.OPTIMIZE_SUBQUERY_CACHE});
add(rows, new String[]{"h2.overflowExceptions", "" + SysProperties.OVERFLOW_EXCEPTIONS}); add(rows, new String[]{"h2.overflowExceptions", "" + SysProperties.OVERFLOW_EXCEPTIONS});
......
...@@ -272,6 +272,9 @@ java org.h2.test.TestAll timer ...@@ -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 LINKED TABLE ... READONLY
CREATE FUNCTION? Function interface CREATE FUNCTION? Function interface
main methods for the tests and make that work main methods for the tests and make that work
......
...@@ -15,6 +15,7 @@ import java.util.HashMap; ...@@ -15,6 +15,7 @@ import java.util.HashMap;
import java.util.Random; import java.util.Random;
import java.util.TreeSet; import java.util.TreeSet;
import org.h2.constant.SysProperties;
import org.h2.test.TestBase; import org.h2.test.TestBase;
/** /**
...@@ -28,6 +29,7 @@ public class TestOptimizations extends TestBase { ...@@ -28,6 +29,7 @@ public class TestOptimizations extends TestBase {
if (config.networked) { if (config.networked) {
return; return;
} }
testOptimizeInJoin();
testMultiColumnRangeQuery(); testMultiColumnRangeQuery();
testDistinctOptimization(); testDistinctOptimization();
testQueryCacheTimestamp(); testQueryCacheTimestamp();
...@@ -39,6 +41,27 @@ public class TestOptimizations extends TestBase { ...@@ -39,6 +41,27 @@ public class TestOptimizations extends TestBase {
testMinMaxCountOptimization(false); 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 { private void testMinMaxNullOptimization() throws Exception {
deleteDb("optimizations"); deleteDb("optimizations");
Connection conn = getConnection("optimizations"); Connection conn = getConnection("optimizations");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论