Search in sources :

Example 21 with Function

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

the class TableLink method addIndex.

private void addIndex(List<Column> list, IndexType indexType) {
    // bind the index to the leading recognized columns in the index
    // (null columns might come from a function-based index)
    int firstNull = list.indexOf(null);
    if (firstNull == 0) {
        trace.info("Omitting linked index - no recognized columns.");
        return;
    } else if (firstNull > 0) {
        trace.info("Unrecognized columns in linked index. " + "Registering the index against the leading {0} " + "recognized columns of {1} total columns.", firstNull, list.size());
        list = list.subList(0, firstNull);
    }
    Column[] cols = list.toArray(new Column[0]);
    Index index = new LinkedIndex(this, 0, IndexColumn.wrap(cols), indexType);
    indexes.add(index);
}
Also used : LinkedIndex(org.h2.index.LinkedIndex) Index(org.h2.index.Index) LinkedIndex(org.h2.index.LinkedIndex)

Example 22 with Function

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

the class FunctionTable method getResult.

/**
 * Read the result from the function. This method buffers the result in a
 * temporary file.
 *
 * @param session the session
 * @return the result
 */
public ResultInterface getResult(Session session) {
    ValueResultSet v = getValueResultSet(session);
    if (v == null) {
        return null;
    }
    if (cachedResult != null && cachedValue == v) {
        cachedResult.reset();
        return cachedResult;
    }
    LocalResult result = LocalResult.read(session, v.getResultSet(), 0);
    if (function.isDeterministic()) {
        cachedResult = result;
        cachedValue = v;
    }
    return result;
}
Also used : LocalResult(org.h2.result.LocalResult) ValueResultSet(org.h2.value.ValueResultSet)

Example 23 with Function

use of org.h2.expression.Function 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 24 with Function

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

Example 25 with Function

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

the class Parser method parseUpdateSetClause.

private void parseUpdateSetClause(Update command, TableFilter filter, int start) {
    read("SET");
    if (readIf("(")) {
        ArrayList<Column> columns = New.arrayList();
        do {
            Column column = readTableColumn(filter);
            columns.add(column);
        } while (readIfMore(true));
        read("=");
        Expression expression = readExpression();
        if (columns.size() == 1) {
            // the expression is parsed as a simple value
            command.setAssignment(columns.get(0), expression);
        } else {
            for (int i = 0, size = columns.size(); i < size; i++) {
                Column column = columns.get(i);
                Function f = Function.getFunction(database, "ARRAY_GET");
                f.setParameter(0, expression);
                f.setParameter(1, ValueExpression.get(ValueInt.get(i + 1)));
                f.doneWithParameters();
                command.setAssignment(column, f);
            }
        }
    } else {
        do {
            Column column = readTableColumn(filter);
            read("=");
            Expression expression;
            if (readIf("DEFAULT")) {
                expression = ValueExpression.getDefault();
            } else {
                expression = readExpression();
            }
            command.setAssignment(column, expression);
        } while (readIf(","));
    }
    if (readIf("WHERE")) {
        Expression condition = readExpression();
        command.setCondition(condition);
    }
    if (readIf("ORDER")) {
        // for MySQL compatibility
        // (this syntax is supported, but ignored)
        read("BY");
        parseSimpleOrderList();
    }
    if (readIf("LIMIT")) {
        Expression limit = readTerm().optimize(session);
        command.setLimit(limit);
    }
    setSQL(command, "UPDATE", start);
}
Also used : Function(org.h2.expression.Function) TableFunction(org.h2.expression.TableFunction) JavaFunction(org.h2.expression.JavaFunction) 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) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint)

Aggregations

SimpleResultSet (org.h2.tools.SimpleResultSet)10 ResultSet (java.sql.ResultSet)9 Function (org.h2.expression.Function)8 JavaFunction (org.h2.expression.JavaFunction)8 TableFunction (org.h2.expression.TableFunction)8 Expression (org.h2.expression.Expression)7 ValueExpression (org.h2.expression.ValueExpression)7 Column (org.h2.table.Column)7 Statement (java.sql.Statement)6 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)6 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)6 ExpressionColumn (org.h2.expression.ExpressionColumn)6 IndexColumn (org.h2.table.IndexColumn)6 SQLException (java.sql.SQLException)5 AlterTableRenameColumn (org.h2.command.ddl.AlterTableRenameColumn)5 PreparedStatement (java.sql.PreparedStatement)4 ValueString (org.h2.value.ValueString)4 Connection (java.sql.Connection)3 ArrayList (java.util.ArrayList)3 AlterTableDropConstraint (org.h2.command.ddl.AlterTableDropConstraint)3