use of org.h2.table.TableFilter in project h2database by h2database.
the class Optimizer method calculateGenetic.
private void calculateGenetic() {
TableFilter[] best = new TableFilter[filters.length];
TableFilter[] list = new TableFilter[filters.length];
for (int x = 0; x < MAX_GENETIC; x++) {
if (canStop(x)) {
break;
}
boolean generateRandom = (x & 127) == 0;
if (!generateRandom) {
System.arraycopy(best, 0, list, 0, filters.length);
if (!shuffleTwo(list)) {
generateRandom = true;
}
}
if (generateRandom) {
switched = new BitSet();
System.arraycopy(filters, 0, best, 0, filters.length);
shuffleAll(best);
System.arraycopy(best, 0, list, 0, filters.length);
}
if (testPlan(list)) {
switched = new BitSet();
System.arraycopy(list, 0, best, 0, filters.length);
}
}
}
use of org.h2.table.TableFilter in project h2database by h2database.
the class Query method initOrder.
/**
* Initialize the order by list. This call may extend the expressions list.
*
* @param session the session
* @param expressions the select list expressions
* @param expressionSQL the select list SQL snippets
* @param orderList the order by list
* @param visible the number of visible columns in the select list
* @param mustBeInResult all order by expressions must be in the select list
* @param filters the table filters
*/
static void initOrder(Session session, ArrayList<Expression> expressions, ArrayList<String> expressionSQL, ArrayList<SelectOrderBy> orderList, int visible, boolean mustBeInResult, ArrayList<TableFilter> filters) {
Database db = session.getDatabase();
for (SelectOrderBy o : orderList) {
Expression e = o.expression;
if (e == null) {
continue;
}
// special case: SELECT 1 AS A FROM DUAL ORDER BY A
// (oracle supports it, but only in order by, not in group by and
// not in having):
// SELECT 1 AS A FROM DUAL ORDER BY -A
boolean isAlias = false;
int idx = expressions.size();
if (e instanceof ExpressionColumn) {
// order by expression
ExpressionColumn exprCol = (ExpressionColumn) e;
String tableAlias = exprCol.getOriginalTableAliasName();
String col = exprCol.getOriginalColumnName();
for (int j = 0; j < visible; j++) {
boolean found = false;
Expression ec = expressions.get(j);
if (ec instanceof ExpressionColumn) {
// select expression
ExpressionColumn c = (ExpressionColumn) ec;
found = db.equalsIdentifiers(col, c.getColumnName());
if (found && tableAlias != null) {
String ca = c.getOriginalTableAliasName();
if (ca == null) {
found = false;
if (filters != null) {
// select id from test order by test.id
for (TableFilter f : filters) {
if (db.equalsIdentifiers(f.getTableAlias(), tableAlias)) {
found = true;
break;
}
}
}
} else {
found = db.equalsIdentifiers(ca, tableAlias);
}
}
} else if (!(ec instanceof Alias)) {
continue;
} else if (tableAlias == null && db.equalsIdentifiers(col, ec.getAlias())) {
found = true;
} else {
Expression ec2 = ec.getNonAliasExpression();
if (ec2 instanceof ExpressionColumn) {
ExpressionColumn c2 = (ExpressionColumn) ec2;
String ta = exprCol.getSQL();
String tb = c2.getSQL();
String s2 = c2.getColumnName();
found = db.equalsIdentifiers(col, s2);
if (!db.equalsIdentifiers(ta, tb)) {
found = false;
}
}
}
if (found) {
idx = j;
isAlias = true;
break;
}
}
} else {
String s = e.getSQL();
if (expressionSQL != null) {
for (int j = 0, size = expressionSQL.size(); j < size; j++) {
String s2 = expressionSQL.get(j);
if (db.equalsIdentifiers(s2, s)) {
idx = j;
isAlias = true;
break;
}
}
}
}
if (!isAlias) {
if (mustBeInResult) {
throw DbException.get(ErrorCode.ORDER_BY_NOT_IN_RESULT, e.getSQL());
}
expressions.add(e);
String sql = e.getSQL();
expressionSQL.add(sql);
}
o.columnIndexExpr = ValueExpression.get(ValueInt.get(idx + 1));
o.expression = expressions.get(idx).getNonAliasExpression();
}
}
use of org.h2.table.TableFilter in project h2database by h2database.
the class Select method init.
@Override
public void init() {
if (SysProperties.CHECK && checkInit) {
DbException.throwInternalError();
}
expandColumnList();
visibleColumnCount = expressions.size();
ArrayList<String> expressionSQL;
if (orderList != null || group != null) {
expressionSQL = New.arrayList();
for (int i = 0; i < visibleColumnCount; i++) {
Expression expr = expressions.get(i);
expr = expr.getNonAliasExpression();
String sql = expr.getSQL();
expressionSQL.add(sql);
}
} else {
expressionSQL = null;
}
if (orderList != null) {
initOrder(session, expressions, expressionSQL, orderList, visibleColumnCount, distinct, filters);
}
distinctColumnCount = expressions.size();
if (having != null) {
expressions.add(having);
havingIndex = expressions.size() - 1;
having = null;
} else {
havingIndex = -1;
}
Database db = session.getDatabase();
// and 'GROUP BY' expressions at the end
if (group != null) {
int size = group.size();
int expSize = expressionSQL.size();
groupIndex = new int[size];
for (int i = 0; i < size; i++) {
Expression expr = group.get(i);
String sql = expr.getSQL();
int found = -1;
for (int j = 0; j < expSize; j++) {
String s2 = expressionSQL.get(j);
if (db.equalsIdentifiers(s2, sql)) {
found = j;
break;
}
}
if (found < 0) {
// special case: GROUP BY a column alias
for (int j = 0; j < expSize; j++) {
Expression e = expressions.get(j);
if (db.equalsIdentifiers(sql, e.getAlias())) {
found = j;
break;
}
sql = expr.getAlias();
if (db.equalsIdentifiers(sql, e.getAlias())) {
found = j;
break;
}
}
}
if (found < 0) {
int index = expressions.size();
groupIndex[i] = index;
expressions.add(expr);
} else {
groupIndex[i] = found;
}
}
groupByExpression = new boolean[expressions.size()];
for (int gi : groupIndex) {
groupByExpression[gi] = true;
}
group = null;
}
// map columns in select list and condition
for (TableFilter f : filters) {
mapColumns(f, 0);
}
if (havingIndex >= 0) {
Expression expr = expressions.get(havingIndex);
SelectListColumnResolver res = new SelectListColumnResolver(this);
expr.mapColumns(res, 0);
}
checkInit = true;
}
use of org.h2.table.TableFilter in project h2database by h2database.
the class Update method prepare.
@Override
public void prepare() {
if (condition != null) {
condition.mapColumns(targetTableFilter, 0);
condition = condition.optimize(session);
condition.createIndexConditions(session, targetTableFilter);
}
for (Column c : columns) {
Expression e = expressionMap.get(c);
e.mapColumns(targetTableFilter, 0);
if (sourceTableFilter != null) {
e.mapColumns(sourceTableFilter, 0);
}
expressionMap.put(c, e.optimize(session));
}
TableFilter[] filters;
if (sourceTableFilter == null) {
filters = new TableFilter[] { targetTableFilter };
} else {
filters = new TableFilter[] { targetTableFilter, sourceTableFilter };
}
PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0, ExpressionVisitor.allColumnsForTableFilters(filters));
targetTableFilter.setPlanItem(item);
targetTableFilter.prepare();
}
use of org.h2.table.TableFilter in project h2database by h2database.
the class CompareLike method createIndexConditions.
@Override
public void createIndexConditions(Session session, TableFilter filter) {
if (regexp) {
return;
}
if (!(left instanceof ExpressionColumn)) {
return;
}
ExpressionColumn l = (ExpressionColumn) left;
if (filter != l.getTableFilter()) {
return;
}
// which may be slower (possibly not in this case)
if (!right.isEverything(ExpressionVisitor.INDEPENDENT_VISITOR)) {
return;
}
if (escape != null && !escape.isEverything(ExpressionVisitor.INDEPENDENT_VISITOR)) {
return;
}
String p = right.getValue(session).getString();
if (!isInit) {
Value e = escape == null ? null : escape.getValue(session);
if (e == ValueNull.INSTANCE) {
// should already be optimized
DbException.throwInternalError();
}
initPattern(p, getEscapeChar(e));
}
if (invalidPattern) {
return;
}
if (patternLength <= 0 || patternTypes[0] != MATCH) {
// can't use an index
return;
}
int dataType = l.getColumn().getType();
if (dataType != Value.STRING && dataType != Value.STRING_IGNORECASE && dataType != Value.STRING_FIXED) {
// column is not a varchar - can't use the index
return;
}
// Get the MATCH prefix and see if we can create an index condition from
// that.
int maxMatch = 0;
StringBuilder buff = new StringBuilder();
while (maxMatch < patternLength && patternTypes[maxMatch] == MATCH) {
buff.append(patternChars[maxMatch++]);
}
String begin = buff.toString();
if (maxMatch == patternLength) {
filter.addIndexCondition(IndexCondition.get(Comparison.EQUAL, l, ValueExpression.get(ValueString.get(begin))));
} else {
// TODO check if this is correct according to Unicode rules
// (code points)
String end;
if (begin.length() > 0) {
filter.addIndexCondition(IndexCondition.get(Comparison.BIGGER_EQUAL, l, ValueExpression.get(ValueString.get(begin))));
char next = begin.charAt(begin.length() - 1);
// that is higher)
for (int i = 1; i < 2000; i++) {
end = begin.substring(0, begin.length() - 1) + (char) (next + i);
if (compareMode.compareString(begin, end, ignoreCase) == -1) {
filter.addIndexCondition(IndexCondition.get(Comparison.SMALLER, l, ValueExpression.get(ValueString.get(end))));
break;
}
}
}
}
}
Aggregations