Unverified 提交 cacef49b authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #902 from katzyn/nested_joins

Remove DbSettings.nestedJoins
......@@ -1368,14 +1368,9 @@ public class Parser {
query, currentSelect);
} else {
TableFilter top;
if (database.getSettings().nestedJoins) {
top = readTableFilter(false);
top = readJoin(top, currentSelect, false, false);
top = getNested(top);
} else {
top = readTableFilter(fromOuter);
top = readJoin(top, currentSelect, false, fromOuter);
}
top = readTableFilter(false);
top = readJoin(top, currentSelect, false, false);
top = getNested(top);
read(")");
alias = readFromAlias(null);
if (alias != null) {
......@@ -1726,88 +1721,57 @@ public class Parser {
boolean nested, boolean fromOuter) {
boolean joined = false;
TableFilter last = top;
boolean nestedJoins = database.getSettings().nestedJoins;
while (true) {
TableFilter join;
if (readIf("RIGHT")) {
readIf("OUTER");
read("JOIN");
joined = true;
// the right hand side is the 'inner' table usually
TableFilter newTop = readTableFilter(fromOuter);
newTop = readJoin(newTop, command, nested, true);
join = readTableFilter(fromOuter);
join = readJoin(join, command, nested, true);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
if (nestedJoins) {
top = getNested(top);
newTop.addJoin(top, true, false, on);
} else {
newTop.addJoin(top, true, false, on);
}
top = newTop;
last = newTop;
top = getNested(top);
join.addJoin(top, true, false, on);
top = join;
} else if (readIf("LEFT")) {
readIf("OUTER");
read("JOIN");
joined = true;
TableFilter join = readTableFilter(true);
if (nestedJoins) {
join = readJoin(join, command, true, true);
} else {
top = readJoin(top, command, false, true);
}
join = readTableFilter(true);
join = readJoin(join, command, true, true);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
top.addJoin(join, true, false, on);
last = join;
} else if (readIf("FULL")) {
throw getSyntaxError();
} else if (readIf("INNER")) {
read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter);
join = readTableFilter(fromOuter);
top = readJoin(top, command, false, false);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
if (nestedJoins) {
top.addJoin(join, false, false, on);
} else {
top.addJoin(join, fromOuter, false, on);
}
last = join;
top.addJoin(join, false, false, on);
} else if (readIf("JOIN")) {
joined = true;
TableFilter join = readTableFilter(fromOuter);
join = readTableFilter(fromOuter);
top = readJoin(top, command, false, false);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
if (nestedJoins) {
top.addJoin(join, false, false, on);
} else {
top.addJoin(join, fromOuter, false, on);
}
last = join;
top.addJoin(join, false, false, on);
} else if (readIf("CROSS")) {
read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter);
if (nestedJoins) {
top.addJoin(join, false, false, null);
} else {
top.addJoin(join, fromOuter, false, null);
}
last = join;
join = readTableFilter(fromOuter);
top.addJoin(join, false, false, null);
} else if (readIf("NATURAL")) {
read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter);
join = readTableFilter(fromOuter);
Column[] tableCols = last.getTable().getColumns();
Column[] joinCols = join.getTable().getColumns();
String tableSchema = last.getTable().getSchema().getName();
......@@ -1836,15 +1800,12 @@ public class Parser {
}
}
}
if (nestedJoins) {
top.addJoin(join, false, nested, on);
} else {
top.addJoin(join, fromOuter, false, on);
}
last = join;
top.addJoin(join, false, nested, on);
} else {
break;
}
joined = true;
last = join;
}
if (nested && joined) {
top = getNested(top);
......
......@@ -1046,26 +1046,10 @@ public class Select extends Query {
Expression on = f.getJoinCondition();
if (on != null) {
if (!on.isEverything(ExpressionVisitor.EVALUATABLE_VISITOR)) {
if (session.getDatabase().getSettings().nestedJoins) {
// need to check that all added are bound to a table
on = on.optimize(session);
if (!f.isJoinOuter() && !f.isJoinOuterIndirect()) {
f.removeJoinCondition();
addCondition(on);
}
} else {
if (f.isJoinOuter()) {
// this will check if all columns exist - it may or
// may not throw an exception
on = on.optimize(session);
// it is not supported even if the columns exist
throw DbException.get(
ErrorCode.UNSUPPORTED_OUTER_JOIN_CONDITION_1,
on.getSQL());
}
// need to check that all added are bound to a table
on = on.optimize(session);
if (!f.isJoinOuter() && !f.isJoinOuterIndirect()) {
f.removeJoinCondition();
// need to check that all added are bound to a table
on = on.optimize(session);
addCondition(on);
}
}
......
......@@ -7,6 +7,9 @@ package org.h2.engine;
import java.util.HashMap;
import org.h2.message.DbException;
import org.h2.util.Utils;
/**
* This class contains various database-level settings. To override the
* documented default value for a database, append the setting in the database
......@@ -164,12 +167,6 @@ public class DbSettings extends SettingsBase {
*/
public final int maxQueryTimeout = get("MAX_QUERY_TIMEOUT", 0);
/**
* Database setting <code>NESTED_JOINS</code> (default: true).<br />
* Whether nested joins should be supported.
*/
public final boolean nestedJoins = get("NESTED_JOINS", true);
/**
* Database setting <code>OPTIMIZE_DISTINCT</code> (default: true).<br />
* Improve the performance of simple DISTINCT queries if an index is
......@@ -363,6 +360,9 @@ public class DbSettings extends SettingsBase {
private DbSettings(HashMap<String, String> s) {
super(s);
if (s.get("NESTED_JOINS") != null || Utils.getProperty("h2.nestedJoins", null) != null) {
throw DbException.getUnsupportedException("NESTED_JOINS setting is not available since 1.4.197");
}
}
/**
......
......@@ -37,7 +37,6 @@ public class ExpressionColumn extends Expression {
private ColumnResolver columnResolver;
private int queryLevel;
private Column column;
private boolean evaluatable;
public ExpressionColumn(Database database, Column column) {
this.database = database;
......@@ -205,9 +204,6 @@ public class ExpressionColumn extends Expression {
@Override
public void setEvaluatable(TableFilter tableFilter, boolean b) {
if (columnResolver != null && tableFilter == columnResolver.getTableFilter()) {
evaluatable = b;
}
}
public Column getColumn() {
......@@ -287,19 +283,15 @@ public class ExpressionColumn extends Expression {
case ExpressionVisitor.INDEPENDENT:
return this.queryLevel < visitor.getQueryLevel();
case ExpressionVisitor.EVALUATABLE:
// if the current value is known (evaluatable set)
// or if this columns belongs to a 'higher level' query and is
// if this column belongs to a 'higher level' query and is
// therefore just a parameter
if (database.getSettings().nestedJoins) {
if (visitor.getQueryLevel() < this.queryLevel) {
return true;
}
if (getTableFilter() == null) {
return false;
}
return getTableFilter().isEvaluatable();
if (visitor.getQueryLevel() < this.queryLevel) {
return true;
}
if (getTableFilter() == null) {
return false;
}
return evaluatable || visitor.getQueryLevel() < this.queryLevel;
return getTableFilter().isEvaluatable();
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
visitor.addDataModificationId(column.getTable().getMaxDataModificationId());
return true;
......
......@@ -230,14 +230,14 @@ public class TableFilter implements ColumnResolver {
}
if (nestedJoin != null) {
setEvaluatable(nestedJoin);
setEvaluatable(true);
item.setNestedJoinPlan(nestedJoin.getBestPlanItem(s, filters, filter, allColumnsSet));
// TODO optimizer: calculate cost of a join: should use separate
// expected row number and lookup cost
item.cost += item.cost * item.getNestedJoinPlan().cost;
}
if (join != null) {
setEvaluatable(join);
setEvaluatable(true);
do {
filter++;
} while (filters[filter] != join);
......@@ -249,25 +249,6 @@ public class TableFilter implements ColumnResolver {
return item;
}
private void setEvaluatable(TableFilter join) {
if (session.getDatabase().getSettings().nestedJoins) {
setEvaluatable(true);
return;
}
// this table filter is now evaluatable - in all sub-joins
do {
Expression e = join.getJoinCondition();
if (e != null) {
e.setEvaluatable(this, true);
}
TableFilter n = join.getNestedJoin();
if (n != null) {
setEvaluatable(n);
}
join = join.getJoin();
} while (join != null);
}
/**
* Set what plan item (index, cost, masks) to use.
*
......@@ -663,13 +644,11 @@ public class TableFilter implements ColumnResolver {
final Expression on) {
if (on != null) {
on.mapColumns(this, 0);
if (session.getDatabase().getSettings().nestedJoins) {
TableFilterVisitor visitor = new MapColumnsVisitor(on);
visit(visitor);
filter.visit(visitor);
}
TableFilterVisitor visitor = new MapColumnsVisitor(on);
visit(visitor);
filter.visit(visitor);
}
if (nested && session.getDatabase().getSettings().nestedJoins) {
if (nested) {
if (nestedJoin != null) {
throw DbException.throwInternalError();
}
......@@ -685,20 +664,8 @@ public class TableFilter implements ColumnResolver {
if (join == null) {
join = filter;
filter.joinOuter = outer;
if (session.getDatabase().getSettings().nestedJoins) {
if (outer) {
filter.visit(new JOIVisitor());
}
} else {
if (outer) {
// convert all inner joins on the right hand side to
// outer joins
TableFilter f = filter.join;
while (f != null) {
f.joinOuter = true;
f = f.join;
}
}
if (outer) {
filter.visit(new JOIVisitor());
}
if (on != null) {
filter.mapAndAddFilter(on);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论