Search in sources :

Example 41 with TableFilter

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);
        }
    }
}
Also used : TableFilter(org.h2.table.TableFilter) BitSet(java.util.BitSet)

Example 42 with TableFilter

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();
    }
}
Also used : ValueExpression(org.h2.expression.ValueExpression) Expression(org.h2.expression.Expression) TableFilter(org.h2.table.TableFilter) Alias(org.h2.expression.Alias) Database(org.h2.engine.Database) ExpressionColumn(org.h2.expression.ExpressionColumn)

Example 43 with TableFilter

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;
}
Also used : Database(org.h2.engine.Database)

Example 44 with TableFilter

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();
}
Also used : Column(org.h2.table.Column) ValueExpression(org.h2.expression.ValueExpression) Expression(org.h2.expression.Expression) TableFilter(org.h2.table.TableFilter) PlanItem(org.h2.table.PlanItem)

Example 45 with TableFilter

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;
                }
            }
        }
    }
}
Also used : Value(org.h2.value.Value) ValueString(org.h2.value.ValueString)

Aggregations

TableFilter (org.h2.table.TableFilter)39 IndexColumn (org.h2.table.IndexColumn)21 Column (org.h2.table.Column)20 Expression (org.h2.expression.Expression)18 ValueExpression (org.h2.expression.ValueExpression)14 ExpressionColumn (org.h2.expression.ExpressionColumn)12 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)11 Table (org.h2.table.Table)11 AlterTableDropConstraint (org.h2.command.ddl.AlterTableDropConstraint)9 AlterTableRenameConstraint (org.h2.command.ddl.AlterTableRenameConstraint)9 Select (org.h2.command.dml.Select)9 ValueString (org.h2.value.ValueString)9 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)6 AlterTableRenameColumn (org.h2.command.ddl.AlterTableRenameColumn)6 CreateTable (org.h2.command.ddl.CreateTable)6 DropTable (org.h2.command.ddl.DropTable)6 Query (org.h2.command.dml.Query)6 IndexCondition (org.h2.index.IndexCondition)6 ArrayList (java.util.ArrayList)5 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)5