提交 24b4a0b0 authored 作者: Noel Grandin's avatar Noel Grandin

Merge remote-tracking branch 'upstream/master' into testing_pagestore

/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.command.dml;
import java.util.ArrayList;
import java.util.HashMap;
import org.h2.expression.ExpressionVisitor;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.table.TableFilter;
/**
* This information is expensive to compute for large queries, so do so
* on-demand. Also store the information pre-mapped by table to avoid expensive
* traversal.
*/
public class AllColumnsForPlan {
private final TableFilter[] filters;
private HashMap<Table, ArrayList<Column>> map;
public AllColumnsForPlan(TableFilter[] filters) {
this.filters = filters;
}
/** Called by ExpressionVisitor. */
public void add(Column newCol) {
ArrayList<Column> cols = map.get(newCol.getTable());
if (cols == null) {
cols = new ArrayList<>();
map.put(newCol.getTable(), cols);
}
if (!cols.contains(newCol))
cols.add(newCol);
}
public ArrayList<Column> get(Table table) {
if (map == null) {
map = new HashMap<>();
ExpressionVisitor.allColumnsForTableFilters(filters, this);
}
return map.get(table);
}
}
...@@ -12,7 +12,6 @@ import org.h2.engine.Right; ...@@ -12,7 +12,6 @@ import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.UndoLogRecord; import org.h2.engine.UndoLogRecord;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.RowList; import org.h2.result.RowList;
...@@ -148,7 +147,7 @@ public class Delete extends Prepared { ...@@ -148,7 +147,7 @@ public class Delete extends Prepared {
filters = new TableFilter[] { targetTableFilter, sourceTableFilter }; filters = new TableFilter[] { targetTableFilter, sourceTableFilter };
} }
PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0, PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0,
ExpressionVisitor.allColumnsForTableFilters(filters)); new AllColumnsForPlan(filters));
targetTableFilter.setPlanItem(item); targetTableFilter.setPlanItem(item);
targetTableFilter.prepare(); targetTableFilter.prepare();
} }
......
...@@ -8,7 +8,6 @@ package org.h2.command.dml; ...@@ -8,7 +8,6 @@ package org.h2.command.dml;
import java.util.BitSet; import java.util.BitSet;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.table.Plan; import org.h2.table.Plan;
...@@ -48,11 +47,13 @@ class Optimizer { ...@@ -48,11 +47,13 @@ class Optimizer {
private TableFilter topFilter; private TableFilter topFilter;
private double cost; private double cost;
private Random random; private Random random;
final AllColumnsForPlan allColumnsSet;
Optimizer(TableFilter[] filters, Expression condition, Session session) { Optimizer(TableFilter[] filters, Expression condition, Session session) {
this.filters = filters; this.filters = filters;
this.condition = condition; this.condition = condition;
this.session = session; this.session = session;
allColumnsSet = new AllColumnsForPlan(filters);
} }
/** /**
...@@ -134,7 +135,7 @@ class Optimizer { ...@@ -134,7 +135,7 @@ class Optimizer {
} }
list[i] = filters[j]; list[i] = filters[j];
Plan part = new Plan(list, i+1, condition); Plan part = new Plan(list, i+1, condition);
double costNow = part.calculateCost(session); double costNow = part.calculateCost(session, allColumnsSet);
if (costPart < 0 || costNow < costPart) { if (costPart < 0 || costNow < costPart) {
costPart = costNow; costPart = costNow;
bestPart = j; bestPart = j;
...@@ -177,7 +178,7 @@ class Optimizer { ...@@ -177,7 +178,7 @@ class Optimizer {
private boolean testPlan(TableFilter[] list) { private boolean testPlan(TableFilter[] list) {
Plan p = new Plan(list, list.length, condition); Plan p = new Plan(list, list.length, condition);
double costNow = p.calculateCost(session); double costNow = p.calculateCost(session, allColumnsSet);
if (cost < 0 || costNow < cost) { if (cost < 0 || costNow < cost) {
cost = costNow; cost = costNow;
bestPlan = p; bestPlan = p;
......
...@@ -8,7 +8,6 @@ package org.h2.command.dml; ...@@ -8,7 +8,6 @@ package org.h2.command.dml;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects; import java.util.Objects;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
...@@ -16,7 +15,6 @@ import org.h2.command.Prepared; ...@@ -16,7 +15,6 @@ import org.h2.command.Prepared;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor;
import org.h2.expression.Parameter; import org.h2.expression.Parameter;
import org.h2.expression.ValueExpression; import org.h2.expression.ValueExpression;
import org.h2.message.DbException; import org.h2.message.DbException;
...@@ -236,7 +234,7 @@ public class Update extends Prepared { ...@@ -236,7 +234,7 @@ public class Update extends Prepared {
filters = new TableFilter[] { targetTableFilter, sourceTableFilter }; filters = new TableFilter[] { targetTableFilter, sourceTableFilter };
} }
PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0, PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0,
ExpressionVisitor.allColumnsForTableFilters(filters)); new AllColumnsForPlan(filters));
targetTableFilter.setPlanItem(item); targetTableFilter.setPlanItem(item);
targetTableFilter.prepare(); targetTableFilter.prepare();
} }
......
...@@ -133,7 +133,8 @@ public class ConditionInConstantSet extends Condition { ...@@ -133,7 +133,8 @@ public class ConditionInConstantSet extends Condition {
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
case ExpressionVisitor.GET_DEPENDENCIES: case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.QUERY_COMPARABLE: case ExpressionVisitor.QUERY_COMPARABLE:
case ExpressionVisitor.GET_COLUMNS: case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
return true; return true;
default: default:
throw DbException.throwInternalError("type=" + visitor.getType()); throw DbException.throwInternalError("type=" + visitor.getType());
......
...@@ -311,8 +311,11 @@ public class ExpressionColumn extends Expression { ...@@ -311,8 +311,11 @@ public class ExpressionColumn extends Expression {
visitor.addDependency(column.getTable()); visitor.addDependency(column.getTable());
} }
return true; return true;
case ExpressionVisitor.GET_COLUMNS: case ExpressionVisitor.GET_COLUMNS1:
visitor.addColumn(column); visitor.addColumn1(column);
return true;
case ExpressionVisitor.GET_COLUMNS2:
visitor.addColumn2(column);
return true; return true;
default: default:
throw DbException.throwInternalError("type=" + visitor.getType()); throw DbException.throwInternalError("type=" + visitor.getType());
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
package org.h2.expression; package org.h2.expression;
import java.util.HashSet; import java.util.HashSet;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
...@@ -95,10 +96,15 @@ public class ExpressionVisitor { ...@@ -95,10 +96,15 @@ public class ExpressionVisitor {
*/ */
public static final int QUERY_COMPARABLE = 8; public static final int QUERY_COMPARABLE = 8;
/**
* Get all referenced columns for the optimiser.
*/
public static final int GET_COLUMNS1 = 9;
/** /**
* Get all referenced columns. * Get all referenced columns.
*/ */
public static final int GET_COLUMNS = 9; public static final int GET_COLUMNS2 = 10;
/** /**
* The visitor singleton for the type QUERY_COMPARABLE. * The visitor singleton for the type QUERY_COMPARABLE.
...@@ -109,30 +115,34 @@ public class ExpressionVisitor { ...@@ -109,30 +115,34 @@ public class ExpressionVisitor {
private final int type; private final int type;
private final int queryLevel; private final int queryLevel;
private final HashSet<DbObject> dependencies; private final HashSet<DbObject> dependencies;
private final HashSet<Column> columns; private final AllColumnsForPlan columns1;
private final Table table; private final Table table;
private final long[] maxDataModificationId; private final long[] maxDataModificationId;
private final ColumnResolver resolver; private final ColumnResolver resolver;
private final HashSet<Column> columns2;
private ExpressionVisitor(int type, private ExpressionVisitor(int type,
int queryLevel, int queryLevel,
HashSet<DbObject> dependencies, HashSet<DbObject> dependencies,
HashSet<Column> columns, Table table, ColumnResolver resolver, AllColumnsForPlan columns1, Table table, ColumnResolver resolver,
long[] maxDataModificationId) { long[] maxDataModificationId,
HashSet<Column> columns2) {
this.type = type; this.type = type;
this.queryLevel = queryLevel; this.queryLevel = queryLevel;
this.dependencies = dependencies; this.dependencies = dependencies;
this.columns = columns; this.columns1 = columns1;
this.table = table; this.table = table;
this.resolver = resolver; this.resolver = resolver;
this.maxDataModificationId = maxDataModificationId; this.maxDataModificationId = maxDataModificationId;
this.columns2 = columns2;
} }
private ExpressionVisitor(int type) { private ExpressionVisitor(int type) {
this.type = type; this.type = type;
this.queryLevel = 0; this.queryLevel = 0;
this.dependencies = null; this.dependencies = null;
this.columns = null; this.columns1 = null;
this.columns2 = null;
this.table = null; this.table = null;
this.resolver = null; this.resolver = null;
this.maxDataModificationId = null; this.maxDataModificationId = null;
...@@ -147,7 +157,7 @@ public class ExpressionVisitor { ...@@ -147,7 +157,7 @@ public class ExpressionVisitor {
public static ExpressionVisitor getDependenciesVisitor( public static ExpressionVisitor getDependenciesVisitor(
HashSet<DbObject> dependencies) { HashSet<DbObject> dependencies) {
return new ExpressionVisitor(GET_DEPENDENCIES, 0, dependencies, null, return new ExpressionVisitor(GET_DEPENDENCIES, 0, dependencies, null,
null, null, null); null, null, null, null);
} }
/** /**
...@@ -158,7 +168,7 @@ public class ExpressionVisitor { ...@@ -158,7 +168,7 @@ public class ExpressionVisitor {
*/ */
public static ExpressionVisitor getOptimizableVisitor(Table table) { public static ExpressionVisitor getOptimizableVisitor(Table table) {
return new ExpressionVisitor(OPTIMIZABLE_MIN_MAX_COUNT_ALL, 0, null, return new ExpressionVisitor(OPTIMIZABLE_MIN_MAX_COUNT_ALL, 0, null,
null, table, null, null); null, table, null, null, null);
} }
/** /**
...@@ -170,7 +180,17 @@ public class ExpressionVisitor { ...@@ -170,7 +180,17 @@ public class ExpressionVisitor {
*/ */
static ExpressionVisitor getNotFromResolverVisitor(ColumnResolver resolver) { static ExpressionVisitor getNotFromResolverVisitor(ColumnResolver resolver) {
return new ExpressionVisitor(NOT_FROM_RESOLVER, 0, null, null, null, return new ExpressionVisitor(NOT_FROM_RESOLVER, 0, null, null, null,
resolver, null); resolver, null, null);
}
/**
* Create a new visitor to get all referenced columns.
*
* @param columns the columns map
* @return the new visitor
*/
public static ExpressionVisitor getColumnsVisitor(AllColumnsForPlan columns) {
return new ExpressionVisitor(GET_COLUMNS1, 0, null, columns, null, null, null, null);
} }
/** /**
...@@ -180,12 +200,12 @@ public class ExpressionVisitor { ...@@ -180,12 +200,12 @@ public class ExpressionVisitor {
* @return the new visitor * @return the new visitor
*/ */
public static ExpressionVisitor getColumnsVisitor(HashSet<Column> columns) { public static ExpressionVisitor getColumnsVisitor(HashSet<Column> columns) {
return new ExpressionVisitor(GET_COLUMNS, 0, null, columns, null, null, null); return new ExpressionVisitor(GET_COLUMNS2, 0, null, null, null, null, null, columns);
} }
public static ExpressionVisitor getMaxModificationIdVisitor() { public static ExpressionVisitor getMaxModificationIdVisitor() {
return new ExpressionVisitor(SET_MAX_DATA_MODIFICATION_ID, 0, null, return new ExpressionVisitor(SET_MAX_DATA_MODIFICATION_ID, 0, null,
null, null, null, new long[1]); null, null, null, new long[1], null);
} }
/** /**
...@@ -204,8 +224,11 @@ public class ExpressionVisitor { ...@@ -204,8 +224,11 @@ public class ExpressionVisitor {
* *
* @param column the additional column. * @param column the additional column.
*/ */
void addColumn(Column column) { void addColumn1(Column column) {
columns.add(column); columns1.add(column);
}
void addColumn2(Column column) {
columns2.add(column);
} }
/** /**
...@@ -226,7 +249,7 @@ public class ExpressionVisitor { ...@@ -226,7 +249,7 @@ public class ExpressionVisitor {
*/ */
public ExpressionVisitor incrementQueryLevel(int offset) { public ExpressionVisitor incrementQueryLevel(int offset) {
return new ExpressionVisitor(type, queryLevel + offset, dependencies, return new ExpressionVisitor(type, queryLevel + offset, dependencies,
columns, table, resolver, maxDataModificationId); columns1, table, resolver, maxDataModificationId, columns2);
} }
/** /**
...@@ -290,16 +313,13 @@ public class ExpressionVisitor { ...@@ -290,16 +313,13 @@ public class ExpressionVisitor {
* Get the set of columns of all tables. * Get the set of columns of all tables.
* *
* @param filters the filters * @param filters the filters
* @return the set of columns
*/ */
public static HashSet<Column> allColumnsForTableFilters(TableFilter[] filters) { public static void allColumnsForTableFilters(TableFilter[] filters, AllColumnsForPlan allColumnsSet) {
HashSet<Column> allColumnsSet = new HashSet<>();
for (TableFilter filter : filters) { for (TableFilter filter : filters) {
if (filter.getSelect() != null) { if (filter.getSelect() != null) {
filter.getSelect().isEverything(ExpressionVisitor.getColumnsVisitor(allColumnsSet)); filter.getSelect().isEverything(ExpressionVisitor.getColumnsVisitor(allColumnsSet));
} }
} }
return allColumnsSet;
} }
} }
...@@ -2649,7 +2649,8 @@ public class Function extends Expression implements FunctionCall { ...@@ -2649,7 +2649,8 @@ public class Function extends Expression implements FunctionCall {
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
case ExpressionVisitor.GET_COLUMNS: case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
return true; return true;
default: default:
throw DbException.throwInternalError("type=" + visitor.getType()); throw DbException.throwInternalError("type=" + visitor.getType());
......
...@@ -159,7 +159,8 @@ public class Parameter extends Expression implements ParameterInterface { ...@@ -159,7 +159,8 @@ public class Parameter extends Expression implements ParameterInterface {
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
case ExpressionVisitor.DETERMINISTIC: case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY: case ExpressionVisitor.READONLY:
case ExpressionVisitor.GET_COLUMNS: case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
return true; return true;
case ExpressionVisitor.INDEPENDENT: case ExpressionVisitor.INDEPENDENT:
return value != null; return value != null;
......
...@@ -90,7 +90,8 @@ public class Rownum extends Expression { ...@@ -90,7 +90,8 @@ public class Rownum extends Expression {
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
case ExpressionVisitor.GET_DEPENDENCIES: case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID: case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
case ExpressionVisitor.GET_COLUMNS: case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
// if everything else is the same, the rownum is the same // if everything else is the same, the rownum is the same
return true; return true;
default: default:
......
...@@ -83,7 +83,8 @@ public class SequenceValue extends Expression { ...@@ -83,7 +83,8 @@ public class SequenceValue extends Expression {
case ExpressionVisitor.EVALUATABLE: case ExpressionVisitor.EVALUATABLE:
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL: case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
case ExpressionVisitor.GET_COLUMNS: case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
return true; return true;
case ExpressionVisitor.DETERMINISTIC: case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY: case ExpressionVisitor.READONLY:
......
...@@ -159,7 +159,8 @@ public class ValueExpression extends Expression { ...@@ -159,7 +159,8 @@ public class ValueExpression extends Expression {
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
case ExpressionVisitor.GET_DEPENDENCIES: case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.QUERY_COMPARABLE: case ExpressionVisitor.QUERY_COMPARABLE:
case ExpressionVisitor.GET_COLUMNS: case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
return true; return true;
default: default:
throw DbException.throwInternalError("type=" + visitor.getType()); throw DbException.throwInternalError("type=" + visitor.getType());
......
...@@ -75,7 +75,8 @@ public class Variable extends Expression { ...@@ -75,7 +75,8 @@ public class Variable extends Expression {
case ExpressionVisitor.NOT_FROM_RESOLVER: case ExpressionVisitor.NOT_FROM_RESOLVER:
case ExpressionVisitor.QUERY_COMPARABLE: case ExpressionVisitor.QUERY_COMPARABLE:
case ExpressionVisitor.GET_DEPENDENCIES: case ExpressionVisitor.GET_DEPENDENCIES:
case ExpressionVisitor.GET_COLUMNS: case ExpressionVisitor.GET_COLUMNS1:
case ExpressionVisitor.GET_COLUMNS2:
return true; return true;
case ExpressionVisitor.DETERMINISTIC: case ExpressionVisitor.DETERMINISTIC:
return false; return false;
......
...@@ -5,8 +5,9 @@ ...@@ -5,8 +5,9 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet; import java.util.ArrayList;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -163,7 +164,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index { ...@@ -163,7 +164,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
*/ */
protected final long getCostRangeIndex(int[] masks, long rowCount, protected final long getCostRangeIndex(int[] masks, long rowCount,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
boolean isScanIndex, HashSet<Column> allColumnsSet) { boolean isScanIndex, AllColumnsForPlan allColumnsSet) {
rowCount += Constants.COST_ROW_OFFSET; rowCount += Constants.COST_ROW_OFFSET;
int totalSelectivity = 0; int totalSelectivity = 0;
long rowsCost = rowCount; long rowsCost = rowCount;
...@@ -246,10 +247,12 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index { ...@@ -246,10 +247,12 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
// satisfy the query without needing to read from the primary table // satisfy the query without needing to read from the primary table
// (scan index), make that one slightly lower cost. // (scan index), make that one slightly lower cost.
boolean needsToReadFromScanIndex = true; boolean needsToReadFromScanIndex = true;
if (!isScanIndex && allColumnsSet != null && !allColumnsSet.isEmpty()) { if (!isScanIndex && allColumnsSet != null) {
boolean foundAllColumnsWeNeed = true; boolean foundAllColumnsWeNeed = true;
for (Column c : allColumnsSet) { ArrayList<Column> foundCols = allColumnsSet.get(getTable());
if (c.getTable() == getTable()) { if (foundCols != null)
{
for (Column c : foundCols) {
boolean found = false; boolean found = false;
for (Column c2 : columns) { for (Column c2 : columns) {
if (c == c2) { if (c == c2) {
......
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.table.Column;
import org.h2.table.FunctionTable; import org.h2.table.FunctionTable;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
...@@ -61,7 +60,7 @@ public class FunctionIndex extends BaseIndex { ...@@ -61,7 +60,7 @@ public class FunctionIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
if (masks != null) { if (masks != null) {
throw DbException.getUnsupportedException("ALIAS"); throw DbException.getUnsupportedException("ALIAS");
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
...@@ -116,7 +116,7 @@ public class HashIndex extends BaseIndex { ...@@ -116,7 +116,7 @@ public class HashIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
for (Column column : columns) { for (Column column : columns) {
int index = column.getColumnId(); int index = column.getColumnId();
int mask = masks[index]; int mask = masks[index];
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
...@@ -98,7 +98,7 @@ public interface Index extends SchemaObject { ...@@ -98,7 +98,7 @@ public interface Index extends SchemaObject {
* @return the estimated cost * @return the estimated cost
*/ */
double getCost(Session session, int[] masks, TableFilter[] filters, int filter, double getCost(Session session, int[] masks, TableFilter[] filters, int filter,
SortOrder sortOrder, HashSet<Column> allColumnsSet); SortOrder sortOrder, AllColumnsForPlan allColumnsSet);
/** /**
* Remove the index. * Remove the index.
......
...@@ -8,7 +8,7 @@ package org.h2.index; ...@@ -8,7 +8,7 @@ package org.h2.index;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
...@@ -144,7 +144,7 @@ public class LinkedIndex extends BaseIndex { ...@@ -144,7 +144,7 @@ public class LinkedIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return 100 + getCostRangeIndex(masks, rowCount + return 100 + getCostRangeIndex(masks, rowCount +
Constants.COST_ROW_OFFSET, filters, filter, sortOrder, false, allColumnsSet); Constants.COST_ROW_OFFSET, filters, filter, sortOrder, false, allColumnsSet);
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
package org.h2.index; package org.h2.index;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
...@@ -55,7 +55,7 @@ public class MetaIndex extends BaseIndex { ...@@ -55,7 +55,7 @@ public class MetaIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
if (scan) { if (scan) {
return 10 * MetaTable.ROW_COUNT_APPROXIMATION; return 10 * MetaTable.ROW_COUNT_APPROXIMATION;
} }
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
package org.h2.index; package org.h2.index;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -148,7 +148,7 @@ public class MultiVersionIndex implements Index { ...@@ -148,7 +148,7 @@ public class MultiVersionIndex implements Index {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return base.getCost(session, masks, filters, filter, sortOrder, allColumnsSet); return base.getCost(session, masks, filters, filter, sortOrder, allColumnsSet);
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
package org.h2.index; package org.h2.index;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
...@@ -133,7 +133,7 @@ public class NonUniqueHashIndex extends BaseIndex { ...@@ -133,7 +133,7 @@ public class NonUniqueHashIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
for (Column column : columns) { for (Column column : columns) {
int index = column.getColumnId(); int index = column.getColumnId();
int mask = masks[index]; int mask = masks[index];
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
...@@ -220,7 +220,7 @@ public class PageBtreeIndex extends PageIndex { ...@@ -220,7 +220,7 @@ public class PageBtreeIndex extends PageIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return 10 * getCostRangeIndex(masks, tableData.getRowCount(session), return 10 * getCostRangeIndex(masks, tableData.getRowCount(session),
filters, filter, sortOrder, false, allColumnsSet); filters, filter, sortOrder, false, allColumnsSet);
} }
......
...@@ -11,6 +11,7 @@ import java.util.HashSet; ...@@ -11,6 +11,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
...@@ -310,7 +311,7 @@ public class PageDataIndex extends PageIndex { ...@@ -310,7 +311,7 @@ public class PageDataIndex extends PageIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return 10 * (tableData.getRowCountApproximation() + return 10 * (tableData.getRowCountApproximation() +
Constants.COST_ROW_OFFSET); Constants.COST_ROW_OFFSET);
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
...@@ -104,7 +104,7 @@ public class PageDelegateIndex extends PageIndex { ...@@ -104,7 +104,7 @@ public class PageDelegateIndex extends PageIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return 10 * getCostRangeIndex(masks, mainIndex.getRowCount(session), return 10 * getCostRangeIndex(masks, mainIndex.getRowCount(session),
filters, filter, sortOrder, false, allColumnsSet); filters, filter, sortOrder, false, allColumnsSet);
} }
......
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.RangeTable; import org.h2.table.RangeTable;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
...@@ -84,7 +83,7 @@ public class RangeIndex extends BaseIndex { ...@@ -84,7 +83,7 @@ public class RangeIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return 1; return 1;
} }
......
...@@ -12,6 +12,7 @@ import java.util.HashSet; ...@@ -12,6 +12,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.UndoLogRecord; import org.h2.engine.UndoLogRecord;
...@@ -175,7 +176,7 @@ public class ScanIndex extends BaseIndex { ...@@ -175,7 +176,7 @@ public class ScanIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return tableData.getRowCountApproximation() + Constants.COST_ROW_OFFSET; return tableData.getRowCountApproximation() + Constants.COST_ROW_OFFSET;
} }
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mvstore.MVStore; import org.h2.mvstore.MVStore;
...@@ -201,7 +201,7 @@ public class SpatialTreeIndex extends BaseIndex implements SpatialIndex { ...@@ -201,7 +201,7 @@ public class SpatialTreeIndex extends BaseIndex implements SpatialIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return getCostRangeIndex(masks, columns); return getCostRangeIndex(masks, columns);
} }
......
...@@ -5,14 +5,13 @@ ...@@ -5,14 +5,13 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.RegularTable; import org.h2.table.RegularTable;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
...@@ -321,7 +320,7 @@ public class TreeIndex extends BaseIndex { ...@@ -321,7 +320,7 @@ public class TreeIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, TableFilter[] filters, int filter, public double getCost(Session session, int[] masks, TableFilter[] filters, int filter,
SortOrder sortOrder, HashSet<Column> allColumnsSet) { SortOrder sortOrder, AllColumnsForPlan allColumnsSet) {
return getCostRangeIndex(masks, tableData.getRowCountApproximation(), return getCostRangeIndex(masks, tableData.getRowCountApproximation(),
filters, filter, sortOrder, false, allColumnsSet); filters, filter, sortOrder, false, allColumnsSet);
} }
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
package org.h2.index; package org.h2.index;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Parser; import org.h2.command.Parser;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.command.dml.Query; import org.h2.command.dml.Query;
import org.h2.command.dml.SelectUnion; import org.h2.command.dml.SelectUnion;
import org.h2.engine.Constants; import org.h2.engine.Constants;
...@@ -151,7 +151,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex { ...@@ -151,7 +151,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return recursive ? 1000 : query.getCost(); return recursive ? 1000 : query.getCost();
} }
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
*/ */
package org.h2.mvstore.db; package org.h2.mvstore.db;
import java.util.HashSet;
import java.util.List; import java.util.List;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.BaseIndex; import org.h2.index.BaseIndex;
import org.h2.index.Cursor; import org.h2.index.Cursor;
...@@ -94,7 +94,7 @@ public class MVDelegateIndex extends BaseIndex implements MVIndex { ...@@ -94,7 +94,7 @@ public class MVDelegateIndex extends BaseIndex implements MVIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return 10 * getCostRangeIndex(masks, mainIndex.getRowCountApproximation(), return 10 * getCostRangeIndex(masks, mainIndex.getRowCountApproximation(),
filters, filter, sortOrder, true, allColumnsSet); filters, filter, sortOrder, true, allColumnsSet);
} }
......
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
package org.h2.mvstore.db; package org.h2.mvstore.db;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.BaseIndex; import org.h2.index.BaseIndex;
...@@ -209,7 +209,7 @@ public class MVPrimaryIndex extends BaseIndex { ...@@ -209,7 +209,7 @@ public class MVPrimaryIndex extends BaseIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
try { try {
return 10 * getCostRangeIndex(masks, dataMap.sizeAsLongMax(), return 10 * getCostRangeIndex(masks, dataMap.sizeAsLongMax(),
filters, filter, sortOrder, true, allColumnsSet); filters, filter, sortOrder, true, allColumnsSet);
......
...@@ -7,12 +7,12 @@ package org.h2.mvstore.db; ...@@ -7,12 +7,12 @@ package org.h2.mvstore.db;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import java.util.Queue; import java.util.Queue;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.BaseIndex; import org.h2.index.BaseIndex;
...@@ -358,7 +358,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex { ...@@ -358,7 +358,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
try { try {
return 10 * getCostRangeIndex(masks, dataMap.sizeAsLongMax(), return 10 * getCostRangeIndex(masks, dataMap.sizeAsLongMax(),
filters, filter, sortOrder, false, allColumnsSet); filters, filter, sortOrder, false, allColumnsSet);
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
*/ */
package org.h2.mvstore.db; package org.h2.mvstore.db;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.BaseIndex; import org.h2.index.BaseIndex;
...@@ -17,16 +17,15 @@ import org.h2.index.IndexType; ...@@ -17,16 +17,15 @@ import org.h2.index.IndexType;
import org.h2.index.SpatialIndex; import org.h2.index.SpatialIndex;
import org.h2.index.SpatialTreeIndex; import org.h2.index.SpatialTreeIndex;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mvstore.tx.Transaction;
import org.h2.mvstore.tx.TransactionMap;
import org.h2.mvstore.tx.VersionedValue;
import org.h2.mvstore.rtree.MVRTreeMap; import org.h2.mvstore.rtree.MVRTreeMap;
import org.h2.mvstore.rtree.MVRTreeMap.RTreeCursor; import org.h2.mvstore.rtree.MVRTreeMap.RTreeCursor;
import org.h2.mvstore.rtree.SpatialKey; import org.h2.mvstore.rtree.SpatialKey;
import org.h2.mvstore.tx.Transaction;
import org.h2.mvstore.tx.TransactionMap;
import org.h2.mvstore.tx.VersionedValue;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -251,7 +250,7 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex { ...@@ -251,7 +250,7 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
@Override @Override
public double getCost(Session session, int[] masks, TableFilter[] filters, public double getCost(Session session, int[] masks, TableFilter[] filters,
int filter, SortOrder sortOrder, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return SpatialTreeIndex.getCostRangeIndex(masks, columns); return SpatialTreeIndex.getCostRangeIndex(masks, columns);
} }
......
...@@ -8,7 +8,7 @@ package org.h2.table; ...@@ -8,7 +8,7 @@ package org.h2.table;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor; import org.h2.expression.ExpressionVisitor;
...@@ -104,15 +104,13 @@ public class Plan { ...@@ -104,15 +104,13 @@ public class Plan {
* @param session the session * @param session the session
* @return the cost * @return the cost
*/ */
public double calculateCost(Session session) { public double calculateCost(Session session, AllColumnsForPlan allColumnsSet) {
Trace t = session.getTrace(); Trace t = session.getTrace();
if (t.isDebugEnabled()) { if (t.isDebugEnabled()) {
t.debug("Plan : calculate cost for plan {0}", Arrays.toString(allFilters)); t.debug("Plan : calculate cost for plan {0}", Arrays.toString(allFilters));
} }
double cost = 1; double cost = 1;
boolean invalidPlan = false; boolean invalidPlan = false;
final HashSet<Column> allColumnsSet = ExpressionVisitor
.allColumnsForTableFilters(allFilters);
for (int i = 0; i < allFilters.length; i++) { for (int i = 0; i < allFilters.length; i++) {
TableFilter tableFilter = allFilters[i]; TableFilter tableFilter = allFilters[i];
if (t.isDebugEnabled()) { if (t.isDebugEnabled()) {
......
...@@ -13,6 +13,7 @@ import java.util.Set; ...@@ -13,6 +13,7 @@ import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.constraint.Constraint; import org.h2.constraint.Constraint;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
...@@ -236,7 +237,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -236,7 +237,7 @@ public abstract class Table extends SchemaObjectBase {
@SuppressWarnings("unused") @SuppressWarnings("unused")
public Index getScanIndex(Session session, int[] masks, public Index getScanIndex(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return getScanIndex(session); return getScanIndex(session);
} }
...@@ -712,7 +713,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -712,7 +713,7 @@ public abstract class Table extends SchemaObjectBase {
*/ */
public PlanItem getBestPlanItem(Session session, int[] masks, public PlanItem getBestPlanItem(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
PlanItem item = new PlanItem(); PlanItem item = new PlanItem();
item.setIndex(getScanIndex(session)); item.setIndex(getScanIndex(session));
item.cost = item.getIndex().getCost(session, null, filters, filter, null, allColumnsSet); item.cost = item.getIndex().getCost(session, null, filters, filter, null, allColumnsSet);
......
...@@ -7,9 +7,9 @@ package org.h2.table; ...@@ -7,9 +7,9 @@ package org.h2.table;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Parser; import org.h2.command.Parser;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.command.dml.Select; import org.h2.command.dml.Select;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -194,7 +194,7 @@ public class TableFilter implements ColumnResolver { ...@@ -194,7 +194,7 @@ public class TableFilter implements ColumnResolver {
* @return the best plan item * @return the best plan item
*/ */
public PlanItem getBestPlanItem(Session s, TableFilter[] filters, int filter, public PlanItem getBestPlanItem(Session s, TableFilter[] filters, int filter,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
PlanItem item1 = null; PlanItem item1 = null;
SortOrder sortOrder = null; SortOrder sortOrder = null;
if (select != null) { if (select != null) {
......
...@@ -13,6 +13,7 @@ import java.util.Map; ...@@ -13,6 +13,7 @@ import java.util.Map;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.command.dml.Query; import org.h2.command.dml.Query;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
...@@ -268,7 +269,7 @@ public class TableView extends Table { ...@@ -268,7 +269,7 @@ public class TableView extends Table {
@Override @Override
public PlanItem getBestPlanItem(Session session, int[] masks, public PlanItem getBestPlanItem(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
final CacheKey cacheKey = new CacheKey(masks, this); final CacheKey cacheKey = new CacheKey(masks, this);
Map<Object, ViewIndex> indexCache = session.getViewIndexCache(topQuery != null); Map<Object, ViewIndex> indexCache = session.getViewIndexCache(topQuery != null);
ViewIndex i = indexCache.get(cacheKey); ViewIndex i = indexCache.get(cacheKey);
...@@ -481,7 +482,7 @@ public class TableView extends Table { ...@@ -481,7 +482,7 @@ public class TableView extends Table {
@Override @Override
public Index getScanIndex(Session session, int[] masks, public Index getScanIndex(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
if (createException != null) { if (createException != null) {
String msg = createException.getMessage(); String msg = createException.getMessage();
throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, throw DbException.get(ErrorCode.VIEW_IS_INVALID_2,
......
...@@ -348,7 +348,7 @@ public class Profiler implements Runnable { ...@@ -348,7 +348,7 @@ public class Profiler implements Runnable {
return; return;
} }
try { try {
Thread.sleep(interval); Thread.sleep(interval, 0);
} catch (Exception e) { } catch (Exception e) {
// ignore // ignore
} }
......
...@@ -64,8 +64,8 @@ public class TestSelectCountNonNullColumn extends TestBase { ...@@ -64,8 +64,8 @@ public class TestSelectCountNonNullColumn extends TestBase {
assertEquals(expect, rs.getLong(1)); assertEquals(expect, rs.getLong(1));
} else { } else {
// System.out.println(rs.getString(1)); // System.out.println(rs.getString(1));
assertEquals("SELECT\n" + " COUNT(*)\n" + "FROM PUBLIC.SIMPLE\n" assertEquals("SELECT\n COUNT(*)\nFROM PUBLIC.SIMPLE\n"
+ " /* PUBLIC.SIMPLE.tableScan */\n" + " /* PUBLIC.PRIMARY_KEY_9 */\n"
+ "/* direct lookup */", rs.getString(1)); + "/* direct lookup */", rs.getString(1));
} }
} }
......
...@@ -14,7 +14,6 @@ import java.util.ArrayList; ...@@ -14,7 +14,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
...@@ -28,6 +27,7 @@ import java.util.concurrent.ThreadFactory; ...@@ -28,6 +27,7 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.h2.api.TableEngine; import org.h2.api.TableEngine;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
import org.h2.command.dml.AllColumnsForPlan;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.index.BaseIndex; import org.h2.index.BaseIndex;
...@@ -41,7 +41,13 @@ import org.h2.message.DbException; ...@@ -41,7 +41,13 @@ import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.table.*; import org.h2.table.IndexColumn;
import org.h2.table.RegularTable;
import org.h2.table.SubQueryInfo;
import org.h2.table.Table;
import org.h2.table.TableBase;
import org.h2.table.TableFilter;
import org.h2.table.TableType;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.DoneFuture; import org.h2.util.DoneFuture;
import org.h2.util.New; import org.h2.util.New;
...@@ -950,7 +956,7 @@ public class TestTableEngines extends TestBase { ...@@ -950,7 +956,7 @@ public class TestTableEngines extends TestBase {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return 0; return 0;
} }
...@@ -1174,7 +1180,7 @@ public class TestTableEngines extends TestBase { ...@@ -1174,7 +1180,7 @@ public class TestTableEngines extends TestBase {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
return 0; return 0;
} }
...@@ -1345,7 +1351,7 @@ public class TestTableEngines extends TestBase { ...@@ -1345,7 +1351,7 @@ public class TestTableEngines extends TestBase {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
doTests(session); doTests(session);
return getCostRangeIndex(masks, getRowCount(session), filters, return getCostRangeIndex(masks, getRowCount(session), filters,
filter, sortOrder, true, allColumnsSet); filter, sortOrder, true, allColumnsSet);
...@@ -1695,7 +1701,7 @@ public class TestTableEngines extends TestBase { ...@@ -1695,7 +1701,7 @@ public class TestTableEngines extends TestBase {
@Override @Override
public double getCost(Session session, int[] masks, public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) { AllColumnsForPlan allColumnsSet) {
doTests(session); doTests(session);
return getCostRangeIndex(masks, set.size(), filters, filter, return getCostRangeIndex(masks, set.size(), filters, filter,
sortOrder, false, allColumnsSet); sortOrder, false, allColumnsSet);
......
...@@ -86,6 +86,7 @@ public class TestScript extends TestBase { ...@@ -86,6 +86,7 @@ public class TestScript extends TestBase {
testScript("testScript.sql"); testScript("testScript.sql");
testScript("derived-column-names.sql"); testScript("derived-column-names.sql");
testScript("indexes.sql");
testScript("information_schema.sql"); testScript("information_schema.sql");
if (config.mvStore) { if (config.mvStore) {
// we get slightly different explain plan stuff here in PageStore mode // we get slightly different explain plan stuff here in PageStore mode
......
-- Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
-- Test all possible order modes
CREATE TABLE TEST(A INT);
> ok
INSERT INTO TEST VALUES (NULL), (0), (1);
> update count: 3
-- default
SELECT A FROM TEST ORDER BY A;
> A
> ----
> null
> 0
> 1
> rows (ordered): 3
CREATE INDEX A_IDX ON TEST(A);
> ok
SELECT A FROM TEST ORDER BY A;
> A
> ----
> null
> 0
> 1
> rows (ordered): 3
EXPLAIN SELECT A FROM TEST ORDER BY A;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX */ ORDER BY 1 /* index sorted */
DROP INDEX A_IDX;
> ok
-- ASC
SELECT A FROM TEST ORDER BY A ASC;
> A
> ----
> null
> 0
> 1
> rows (ordered): 3
CREATE INDEX A_IDX ON TEST(A ASC);
> ok
SELECT A FROM TEST ORDER BY A ASC;
> A
> ----
> null
> 0
> 1
> rows (ordered): 3
EXPLAIN SELECT A FROM TEST ORDER BY A ASC;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX */ ORDER BY 1 /* index sorted */
DROP INDEX A_IDX;
> ok
-- ASC NULLS FIRST
SELECT A FROM TEST ORDER BY A ASC NULLS FIRST;
> A
> ----
> null
> 0
> 1
> rows (ordered): 3
CREATE INDEX A_IDX ON TEST(A ASC NULLS FIRST);
> ok
SELECT A FROM TEST ORDER BY A ASC NULLS FIRST;
> A
> ----
> null
> 0
> 1
> rows (ordered): 3
EXPLAIN SELECT A FROM TEST ORDER BY A ASC NULLS FIRST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX */ ORDER BY 1 NULLS FIRST /* index sorted */
DROP INDEX A_IDX;
> ok
-- ASC NULLS LAST
SELECT A FROM TEST ORDER BY A ASC NULLS LAST;
> A
> ----
> 0
> 1
> null
> rows (ordered): 3
CREATE INDEX A_IDX ON TEST(A ASC NULLS LAST);
> ok
SELECT A FROM TEST ORDER BY A ASC NULLS LAST;
> A
> ----
> 0
> 1
> null
> rows (ordered): 3
EXPLAIN SELECT A FROM TEST ORDER BY A ASC NULLS LAST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX */ ORDER BY 1 NULLS LAST /* index sorted */
DROP INDEX A_IDX;
> ok
-- DESC
SELECT A FROM TEST ORDER BY A DESC;
> A
> ----
> 1
> 0
> null
> rows (ordered): 3
CREATE INDEX A_IDX ON TEST(A DESC);
> ok
SELECT A FROM TEST ORDER BY A DESC;
> A
> ----
> 1
> 0
> null
> rows (ordered): 3
EXPLAIN SELECT A FROM TEST ORDER BY A DESC;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX */ ORDER BY 1 DESC /* index sorted */
DROP INDEX A_IDX;
> ok
-- DESC NULLS FIRST
SELECT A FROM TEST ORDER BY A DESC NULLS FIRST;
> A
> ----
> null
> 1
> 0
> rows (ordered): 3
CREATE INDEX A_IDX ON TEST(A DESC NULLS FIRST);
> ok
SELECT A FROM TEST ORDER BY A DESC NULLS FIRST;
> A
> ----
> null
> 1
> 0
> rows (ordered): 3
EXPLAIN SELECT A FROM TEST ORDER BY A DESC NULLS FIRST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX */ ORDER BY 1 DESC NULLS FIRST /* index sorted */
DROP INDEX A_IDX;
> ok
-- DESC NULLS LAST
SELECT A FROM TEST ORDER BY A DESC NULLS LAST;
> A
> ----
> 1
> 0
> null
> rows (ordered): 3
CREATE INDEX A_IDX ON TEST(A DESC NULLS LAST);
> ok
SELECT A FROM TEST ORDER BY A DESC NULLS LAST;
> A
> ----
> 1
> 0
> null
> rows (ordered): 3
EXPLAIN SELECT A FROM TEST ORDER BY A DESC NULLS LAST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX */ ORDER BY 1 DESC NULLS LAST /* index sorted */
DROP INDEX A_IDX;
> ok
-- Index selection
CREATE INDEX A_IDX_ASC ON TEST(A ASC);
> ok
CREATE INDEX A_IDX_ASC_NL ON TEST(A ASC NULLS LAST);
> ok
CREATE INDEX A_IDX_DESC ON TEST(A DESC);
> ok
CREATE INDEX A_IDX_DESC_NF ON TEST(A DESC NULLS FIRST);
> ok
EXPLAIN SELECT A FROM TEST ORDER BY A;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_ASC */ ORDER BY 1 /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A ASC;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_ASC */ ORDER BY 1 /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A NULLS FIRST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_ASC */ ORDER BY 1 NULLS FIRST /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A NULLS LAST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_ASC_NL */ ORDER BY 1 NULLS LAST /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A DESC;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_DESC */ ORDER BY 1 DESC /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A DESC NULLS FIRST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_DESC_NF */ ORDER BY 1 DESC NULLS FIRST /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A DESC NULLS LAST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_DESC */ ORDER BY 1 DESC NULLS LAST /* index sorted */
DROP INDEX A_IDX_ASC;
> ok
DROP INDEX A_IDX_DESC;
> ok
CREATE INDEX A_IDX_ASC_NF ON TEST(A ASC NULLS FIRST);
> ok
CREATE INDEX A_IDX_DESC_NL ON TEST(A DESC NULLS LAST);
> ok
EXPLAIN SELECT A FROM TEST ORDER BY A;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_ASC_NF */ ORDER BY 1 /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A ASC;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_ASC_NF */ ORDER BY 1 /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A NULLS FIRST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_ASC_NF */ ORDER BY 1 NULLS FIRST /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A NULLS LAST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_ASC_NL */ ORDER BY 1 NULLS LAST /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A DESC;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_DESC_NL */ ORDER BY 1 DESC /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A DESC NULLS FIRST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_DESC_NF */ ORDER BY 1 DESC NULLS FIRST /* index sorted */
EXPLAIN SELECT A FROM TEST ORDER BY A DESC NULLS LAST;
>> SELECT A FROM PUBLIC.TEST /* PUBLIC.A_IDX_DESC_NL */ ORDER BY 1 DESC NULLS LAST /* index sorted */
DROP TABLE TEST;
> ok
-- Other tests
create table test(a int, b int);
> ok
insert into test values(1, 1);
> update count: 1
create index on test(a, b desc);
> ok
select * from test where a = 1;
> A B
> - -
> 1 1
> rows: 1
drop table test;
> ok
create table test(x int);
> ok
create hash index on test(x);
> ok
select 1 from test group by x;
> 1
> -
> rows: 0
drop table test;
> ok
...@@ -90,24 +90,6 @@ AND studentID = 2; ...@@ -90,24 +90,6 @@ AND studentID = 2;
drop table results; drop table results;
> ok > ok
create table test(a int, b int);
> ok
insert into test values(1, 1);
> update count: 1
create index on test(a, b desc);
> ok
select * from test where a = 1;
> A B
> - -
> 1 1
> rows: 1
drop table test;
> ok
create table test(id int, name varchar) as select 1, 'a'; create table test(id int, name varchar) as select 1, 'a';
> ok > ok
...@@ -132,20 +114,6 @@ select case seq.nextval when 2 then 'two' when 3 then 'three' when 1 then 'one' ...@@ -132,20 +114,6 @@ select case seq.nextval when 2 then 'two' when 3 then 'three' when 1 then 'one'
drop sequence seq; drop sequence seq;
> ok > ok
create table test(x int);
> ok
create hash index on test(x);
> ok
select 1 from test group by x;
> 1
> -
> rows: 0
drop table test;
> ok
select * from dual where x = x + 1 or x in(2, 0); select * from dual where x = x + 1 or x in(2, 0);
> X > X
> - > -
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论