Search in sources :

Example 71 with Expression

use of de.neemann.digital.hdl.model2.expression.Expression in project h2database by h2database.

the class Merge method prepare.

@Override
public void prepare() {
    if (columns == null) {
        if (!valuesExpressionList.isEmpty() && valuesExpressionList.get(0).length == 0) {
            // special case where table is used as a sequence
            columns = new Column[0];
        } else {
            columns = targetTable.getColumns();
        }
    }
    if (!valuesExpressionList.isEmpty()) {
        for (Expression[] expr : valuesExpressionList) {
            if (expr.length != columns.length) {
                throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
            }
            for (int i = 0; i < expr.length; i++) {
                Expression e = expr[i];
                if (e != null) {
                    expr[i] = e.optimize(session);
                }
            }
        }
    } else {
        query.prepare();
        if (query.getColumnCount() != columns.length) {
            throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
        }
    }
    if (keys == null) {
        Index idx = targetTable.getPrimaryKey();
        if (idx == null) {
            throw DbException.get(ErrorCode.CONSTRAINT_NOT_FOUND_1, "PRIMARY KEY");
        }
        keys = idx.getColumns();
    }
    StatementBuilder buff = new StatementBuilder("UPDATE ");
    buff.append(targetTable.getSQL()).append(" SET ");
    for (Column c : columns) {
        buff.appendExceptFirst(", ");
        buff.append(c.getSQL()).append("=?");
    }
    buff.append(" WHERE ");
    buff.resetCount();
    for (Column c : keys) {
        buff.appendExceptFirst(" AND ");
        buff.append(c.getSQL()).append("=?");
    }
    String sql = buff.toString();
    update = session.prepare(sql);
}
Also used : Expression(org.h2.expression.Expression) Column(org.h2.table.Column) StatementBuilder(org.h2.util.StatementBuilder) Index(org.h2.index.Index)

Example 72 with Expression

use of de.neemann.digital.hdl.model2.expression.Expression in project h2database by h2database.

the class Plan method calculateCost.

/**
 * Calculate the cost of this query plan.
 *
 * @param session the session
 * @return the cost
 */
public double calculateCost(Session session) {
    Trace t = session.getTrace();
    if (t.isDebugEnabled()) {
        t.debug("Plan       : calculate cost for plan {0}", Arrays.toString(allFilters));
    }
    double cost = 1;
    boolean invalidPlan = false;
    final HashSet<Column> allColumnsSet = ExpressionVisitor.allColumnsForTableFilters(allFilters);
    for (int i = 0; i < allFilters.length; i++) {
        TableFilter tableFilter = allFilters[i];
        if (t.isDebugEnabled()) {
            t.debug("Plan       :   for table filter {0}", tableFilter);
        }
        PlanItem item = tableFilter.getBestPlanItem(session, allFilters, i, allColumnsSet);
        planItems.put(tableFilter, item);
        if (t.isDebugEnabled()) {
            t.debug("Plan       :   best plan item cost {0} index {1}", item.cost, item.getIndex().getPlanSQL());
        }
        cost += cost * item.cost;
        setEvaluatable(tableFilter, true);
        Expression on = tableFilter.getJoinCondition();
        if (on != null) {
            if (!on.isEverything(ExpressionVisitor.EVALUATABLE_VISITOR)) {
                invalidPlan = true;
                break;
            }
        }
    }
    if (invalidPlan) {
        cost = Double.POSITIVE_INFINITY;
    }
    if (t.isDebugEnabled()) {
        session.getTrace().debug("Plan       : plan cost {0}", cost);
    }
    for (TableFilter f : allFilters) {
        setEvaluatable(f, false);
    }
    return cost;
}
Also used : Trace(org.h2.message.Trace) Expression(org.h2.expression.Expression)

Example 73 with Expression

use of de.neemann.digital.hdl.model2.expression.Expression in project h2database by h2database.

the class Parser method readFunction.

private Expression readFunction(Schema schema, String name) {
    if (schema != null) {
        return readJavaFunction(schema, name, true);
    }
    boolean allowOverride = database.isAllowBuiltinAliasOverride();
    if (allowOverride) {
        JavaFunction jf = readJavaFunction(null, name, false);
        if (jf != null) {
            return jf;
        }
    }
    AggregateType agg = getAggregateType(name);
    if (agg != null) {
        return readAggregate(agg, name);
    }
    Function function = Function.getFunction(database, name);
    if (function == null) {
        UserAggregate aggregate = database.findAggregate(name);
        if (aggregate != null) {
            return readJavaAggregate(aggregate);
        }
        if (allowOverride) {
            throw DbException.get(ErrorCode.FUNCTION_NOT_FOUND_1, name);
        }
        return readJavaFunction(null, name, true);
    }
    switch(function.getFunctionType()) {
        case Function.CAST:
            {
                function.setParameter(0, readExpression());
                read("AS");
                Column type = parseColumnWithType(null);
                function.setDataType(type);
                read(")");
                break;
            }
        case Function.CONVERT:
            {
                if (database.getMode().swapConvertFunctionParameters) {
                    Column type = parseColumnWithType(null);
                    function.setDataType(type);
                    read(",");
                    function.setParameter(0, readExpression());
                    read(")");
                } else {
                    function.setParameter(0, readExpression());
                    read(",");
                    Column type = parseColumnWithType(null);
                    function.setDataType(type);
                    read(")");
                }
                break;
            }
        case Function.EXTRACT:
            {
                function.setParameter(0, ValueExpression.get(ValueString.get(currentToken)));
                read();
                read("FROM");
                function.setParameter(1, readExpression());
                read(")");
                break;
            }
        case Function.DATE_ADD:
        case Function.DATE_DIFF:
            {
                if (DateTimeFunctions.isDatePart(currentToken)) {
                    function.setParameter(0, ValueExpression.get(ValueString.get(currentToken)));
                    read();
                } else {
                    function.setParameter(0, readExpression());
                }
                read(",");
                function.setParameter(1, readExpression());
                read(",");
                function.setParameter(2, readExpression());
                read(")");
                break;
            }
        case Function.SUBSTRING:
            {
                // Different variants include:
                // SUBSTRING(X,1)
                // SUBSTRING(X,1,1)
                // SUBSTRING(X FROM 1 FOR 1) -- Postgres
                // SUBSTRING(X FROM 1) -- Postgres
                // SUBSTRING(X FOR 1) -- Postgres
                function.setParameter(0, readExpression());
                if (readIf("FROM")) {
                    function.setParameter(1, readExpression());
                    if (readIf("FOR")) {
                        function.setParameter(2, readExpression());
                    }
                } else if (readIf("FOR")) {
                    function.setParameter(1, ValueExpression.get(ValueInt.get(0)));
                    function.setParameter(2, readExpression());
                } else {
                    read(",");
                    function.setParameter(1, readExpression());
                    if (readIf(",")) {
                        function.setParameter(2, readExpression());
                    }
                }
                read(")");
                break;
            }
        case Function.POSITION:
            {
                // can't read expression because IN would be read too early
                function.setParameter(0, readConcat());
                if (!readIf(",")) {
                    read("IN");
                }
                function.setParameter(1, readExpression());
                read(")");
                break;
            }
        case Function.TRIM:
            {
                Expression space = null;
                if (readIf("LEADING")) {
                    function = Function.getFunction(database, "LTRIM");
                    if (!readIf("FROM")) {
                        space = readExpression();
                        read("FROM");
                    }
                } else if (readIf("TRAILING")) {
                    function = Function.getFunction(database, "RTRIM");
                    if (!readIf("FROM")) {
                        space = readExpression();
                        read("FROM");
                    }
                } else if (readIf("BOTH")) {
                    if (!readIf("FROM")) {
                        space = readExpression();
                        read("FROM");
                    }
                }
                Expression p0 = readExpression();
                if (readIf(",")) {
                    space = readExpression();
                } else if (readIf("FROM")) {
                    space = p0;
                    p0 = readExpression();
                }
                function.setParameter(0, p0);
                if (space != null) {
                    function.setParameter(1, space);
                }
                read(")");
                break;
            }
        case Function.TABLE:
        case Function.TABLE_DISTINCT:
            {
                int i = 0;
                ArrayList<Column> columns = New.arrayList();
                do {
                    String columnName = readAliasIdentifier();
                    Column column = parseColumnWithType(columnName);
                    columns.add(column);
                    read("=");
                    function.setParameter(i, readExpression());
                    i++;
                } while (readIfMore(true));
                TableFunction tf = (TableFunction) function;
                tf.setColumns(columns);
                break;
            }
        case Function.ROW_NUMBER:
            read(")");
            read("OVER");
            read("(");
            read(")");
            if (currentSelect == null && currentPrepared == null) {
                throw getSyntaxError();
            }
            return new Rownum(currentSelect == null ? currentPrepared : currentSelect);
        default:
            if (!readIf(")")) {
                int i = 0;
                do {
                    function.setParameter(i++, readExpression());
                } while (readIfMore(true));
            }
    }
    function.doneWithParameters();
    return function;
}
Also used : Function(org.h2.expression.Function) TableFunction(org.h2.expression.TableFunction) JavaFunction(org.h2.expression.JavaFunction) UserAggregate(org.h2.engine.UserAggregate) AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) ArrayList(java.util.ArrayList) JavaFunction(org.h2.expression.JavaFunction) TableFunction(org.h2.expression.TableFunction) ValueString(org.h2.value.ValueString) AggregateType(org.h2.expression.Aggregate.AggregateType) Rownum(org.h2.expression.Rownum) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint)

Example 74 with Expression

use of de.neemann.digital.hdl.model2.expression.Expression in project h2database by h2database.

the class Parser method parseCreateUserDataType.

private CreateUserDataType parseCreateUserDataType() {
    boolean ifNotExists = readIfNotExists();
    CreateUserDataType command = new CreateUserDataType(session);
    command.setTypeName(readUniqueIdentifier());
    read("AS");
    Column col = parseColumnForTable("VALUE", true);
    if (readIf("CHECK")) {
        Expression expr = readExpression();
        col.addCheckConstraint(session, expr);
    }
    col.rename(null);
    command.setColumn(col);
    command.setIfNotExists(ifNotExists);
    return command;
}
Also used : AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) CreateUserDataType(org.h2.command.ddl.CreateUserDataType)

Example 75 with Expression

use of de.neemann.digital.hdl.model2.expression.Expression in project h2database by h2database.

the class Parser method readCondition.

private Expression readCondition() {
    if (readIf("NOT")) {
        return new ConditionNot(readCondition());
    }
    if (readIf("EXISTS")) {
        read("(");
        Query query = parseSelect();
        // can not reduce expression because it might be a union except
        // query with distinct
        read(")");
        return new ConditionExists(query);
    }
    if (readIf("INTERSECTS")) {
        read("(");
        Expression r1 = readConcat();
        read(",");
        Expression r2 = readConcat();
        read(")");
        return new Comparison(session, Comparison.SPATIAL_INTERSECTS, r1, r2);
    }
    Expression r = readConcat();
    while (true) {
        // special case: NOT NULL is not part of an expression (as in CREATE
        // TABLE TEST(ID INT DEFAULT 0 NOT NULL))
        int backup = parseIndex;
        boolean not = false;
        if (readIf("NOT")) {
            not = true;
            if (isToken("NULL")) {
                // this really only works for NOT NULL!
                parseIndex = backup;
                currentToken = "NOT";
                break;
            }
        }
        if (readIf("LIKE")) {
            Expression b = readConcat();
            Expression esc = null;
            if (readIf("ESCAPE")) {
                esc = readConcat();
            }
            recompileAlways = true;
            r = new CompareLike(database, r, b, esc, false);
        } else if (readIf("ILIKE")) {
            Function function = Function.getFunction(database, "CAST");
            function.setDataType(new Column("X", Value.STRING_IGNORECASE));
            function.setParameter(0, r);
            r = function;
            Expression b = readConcat();
            Expression esc = null;
            if (readIf("ESCAPE")) {
                esc = readConcat();
            }
            recompileAlways = true;
            r = new CompareLike(database, r, b, esc, false);
        } else if (readIf("REGEXP")) {
            Expression b = readConcat();
            recompileAlways = true;
            r = new CompareLike(database, r, b, null, true);
        } else if (readIf("IS")) {
            if (readIf("NOT")) {
                if (readIf("NULL")) {
                    r = new Comparison(session, Comparison.IS_NOT_NULL, r, null);
                } else if (readIf("DISTINCT")) {
                    read("FROM");
                    r = new Comparison(session, Comparison.EQUAL_NULL_SAFE, r, readConcat());
                } else {
                    r = new Comparison(session, Comparison.NOT_EQUAL_NULL_SAFE, r, readConcat());
                }
            } else if (readIf("NULL")) {
                r = new Comparison(session, Comparison.IS_NULL, r, null);
            } else if (readIf("DISTINCT")) {
                read("FROM");
                r = new Comparison(session, Comparison.NOT_EQUAL_NULL_SAFE, r, readConcat());
            } else {
                r = new Comparison(session, Comparison.EQUAL_NULL_SAFE, r, readConcat());
            }
        } else if (readIf("IN")) {
            read("(");
            if (readIf(")")) {
                if (database.getMode().prohibitEmptyInPredicate) {
                    throw getSyntaxError();
                }
                r = ValueExpression.get(ValueBoolean.FALSE);
            } else {
                if (isSelect()) {
                    Query query = parseSelect();
                    // can not be lazy because we have to call
                    // method ResultInterface.containsDistinct
                    // which is not supported for lazy execution
                    query.setNeverLazy(true);
                    r = new ConditionInSelect(database, r, query, false, Comparison.EQUAL);
                } else {
                    ArrayList<Expression> v = New.arrayList();
                    Expression last;
                    do {
                        last = readExpression();
                        v.add(last);
                    } while (readIf(","));
                    if (v.size() == 1 && (last instanceof Subquery)) {
                        Subquery s = (Subquery) last;
                        Query q = s.getQuery();
                        r = new ConditionInSelect(database, r, q, false, Comparison.EQUAL);
                    } else {
                        r = new ConditionIn(database, r, v);
                    }
                }
                read(")");
            }
        } else if (readIf("BETWEEN")) {
            Expression low = readConcat();
            read("AND");
            Expression high = readConcat();
            Expression condLow = new Comparison(session, Comparison.SMALLER_EQUAL, low, r);
            Expression condHigh = new Comparison(session, Comparison.BIGGER_EQUAL, high, r);
            r = new ConditionAndOr(ConditionAndOr.AND, condLow, condHigh);
        } else {
            int compareType = getCompareType(currentTokenType);
            if (compareType < 0) {
                break;
            }
            read();
            if (readIf("ALL")) {
                read("(");
                Query query = parseSelect();
                r = new ConditionInSelect(database, r, query, true, compareType);
                read(")");
            } else if (readIf("ANY") || readIf("SOME")) {
                read("(");
                if (currentTokenType == PARAMETER && compareType == 0) {
                    Parameter p = readParameter();
                    r = new ConditionInParameter(database, r, p);
                } else {
                    Query query = parseSelect();
                    r = new ConditionInSelect(database, r, query, false, compareType);
                }
                read(")");
            } else {
                Expression right = readConcat();
                if (SysProperties.OLD_STYLE_OUTER_JOIN && readIf("(") && readIf("+") && readIf(")")) {
                    // join with (+)
                    if (r instanceof ExpressionColumn && right instanceof ExpressionColumn) {
                        ExpressionColumn leftCol = (ExpressionColumn) r;
                        ExpressionColumn rightCol = (ExpressionColumn) right;
                        ArrayList<TableFilter> filters = currentSelect.getTopFilters();
                        for (TableFilter f : filters) {
                            while (f != null) {
                                leftCol.mapColumns(f, 0);
                                rightCol.mapColumns(f, 0);
                                f = f.getJoin();
                            }
                        }
                        TableFilter leftFilter = leftCol.getTableFilter();
                        TableFilter rightFilter = rightCol.getTableFilter();
                        r = new Comparison(session, compareType, r, right);
                        if (leftFilter != null && rightFilter != null) {
                            int idx = filters.indexOf(rightFilter);
                            if (idx >= 0) {
                                filters.remove(idx);
                                leftFilter.addJoin(rightFilter, true, r);
                            } else {
                                rightFilter.mapAndAddFilter(r);
                            }
                            r = ValueExpression.get(ValueBoolean.TRUE);
                        }
                    }
                } else {
                    r = new Comparison(session, compareType, r, right);
                }
            }
        }
        if (not) {
            r = new ConditionNot(r);
        }
    }
    return r;
}
Also used : ConditionNot(org.h2.expression.ConditionNot) Query(org.h2.command.dml.Query) Subquery(org.h2.expression.Subquery) ConditionIn(org.h2.expression.ConditionIn) ConditionAndOr(org.h2.expression.ConditionAndOr) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint) CompareLike(org.h2.expression.CompareLike) ExpressionColumn(org.h2.expression.ExpressionColumn) Function(org.h2.expression.Function) TableFunction(org.h2.expression.TableFunction) JavaFunction(org.h2.expression.JavaFunction) ConditionInParameter(org.h2.expression.ConditionInParameter) ConditionInSelect(org.h2.expression.ConditionInSelect) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) Comparison(org.h2.expression.Comparison) AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) TableFilter(org.h2.table.TableFilter) Parameter(org.h2.expression.Parameter) ConditionInParameter(org.h2.expression.ConditionInParameter) ConditionExists(org.h2.expression.ConditionExists)

Aggregations

Expression (org.h2.expression.Expression)84 ValueExpression (org.h2.expression.ValueExpression)53 Column (org.h2.table.Column)45 ExpressionColumn (org.h2.expression.ExpressionColumn)38 IndexColumn (org.h2.table.IndexColumn)24 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)21 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)18 ValueString (org.h2.value.ValueString)18 AlterTableRenameColumn (org.h2.command.ddl.AlterTableRenameColumn)17 TableFilter (org.h2.table.TableFilter)15 AlterTableDropConstraint (org.h2.command.ddl.AlterTableDropConstraint)14 AlterTableRenameConstraint (org.h2.command.ddl.AlterTableRenameConstraint)14 Expression (expression.Expression)13 Table (org.h2.table.Table)13 Value (org.h2.value.Value)12 ArrayList (java.util.ArrayList)11 Node (expression.Node)10 RangeTable (org.h2.table.RangeTable)10 Number (expression.Number)9 CreateTable (org.h2.command.ddl.CreateTable)9