Search in sources :

Example 21 with ExpressionColumn

use of org.h2.expression.ExpressionColumn 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 22 with ExpressionColumn

use of org.h2.expression.ExpressionColumn in project h2database by h2database.

the class SelectUnion method prepare.

@Override
public void prepare() {
    if (isPrepared) {
        // sometimes a subquery is prepared twice (CREATE TABLE AS SELECT)
        return;
    }
    if (SysProperties.CHECK && !checkInit) {
        DbException.throwInternalError("not initialized");
    }
    isPrepared = true;
    left.prepare();
    right.prepare();
    int len = left.getColumnCount();
    // set the correct expressions now
    expressions = New.arrayList();
    ArrayList<Expression> le = left.getExpressions();
    ArrayList<Expression> re = right.getExpressions();
    ColumnNamer columnNamer = new ColumnNamer(session);
    for (int i = 0; i < len; i++) {
        Expression l = le.get(i);
        Expression r = re.get(i);
        int type = Value.getHigherOrder(l.getType(), r.getType());
        long prec = Math.max(l.getPrecision(), r.getPrecision());
        int scale = Math.max(l.getScale(), r.getScale());
        int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
        String columnName = columnNamer.getColumnName(l, i, l.getAlias());
        Column col = new Column(columnName, type, prec, scale, displaySize);
        Expression e = new ExpressionColumn(session.getDatabase(), col);
        expressions.add(e);
    }
    if (orderList != null) {
        initOrder(session, expressions, null, orderList, getColumnCount(), true, null);
        sort = prepareOrder(orderList, expressions.size());
        orderList = null;
    }
    expressionArray = expressions.toArray(new Expression[0]);
}
Also used : ColumnNamer(org.h2.util.ColumnNamer) ValueExpression(org.h2.expression.ValueExpression) Expression(org.h2.expression.Expression) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) ExpressionColumn(org.h2.expression.ExpressionColumn)

Example 23 with ExpressionColumn

use of org.h2.expression.ExpressionColumn 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)

Example 24 with ExpressionColumn

use of org.h2.expression.ExpressionColumn in project h2database by h2database.

the class Comparison method optimize.

@Override
public Expression optimize(Session session) {
    left = left.optimize(session);
    if (right != null) {
        right = right.optimize(session);
        if (right instanceof ExpressionColumn) {
            if (left.isConstant() || left instanceof Parameter) {
                Expression temp = left;
                left = right;
                right = temp;
                compareType = getReversedCompareType(compareType);
            }
        }
        if (left instanceof ExpressionColumn) {
            if (right.isConstant()) {
                Value r = right.getValue(session);
                if (r == ValueNull.INSTANCE) {
                    if ((compareType & NULL_SAFE) == 0) {
                        return ValueExpression.getNull();
                    }
                }
                int colType = left.getType();
                int constType = r.getType();
                int resType = Value.getHigherOrder(colType, constType);
                // once.
                if (constType != resType) {
                    Column column = ((ExpressionColumn) left).getColumn();
                    right = ValueExpression.get(r.convertTo(resType, MathUtils.convertLongToInt(left.getPrecision()), session.getDatabase().getMode(), column, column.getEnumerators()));
                }
            } else if (right instanceof Parameter) {
                ((Parameter) right).setColumn(((ExpressionColumn) left).getColumn());
            }
        }
    }
    if (compareType == IS_NULL || compareType == IS_NOT_NULL) {
        if (left.isConstant()) {
            return ValueExpression.get(getValue(session));
        }
    } else {
        if (SysProperties.CHECK && (left == null || right == null)) {
            DbException.throwInternalError(left + " " + right);
        }
        if (left == ValueExpression.getNull() || right == ValueExpression.getNull()) {
            // a NULL constants
            if ((compareType & NULL_SAFE) == 0) {
                return ValueExpression.getNull();
            }
        }
        if (left.isConstant() && right.isConstant()) {
            return ValueExpression.get(getValue(session));
        }
    }
    return this;
}
Also used : Column(org.h2.table.Column)

Example 25 with ExpressionColumn

use of org.h2.expression.ExpressionColumn in project h2database by h2database.

the class Aggregate method getMinMaxColumnIndex.

private Index getMinMaxColumnIndex() {
    if (on instanceof ExpressionColumn) {
        ExpressionColumn col = (ExpressionColumn) on;
        Column column = col.getColumn();
        TableFilter filter = col.getTableFilter();
        if (filter != null) {
            Table table = filter.getTable();
            return table.getIndexForColumn(column, true, false);
        }
    }
    return null;
}
Also used : Table(org.h2.table.Table) Column(org.h2.table.Column) TableFilter(org.h2.table.TableFilter)

Aggregations

ExpressionColumn (org.h2.expression.ExpressionColumn)21 Column (org.h2.table.Column)18 Expression (org.h2.expression.Expression)17 ValueExpression (org.h2.expression.ValueExpression)9 IndexColumn (org.h2.table.IndexColumn)9 TableFilter (org.h2.table.TableFilter)8 Query (org.h2.command.dml.Query)6 Comparison (org.h2.expression.Comparison)6 ConditionAndOr (org.h2.expression.ConditionAndOr)6 ValueString (org.h2.value.ValueString)6 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)4 Database (org.h2.engine.Database)4 Index (org.h2.index.Index)4 Value (org.h2.value.Value)4 Parser (org.h2.command.Parser)3 LocalResult (org.h2.result.LocalResult)3 Table (org.h2.table.Table)3 IOException (java.io.IOException)2 SQLException (java.sql.SQLException)2 CacheException (javax.cache.CacheException)2