Search in sources :

Example 1 with SequenceValue

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

the class Parser method readTerm.

private Expression readTerm() {
    Expression r;
    switch(currentTokenType) {
        case AT:
            read();
            r = new Variable(session, readAliasIdentifier());
            if (readIf(":=")) {
                Expression value = readExpression();
                Function function = Function.getFunction(database, "SET");
                function.setParameter(0, r);
                function.setParameter(1, value);
                r = function;
            }
            break;
        case PARAMETER:
            r = readParameter();
            break;
        case KEYWORD:
            if (isToken("SELECT") || isToken("FROM") || isToken("WITH")) {
                Query query = parseSelect();
                r = new Subquery(query);
            } else {
                throw getSyntaxError();
            }
            break;
        case IDENTIFIER:
            String name = currentToken;
            if (currentTokenQuoted) {
                read();
                if (readIf("(")) {
                    r = readFunction(null, name);
                } else if (readIf(".")) {
                    r = readTermObjectDot(name);
                } else {
                    r = new ExpressionColumn(database, null, null, name);
                }
            } else {
                read();
                if (readIf(".")) {
                    r = readTermObjectDot(name);
                } else if (equalsToken("CASE", name)) {
                    // CASE must be processed before (,
                    // otherwise CASE(3) would be a function call, which it is
                    // not
                    r = readCase();
                } else if (readIf("(")) {
                    r = readFunction(null, name);
                } else if (equalsToken("CURRENT_USER", name)) {
                    r = readFunctionWithoutParameters("USER");
                } else if (equalsToken("CURRENT_TIMESTAMP", name)) {
                    r = readFunctionWithoutParameters("CURRENT_TIMESTAMP");
                } else if (equalsToken("SYSDATE", name)) {
                    r = readFunctionWithoutParameters("CURRENT_TIMESTAMP");
                } else if (equalsToken("SYSTIMESTAMP", name)) {
                    r = readFunctionWithoutParameters("CURRENT_TIMESTAMP");
                } else if (equalsToken("CURRENT_DATE", name)) {
                    r = readFunctionWithoutParameters("CURRENT_DATE");
                } else if (equalsToken("TODAY", name)) {
                    r = readFunctionWithoutParameters("CURRENT_DATE");
                } else if (equalsToken("CURRENT_TIME", name)) {
                    r = readFunctionWithoutParameters("CURRENT_TIME");
                } else if (equalsToken("SYSTIME", name)) {
                    r = readFunctionWithoutParameters("CURRENT_TIME");
                } else if (equalsToken("CURRENT", name)) {
                    if (readIf("TIMESTAMP")) {
                        r = readFunctionWithoutParameters("CURRENT_TIMESTAMP");
                    } else if (readIf("TIME")) {
                        r = readFunctionWithoutParameters("CURRENT_TIME");
                    } else if (readIf("DATE")) {
                        r = readFunctionWithoutParameters("CURRENT_DATE");
                    } else {
                        r = new ExpressionColumn(database, null, null, name);
                    }
                } else if (equalsToken("NEXT", name) && readIf("VALUE")) {
                    read("FOR");
                    Sequence sequence = readSequence();
                    r = new SequenceValue(sequence);
                } else if (equalsToken("TIME", name)) {
                    boolean without = readIf("WITHOUT");
                    if (without) {
                        read("TIME");
                        read("ZONE");
                    }
                    if (currentTokenType != VALUE || currentValue.getType() != Value.STRING) {
                        if (without) {
                            throw getSyntaxError();
                        }
                        r = new ExpressionColumn(database, null, null, name);
                    } else {
                        String time = currentValue.getString();
                        read();
                        r = ValueExpression.get(ValueTime.parse(time));
                    }
                } else if (equalsToken("TIMESTAMP", name)) {
                    if (readIf("WITH")) {
                        read("TIME");
                        read("ZONE");
                        if (currentTokenType != VALUE || currentValue.getType() != Value.STRING) {
                            throw getSyntaxError();
                        }
                        String timestamp = currentValue.getString();
                        read();
                        r = ValueExpression.get(ValueTimestampTimeZone.parse(timestamp));
                    } else {
                        boolean without = readIf("WITHOUT");
                        if (without) {
                            read("TIME");
                            read("ZONE");
                        }
                        if (currentTokenType != VALUE || currentValue.getType() != Value.STRING) {
                            if (without) {
                                throw getSyntaxError();
                            }
                            r = new ExpressionColumn(database, null, null, name);
                        } else {
                            String timestamp = currentValue.getString();
                            read();
                            r = ValueExpression.get(ValueTimestamp.parse(timestamp, database.getMode()));
                        }
                    }
                } else if (currentTokenType == VALUE && currentValue.getType() == Value.STRING) {
                    if (equalsToken("DATE", name) || equalsToken("D", name)) {
                        String date = currentValue.getString();
                        read();
                        r = ValueExpression.get(ValueDate.parse(date));
                    } else if (equalsToken("T", name)) {
                        String time = currentValue.getString();
                        read();
                        r = ValueExpression.get(ValueTime.parse(time));
                    } else if (equalsToken("TS", name)) {
                        String timestamp = currentValue.getString();
                        read();
                        r = ValueExpression.get(ValueTimestamp.parse(timestamp, database.getMode()));
                    } else if (equalsToken("X", name)) {
                        read();
                        byte[] buffer = StringUtils.convertHexToBytes(currentValue.getString());
                        r = ValueExpression.get(ValueBytes.getNoCopy(buffer));
                    } else if (equalsToken("E", name)) {
                        String text = currentValue.getString();
                        // the PostgreSQL ODBC driver uses
                        // LIKE E'PROJECT\\_DATA' instead of LIKE
                        // 'PROJECT\_DATA'
                        // N: SQL-92 "National Language" strings
                        text = StringUtils.replaceAll(text, "\\\\", "\\");
                        read();
                        r = ValueExpression.get(ValueString.get(text));
                    } else if (equalsToken("N", name)) {
                        // SQL-92 "National Language" strings
                        String text = currentValue.getString();
                        read();
                        r = ValueExpression.get(ValueString.get(text));
                    } else {
                        r = new ExpressionColumn(database, null, null, name);
                    }
                } else {
                    r = new ExpressionColumn(database, null, null, name);
                }
            }
            break;
        case MINUS:
            read();
            if (currentTokenType == VALUE) {
                r = ValueExpression.get(currentValue.negate());
                if (r.getType() == Value.LONG && r.getValue(session).getLong() == Integer.MIN_VALUE) {
                    // convert Integer.MIN_VALUE to type 'int'
                    // (Integer.MAX_VALUE+1 is of type 'long')
                    r = ValueExpression.get(ValueInt.get(Integer.MIN_VALUE));
                } else if (r.getType() == Value.DECIMAL && r.getValue(session).getBigDecimal().compareTo(ValueLong.MIN_BD) == 0) {
                    // convert Long.MIN_VALUE to type 'long'
                    // (Long.MAX_VALUE+1 is of type 'decimal')
                    r = ValueExpression.get(ValueLong.MIN);
                }
                read();
            } else {
                r = new Operation(OpType.NEGATE, readTerm(), null);
            }
            break;
        case PLUS:
            read();
            r = readTerm();
            break;
        case OPEN:
            read();
            if (readIf(")")) {
                r = new ExpressionList(new Expression[0]);
            } else {
                r = readExpression();
                if (readIf(",")) {
                    ArrayList<Expression> list = New.arrayList();
                    list.add(r);
                    while (!readIf(")")) {
                        r = readExpression();
                        list.add(r);
                        if (!readIf(",")) {
                            read(")");
                            break;
                        }
                    }
                    r = new ExpressionList(list.toArray(new Expression[0]));
                } else {
                    read(")");
                }
            }
            break;
        case TRUE:
            read();
            r = ValueExpression.get(ValueBoolean.TRUE);
            break;
        case FALSE:
            read();
            r = ValueExpression.get(ValueBoolean.FALSE);
            break;
        case ROWNUM:
            read();
            if (readIf("(")) {
                read(")");
            }
            if (currentSelect == null && currentPrepared == null) {
                throw getSyntaxError();
            }
            r = new Rownum(currentSelect == null ? currentPrepared : currentSelect);
            break;
        case NULL:
            read();
            r = ValueExpression.getNull();
            break;
        case VALUE:
            r = ValueExpression.get(currentValue);
            read();
            break;
        default:
            throw getSyntaxError();
    }
    if (readIf("[")) {
        Function function = Function.getFunction(database, "ARRAY_GET");
        function.setParameter(0, r);
        r = readExpression();
        r = new Operation(OpType.PLUS, r, ValueExpression.get(ValueInt.get(1)));
        function.setParameter(1, r);
        r = function;
        read("]");
    }
    if (readIf("::")) {
        // PostgreSQL compatibility
        if (isToken("PG_CATALOG")) {
            read("PG_CATALOG");
            read(".");
        }
        if (readIf("REGCLASS")) {
            FunctionAlias f = findFunctionAlias(Constants.SCHEMA_MAIN, "PG_GET_OID");
            if (f == null) {
                throw getSyntaxError();
            }
            Expression[] args = { r };
            r = new JavaFunction(f, args);
        } else {
            Column col = parseColumnWithType(null);
            Function function = Function.getFunction(database, "CAST");
            function.setDataType(col);
            function.setParameter(0, r);
            r = function;
        }
    }
    return r;
}
Also used : Variable(org.h2.expression.Variable) Query(org.h2.command.dml.Query) CreateFunctionAlias(org.h2.command.ddl.CreateFunctionAlias) FunctionAlias(org.h2.engine.FunctionAlias) DropFunctionAlias(org.h2.command.ddl.DropFunctionAlias) JavaFunction(org.h2.expression.JavaFunction) ValueString(org.h2.value.ValueString) DropSequence(org.h2.command.ddl.DropSequence) CreateSequence(org.h2.command.ddl.CreateSequence) Sequence(org.h2.schema.Sequence) AlterSequence(org.h2.command.dml.AlterSequence) Operation(org.h2.expression.Operation) NoOperation(org.h2.command.dml.NoOperation) Subquery(org.h2.expression.Subquery) Rownum(org.h2.expression.Rownum) ExpressionColumn(org.h2.expression.ExpressionColumn) Function(org.h2.expression.Function) TableFunction(org.h2.expression.TableFunction) JavaFunction(org.h2.expression.JavaFunction) SequenceValue(org.h2.expression.SequenceValue) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) 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) ExpressionList(org.h2.expression.ExpressionList)

Example 2 with SequenceValue

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

the class Function method getValueWithArgs.

private Value getValueWithArgs(Session session, Expression[] args) {
    Value[] values = new Value[args.length];
    if (info.nullIfParameterIsNull) {
        for (int i = 0; i < args.length; i++) {
            Expression e = args[i];
            Value v = e.getValue(session);
            if (v == ValueNull.INSTANCE) {
                return ValueNull.INSTANCE;
            }
            values[i] = v;
        }
    }
    Value v0 = getNullOrValue(session, args, values, 0);
    Value resultSimple = getSimpleValue(session, v0, args, values);
    if (resultSimple != null) {
        return resultSimple;
    }
    Value v1 = getNullOrValue(session, args, values, 1);
    Value v2 = getNullOrValue(session, args, values, 2);
    Value v3 = getNullOrValue(session, args, values, 3);
    Value v4 = getNullOrValue(session, args, values, 4);
    Value v5 = getNullOrValue(session, args, values, 5);
    Value result;
    switch(info.type) {
        case ATAN2:
            result = ValueDouble.get(Math.atan2(v0.getDouble(), v1.getDouble()));
            break;
        case BITAND:
            result = ValueLong.get(v0.getLong() & v1.getLong());
            break;
        case BITGET:
            result = ValueBoolean.get((v0.getLong() & (1L << v1.getInt())) != 0);
            break;
        case BITOR:
            result = ValueLong.get(v0.getLong() | v1.getLong());
            break;
        case BITXOR:
            result = ValueLong.get(v0.getLong() ^ v1.getLong());
            break;
        case MOD:
            {
                long x = v1.getLong();
                if (x == 0) {
                    throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL());
                }
                result = ValueLong.get(v0.getLong() % x);
                break;
            }
        case POWER:
            result = ValueDouble.get(Math.pow(v0.getDouble(), v1.getDouble()));
            break;
        case ROUND:
            {
                double f = v1 == null ? 1. : Math.pow(10., v1.getDouble());
                double middleResult = v0.getDouble() * f;
                int oneWithSymbol = middleResult > 0 ? 1 : -1;
                result = ValueDouble.get(Math.round(Math.abs(middleResult)) / f * oneWithSymbol);
                break;
            }
        case TRUNCATE:
            {
                if (v0.getType() == Value.TIMESTAMP) {
                    result = ValueTimestamp.fromDateValueAndNanos(((ValueTimestamp) v0).getDateValue(), 0);
                } else if (v0.getType() == Value.DATE) {
                    result = ValueTimestamp.fromDateValueAndNanos(((ValueDate) v0).getDateValue(), 0);
                } else if (v0.getType() == Value.TIMESTAMP_TZ) {
                    ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v0;
                    result = ValueTimestampTimeZone.fromDateValueAndNanos(ts.getDateValue(), 0, ts.getTimeZoneOffsetMins());
                } else if (v0.getType() == Value.STRING) {
                    ValueTimestamp ts = ValueTimestamp.parse(v0.getString(), session.getDatabase().getMode());
                    result = ValueTimestamp.fromDateValueAndNanos(ts.getDateValue(), 0);
                } else {
                    double d = v0.getDouble();
                    int p = v1 == null ? 0 : v1.getInt();
                    double f = Math.pow(10., p);
                    double g = d * f;
                    result = ValueDouble.get(((d < 0) ? Math.ceil(g) : Math.floor(g)) / f);
                }
                break;
            }
        case HASH:
            result = ValueBytes.getNoCopy(getHash(v0.getString(), v1.getBytesNoCopy(), v2.getInt()));
            break;
        case ENCRYPT:
            result = ValueBytes.getNoCopy(encrypt(v0.getString(), v1.getBytesNoCopy(), v2.getBytesNoCopy()));
            break;
        case DECRYPT:
            result = ValueBytes.getNoCopy(decrypt(v0.getString(), v1.getBytesNoCopy(), v2.getBytesNoCopy()));
            break;
        case COMPRESS:
            {
                String algorithm = null;
                if (v1 != null) {
                    algorithm = v1.getString();
                }
                result = ValueBytes.getNoCopy(CompressTool.getInstance().compress(v0.getBytesNoCopy(), algorithm));
                break;
            }
        case DIFFERENCE:
            result = ValueInt.get(getDifference(v0.getString(), v1.getString()));
            break;
        case INSERT:
            {
                if (v1 == ValueNull.INSTANCE || v2 == ValueNull.INSTANCE) {
                    result = v1;
                } else {
                    result = ValueString.get(insert(v0.getString(), v1.getInt(), v2.getInt(), v3.getString()), database.getMode().treatEmptyStringsAsNull);
                }
                break;
            }
        case LEFT:
            result = ValueString.get(left(v0.getString(), v1.getInt()), database.getMode().treatEmptyStringsAsNull);
            break;
        case LOCATE:
            {
                int start = v2 == null ? 0 : v2.getInt();
                result = ValueInt.get(locate(v0.getString(), v1.getString(), start));
                break;
            }
        case INSTR:
            {
                int start = v2 == null ? 0 : v2.getInt();
                result = ValueInt.get(locate(v1.getString(), v0.getString(), start));
                break;
            }
        case REPEAT:
            {
                int count = Math.max(0, v1.getInt());
                result = ValueString.get(repeat(v0.getString(), count), database.getMode().treatEmptyStringsAsNull);
                break;
            }
        case REPLACE:
            {
                if (v0 == ValueNull.INSTANCE || v1 == ValueNull.INSTANCE || v2 == ValueNull.INSTANCE && database.getMode().getEnum() != Mode.ModeEnum.Oracle) {
                    result = ValueNull.INSTANCE;
                } else {
                    String s0 = v0.getString();
                    String s1 = v1.getString();
                    String s2 = (v2 == null) ? "" : v2.getString();
                    if (s2 == null) {
                        s2 = "";
                    }
                    result = ValueString.get(StringUtils.replaceAll(s0, s1, s2), database.getMode().treatEmptyStringsAsNull);
                }
                break;
            }
        case RIGHT:
            result = ValueString.get(right(v0.getString(), v1.getInt()), database.getMode().treatEmptyStringsAsNull);
            break;
        case LTRIM:
            result = ValueString.get(StringUtils.trim(v0.getString(), true, false, v1 == null ? " " : v1.getString()), database.getMode().treatEmptyStringsAsNull);
            break;
        case TRIM:
            result = ValueString.get(StringUtils.trim(v0.getString(), true, true, v1 == null ? " " : v1.getString()), database.getMode().treatEmptyStringsAsNull);
            break;
        case RTRIM:
            result = ValueString.get(StringUtils.trim(v0.getString(), false, true, v1 == null ? " " : v1.getString()), database.getMode().treatEmptyStringsAsNull);
            break;
        case SUBSTR:
        case SUBSTRING:
            {
                String s = v0.getString();
                int offset = v1.getInt();
                if (offset < 0) {
                    offset = s.length() + offset + 1;
                }
                int length = v2 == null ? s.length() : v2.getInt();
                result = ValueString.get(substring(s, offset, length), database.getMode().treatEmptyStringsAsNull);
                break;
            }
        case POSITION:
            result = ValueInt.get(locate(v0.getString(), v1.getString(), 0));
            break;
        case XMLATTR:
            result = ValueString.get(StringUtils.xmlAttr(v0.getString(), v1.getString()), database.getMode().treatEmptyStringsAsNull);
            break;
        case XMLNODE:
            {
                String attr = v1 == null ? null : v1 == ValueNull.INSTANCE ? null : v1.getString();
                String content = v2 == null ? null : v2 == ValueNull.INSTANCE ? null : v2.getString();
                boolean indent = v3 == null ? true : v3.getBoolean();
                result = ValueString.get(StringUtils.xmlNode(v0.getString(), attr, content, indent), database.getMode().treatEmptyStringsAsNull);
                break;
            }
        case REGEXP_REPLACE:
            {
                String regexp = v1.getString();
                String replacement = v2.getString();
                if (database.getMode().regexpReplaceBackslashReferences) {
                    if ((replacement.indexOf('\\') >= 0) || (replacement.indexOf('$') >= 0)) {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < replacement.length(); i++) {
                            char c = replacement.charAt(i);
                            if (c == '$') {
                                sb.append('\\');
                            } else if (c == '\\' && ++i < replacement.length()) {
                                c = replacement.charAt(i);
                                sb.append(c >= '0' && c <= '9' ? '$' : '\\');
                            }
                            sb.append(c);
                        }
                        replacement = sb.toString();
                    }
                }
                String regexpMode = v3 == null || v3.getString() == null ? "" : v3.getString();
                int flags = makeRegexpFlags(regexpMode);
                try {
                    result = ValueString.get(Pattern.compile(regexp, flags).matcher(v0.getString()).replaceAll(replacement), database.getMode().treatEmptyStringsAsNull);
                } catch (StringIndexOutOfBoundsException e) {
                    throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
                } catch (PatternSyntaxException e) {
                    throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, regexp);
                } catch (IllegalArgumentException e) {
                    throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
                }
                break;
            }
        case RPAD:
            result = ValueString.get(StringUtils.pad(v0.getString(), v1.getInt(), v2 == null ? null : v2.getString(), true), database.getMode().treatEmptyStringsAsNull);
            break;
        case LPAD:
            result = ValueString.get(StringUtils.pad(v0.getString(), v1.getInt(), v2 == null ? null : v2.getString(), false), database.getMode().treatEmptyStringsAsNull);
            break;
        case ORA_HASH:
            result = ValueLong.get(oraHash(v0.getString(), v1 == null ? null : v1.getInt(), v2 == null ? null : v2.getInt()));
            break;
        case TO_CHAR:
            switch(v0.getType()) {
                case Value.TIME:
                case Value.DATE:
                case Value.TIMESTAMP:
                case Value.TIMESTAMP_TZ:
                    result = ValueString.get(ToChar.toCharDateTime(v0, v1 == null ? null : v1.getString(), v2 == null ? null : v2.getString()), database.getMode().treatEmptyStringsAsNull);
                    break;
                case Value.SHORT:
                case Value.INT:
                case Value.LONG:
                case Value.DECIMAL:
                case Value.DOUBLE:
                case Value.FLOAT:
                    result = ValueString.get(ToChar.toChar(v0.getBigDecimal(), v1 == null ? null : v1.getString(), v2 == null ? null : v2.getString()), database.getMode().treatEmptyStringsAsNull);
                    break;
                default:
                    result = ValueString.get(v0.getString(), database.getMode().treatEmptyStringsAsNull);
            }
            break;
        case TO_DATE:
            result = ToDateParser.toDate(v0.getString(), v1 == null ? null : v1.getString());
            break;
        case TO_TIMESTAMP:
            result = ToDateParser.toTimestamp(v0.getString(), v1 == null ? null : v1.getString());
            break;
        case ADD_MONTHS:
            result = DateTimeFunctions.dateadd("MONTH", v1.getInt(), v0);
            break;
        case TO_TIMESTAMP_TZ:
            result = ToDateParser.toTimestampTz(v0.getString(), v1 == null ? null : v1.getString());
            break;
        case TRANSLATE:
            {
                String matching = v1.getString();
                String replacement = v2.getString();
                result = ValueString.get(translate(v0.getString(), matching, replacement), database.getMode().treatEmptyStringsAsNull);
                break;
            }
        case H2VERSION:
            result = ValueString.get(Constants.getVersion(), database.getMode().treatEmptyStringsAsNull);
            break;
        case DATE_ADD:
            result = DateTimeFunctions.dateadd(v0.getString(), v1.getLong(), v2);
            break;
        case DATE_DIFF:
            result = ValueLong.get(DateTimeFunctions.datediff(v0.getString(), v1, v2));
            break;
        case DATE_TRUNC:
            result = DateTimeFunctions.truncateDate(v0.getString(), v1);
            break;
        case EXTRACT:
            result = DateTimeFunctions.extract(v0.getString(), v1);
            break;
        case FORMATDATETIME:
            {
                if (v0 == ValueNull.INSTANCE || v1 == ValueNull.INSTANCE) {
                    result = ValueNull.INSTANCE;
                } else {
                    String locale = v2 == null ? null : v2 == ValueNull.INSTANCE ? null : v2.getString();
                    String tz = v3 == null ? null : v3 == ValueNull.INSTANCE ? null : v3.getString();
                    if (v0 instanceof ValueTimestampTimeZone) {
                        tz = DateTimeUtils.timeZoneNameFromOffsetMins(((ValueTimestampTimeZone) v0).getTimeZoneOffsetMins());
                    }
                    result = ValueString.get(DateTimeFunctions.formatDateTime(v0.getTimestamp(), v1.getString(), locale, tz), database.getMode().treatEmptyStringsAsNull);
                }
                break;
            }
        case PARSEDATETIME:
            {
                if (v0 == ValueNull.INSTANCE || v1 == ValueNull.INSTANCE) {
                    result = ValueNull.INSTANCE;
                } else {
                    String locale = v2 == null ? null : v2 == ValueNull.INSTANCE ? null : v2.getString();
                    String tz = v3 == null ? null : v3 == ValueNull.INSTANCE ? null : v3.getString();
                    java.util.Date d = DateTimeFunctions.parseDateTime(v0.getString(), v1.getString(), locale, tz);
                    result = ValueTimestamp.fromMillis(d.getTime());
                }
                break;
            }
        case NULLIF:
            result = database.areEqual(v0, v1) ? ValueNull.INSTANCE : v0;
            break;
        // system
        case NEXTVAL:
            {
                Sequence sequence = getSequence(session, v0, v1);
                SequenceValue value = new SequenceValue(sequence);
                result = value.getValue(session);
                break;
            }
        case CURRVAL:
            {
                Sequence sequence = getSequence(session, v0, v1);
                result = ValueLong.get(sequence.getCurrentValue());
                break;
            }
        case CSVREAD:
            {
                String fileName = v0.getString();
                String columnList = v1 == null ? null : v1.getString();
                Csv csv = new Csv();
                String options = v2 == null ? null : v2.getString();
                String charset = null;
                if (options != null && options.indexOf('=') >= 0) {
                    charset = csv.setOptions(options);
                } else {
                    charset = options;
                    String fieldSeparatorRead = v3 == null ? null : v3.getString();
                    String fieldDelimiter = v4 == null ? null : v4.getString();
                    String escapeCharacter = v5 == null ? null : v5.getString();
                    Value v6 = getNullOrValue(session, args, values, 6);
                    String nullString = v6 == null ? null : v6.getString();
                    setCsvDelimiterEscape(csv, fieldSeparatorRead, fieldDelimiter, escapeCharacter);
                    csv.setNullString(nullString);
                }
                char fieldSeparator = csv.getFieldSeparatorRead();
                String[] columns = StringUtils.arraySplit(columnList, fieldSeparator, true);
                try {
                    result = ValueResultSet.get(csv.read(fileName, columns, charset));
                } catch (SQLException e) {
                    throw DbException.convert(e);
                }
                break;
            }
        case LINK_SCHEMA:
            {
                session.getUser().checkAdmin();
                Connection conn = session.createConnection(false);
                ResultSet rs = LinkSchema.linkSchema(conn, v0.getString(), v1.getString(), v2.getString(), v3.getString(), v4.getString(), v5.getString());
                result = ValueResultSet.get(rs);
                break;
            }
        case CSVWRITE:
            {
                session.getUser().checkAdmin();
                Connection conn = session.createConnection(false);
                Csv csv = new Csv();
                String options = v2 == null ? null : v2.getString();
                String charset = null;
                if (options != null && options.indexOf('=') >= 0) {
                    charset = csv.setOptions(options);
                } else {
                    charset = options;
                    String fieldSeparatorWrite = v3 == null ? null : v3.getString();
                    String fieldDelimiter = v4 == null ? null : v4.getString();
                    String escapeCharacter = v5 == null ? null : v5.getString();
                    Value v6 = getNullOrValue(session, args, values, 6);
                    String nullString = v6 == null ? null : v6.getString();
                    Value v7 = getNullOrValue(session, args, values, 7);
                    String lineSeparator = v7 == null ? null : v7.getString();
                    setCsvDelimiterEscape(csv, fieldSeparatorWrite, fieldDelimiter, escapeCharacter);
                    csv.setNullString(nullString);
                    if (lineSeparator != null) {
                        csv.setLineSeparator(lineSeparator);
                    }
                }
                try {
                    int rows = csv.write(conn, v0.getString(), v1.getString(), charset);
                    result = ValueInt.get(rows);
                } catch (SQLException e) {
                    throw DbException.convert(e);
                }
                break;
            }
        case SET:
            {
                Variable var = (Variable) args[0];
                session.setVariable(var.getName(), v1);
                result = v1;
                break;
            }
        case FILE_READ:
            {
                session.getUser().checkAdmin();
                String fileName = v0.getString();
                boolean blob = args.length == 1;
                try {
                    long fileLength = FileUtils.size(fileName);
                    final InputStream in = FileUtils.newInputStream(fileName);
                    try {
                        if (blob) {
                            result = database.getLobStorage().createBlob(in, fileLength);
                        } else {
                            Reader reader;
                            if (v1 == ValueNull.INSTANCE) {
                                reader = new InputStreamReader(in);
                            } else {
                                reader = new InputStreamReader(in, v1.getString());
                            }
                            result = database.getLobStorage().createClob(reader, fileLength);
                        }
                    } finally {
                        IOUtils.closeSilently(in);
                    }
                    session.addTemporaryLob(result);
                } catch (IOException e) {
                    throw DbException.convertIOException(e, fileName);
                }
                break;
            }
        case FILE_WRITE:
            {
                session.getUser().checkAdmin();
                result = ValueNull.INSTANCE;
                String fileName = v1.getString();
                try {
                    FileOutputStream fileOutputStream = new FileOutputStream(fileName);
                    try (InputStream in = v0.getInputStream()) {
                        result = ValueLong.get(IOUtils.copyAndClose(in, fileOutputStream));
                    }
                } catch (IOException e) {
                    throw DbException.convertIOException(e, fileName);
                }
                break;
            }
        case TRUNCATE_VALUE:
            {
                result = v0.convertPrecision(v1.getLong(), v2.getBoolean());
                break;
            }
        case XMLTEXT:
            if (v1 == null) {
                result = ValueString.get(StringUtils.xmlText(v0.getString()), database.getMode().treatEmptyStringsAsNull);
            } else {
                result = ValueString.get(StringUtils.xmlText(v0.getString(), v1.getBoolean()), database.getMode().treatEmptyStringsAsNull);
            }
            break;
        case REGEXP_LIKE:
            {
                String regexp = v1.getString();
                String regexpMode = v2 == null || v2.getString() == null ? "" : v2.getString();
                int flags = makeRegexpFlags(regexpMode);
                try {
                    result = ValueBoolean.get(Pattern.compile(regexp, flags).matcher(v0.getString()).find());
                } catch (PatternSyntaxException e) {
                    throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, regexp);
                }
                break;
            }
        case VALUES:
            result = session.getVariable(args[0].getSchemaName() + "." + args[0].getTableName() + "." + args[0].getColumnName());
            break;
        case SIGNAL:
            {
                String sqlState = v0.getString();
                if (sqlState.startsWith("00") || !SIGNAL_PATTERN.matcher(sqlState).matches()) {
                    throw DbException.getInvalidValueException("SQLSTATE", sqlState);
                }
                String msgText = v1.getString();
                throw DbException.fromUser(sqlState, msgText);
            }
        default:
            throw DbException.throwInternalError("type=" + info.type);
    }
    return result;
}
Also used : SQLException(java.sql.SQLException) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) ValueString(org.h2.value.ValueString) ValueTimestamp(org.h2.value.ValueTimestamp) ResultSet(java.sql.ResultSet) ValueResultSet(org.h2.value.ValueResultSet) ValueDate(org.h2.value.ValueDate) PatternSyntaxException(java.util.regex.PatternSyntaxException) InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) Csv(org.h2.tools.Csv) ValueTimestampTimeZone(org.h2.value.ValueTimestampTimeZone) Connection(java.sql.Connection) Sequence(org.h2.schema.Sequence) IOException(java.io.IOException) ValueDate(org.h2.value.ValueDate) FileOutputStream(java.io.FileOutputStream) Value(org.h2.value.Value)

Example 3 with SequenceValue

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

the class Insert method insertRows.

private int insertRows() {
    session.getUser().checkRight(table, Right.INSERT);
    setCurrentRowNumber(0);
    table.fire(session, Trigger.INSERT, true);
    rowNumber = 0;
    GeneratedKeys generatedKeys = session.getGeneratedKeys();
    generatedKeys.initialize(table);
    int listSize = list.size();
    if (listSize > 0) {
        int columnLen = columns.length;
        for (int x = 0; x < listSize; x++) {
            session.startStatementWithinTransaction();
            generatedKeys.nextRow();
            Row newRow = table.getTemplateRow();
            Expression[] expr = list.get(x);
            setCurrentRowNumber(x + 1);
            for (int i = 0; i < columnLen; i++) {
                Column c = columns[i];
                int index = c.getColumnId();
                Expression e = expr[i];
                if (e != null) {
                    // e can be null (DEFAULT)
                    e = e.optimize(session);
                    try {
                        Value v = c.convert(e.getValue(session), session.getDatabase().getMode());
                        newRow.setValue(index, v);
                        if (e instanceof SequenceValue) {
                            generatedKeys.add(c);
                        }
                    } catch (DbException ex) {
                        throw setRow(ex, x, getSQL(expr));
                    }
                }
            }
            rowNumber++;
            table.validateConvertUpdateSequence(session, newRow);
            boolean done = table.fireBeforeRow(session, null, newRow);
            if (!done) {
                table.lock(session, true, false);
                try {
                    table.addRow(session, newRow);
                } catch (DbException de) {
                    if (handleOnDuplicate(de)) {
                        // MySQL returns 2 for updated row
                        // TODO: detect no-op change
                        rowNumber++;
                    } else {
                        // INSERT IGNORE case
                        rowNumber--;
                    }
                    continue;
                }
                generatedKeys.confirmRow(newRow);
                session.log(table, UndoLogRecord.INSERT, newRow);
                table.fireAfterRow(session, null, newRow, false);
            }
        }
    } else {
        table.lock(session, true, false);
        if (insertFromSelect) {
            query.query(0, this);
        } else {
            ResultInterface rows = query.query(0);
            while (rows.next()) {
                generatedKeys.nextRow();
                Value[] r = rows.currentRow();
                Row newRow = addRowImpl(r);
                if (newRow != null) {
                    generatedKeys.confirmRow(newRow);
                }
            }
            rows.close();
        }
    }
    table.fire(session, Trigger.INSERT, false);
    return rowNumber;
}
Also used : SequenceValue(org.h2.expression.SequenceValue) ResultInterface(org.h2.result.ResultInterface) Expression(org.h2.expression.Expression) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) Value(org.h2.value.Value) SequenceValue(org.h2.expression.SequenceValue) GeneratedKeys(org.h2.engine.GeneratedKeys) Row(org.h2.result.Row) DbException(org.h2.message.DbException)

Example 4 with SequenceValue

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

the class Merge method update.

@Override
public int update() {
    int count;
    session.getUser().checkRight(targetTable, Right.INSERT);
    session.getUser().checkRight(targetTable, Right.UPDATE);
    setCurrentRowNumber(0);
    GeneratedKeys generatedKeys = session.getGeneratedKeys();
    if (!valuesExpressionList.isEmpty()) {
        // process values in list
        count = 0;
        generatedKeys.initialize(targetTable);
        for (int x = 0, size = valuesExpressionList.size(); x < size; x++) {
            setCurrentRowNumber(x + 1);
            generatedKeys.nextRow();
            Expression[] expr = valuesExpressionList.get(x);
            Row newRow = targetTable.getTemplateRow();
            for (int i = 0, len = columns.length; i < len; i++) {
                Column c = columns[i];
                int index = c.getColumnId();
                Expression e = expr[i];
                if (e != null) {
                    // e can be null (DEFAULT)
                    try {
                        Value v = c.convert(e.getValue(session));
                        newRow.setValue(index, v);
                        if (e instanceof SequenceValue) {
                            generatedKeys.add(c);
                        }
                    } catch (DbException ex) {
                        throw setRow(ex, count, getSQL(expr));
                    }
                }
            }
            merge(newRow);
            count++;
        }
    } else {
        // process select data for list
        query.setNeverLazy(true);
        ResultInterface rows = query.query(0);
        count = 0;
        targetTable.fire(session, Trigger.UPDATE | Trigger.INSERT, true);
        targetTable.lock(session, true, false);
        while (rows.next()) {
            count++;
            generatedKeys.nextRow();
            Value[] r = rows.currentRow();
            Row newRow = targetTable.getTemplateRow();
            setCurrentRowNumber(count);
            for (int j = 0; j < columns.length; j++) {
                Column c = columns[j];
                int index = c.getColumnId();
                try {
                    Value v = c.convert(r[j]);
                    newRow.setValue(index, v);
                } catch (DbException ex) {
                    throw setRow(ex, count, getSQL(r));
                }
            }
            merge(newRow);
        }
        rows.close();
        targetTable.fire(session, Trigger.UPDATE | Trigger.INSERT, false);
    }
    return count;
}
Also used : SequenceValue(org.h2.expression.SequenceValue) ResultInterface(org.h2.result.ResultInterface) Expression(org.h2.expression.Expression) Column(org.h2.table.Column) SequenceValue(org.h2.expression.SequenceValue) Value(org.h2.value.Value) GeneratedKeys(org.h2.engine.GeneratedKeys) Row(org.h2.result.Row) DbException(org.h2.message.DbException)

Example 5 with SequenceValue

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

the class Column method convertAutoIncrementToSequence.

/**
 * Convert the auto-increment flag to a sequence that is linked with this
 * table.
 *
 * @param session the session
 * @param schema the schema where the sequence should be generated
 * @param id the object id
 * @param temporary true if the sequence is temporary and does not need to
 *            be stored
 */
public void convertAutoIncrementToSequence(Session session, Schema schema, int id, boolean temporary) {
    if (!autoIncrement) {
        DbException.throwInternalError();
    }
    if ("IDENTITY".equals(originalSQL)) {
        originalSQL = "BIGINT";
    } else if ("SERIAL".equals(originalSQL)) {
        originalSQL = "INT";
    }
    String sequenceName;
    do {
        ValueUuid uuid = ValueUuid.getNewRandom();
        String s = uuid.getString();
        s = StringUtils.toUpperEnglish(s.replace('-', '_'));
        sequenceName = "SYSTEM_SEQUENCE_" + s;
    } while (schema.findSequence(sequenceName) != null);
    Sequence seq = new Sequence(schema, id, sequenceName, start, increment);
    seq.setTemporary(temporary);
    session.getDatabase().addSchemaObject(session, seq);
    setAutoIncrement(false, 0, 0);
    SequenceValue seqValue = new SequenceValue(seq);
    setDefaultExpression(session, seqValue);
    setSequence(seq);
}
Also used : ValueUuid(org.h2.value.ValueUuid) SequenceValue(org.h2.expression.SequenceValue) ValueString(org.h2.value.ValueString) Sequence(org.h2.schema.Sequence)

Aggregations

SequenceValue (org.h2.expression.SequenceValue)4 Expression (org.h2.expression.Expression)3 Sequence (org.h2.schema.Sequence)3 Column (org.h2.table.Column)3 Value (org.h2.value.Value)3 ValueString (org.h2.value.ValueString)3 GeneratedKeys (org.h2.engine.GeneratedKeys)2 ExpressionColumn (org.h2.expression.ExpressionColumn)2 DbException (org.h2.message.DbException)2 ResultInterface (org.h2.result.ResultInterface)2 Row (org.h2.result.Row)2 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 Reader (java.io.Reader)1 Connection (java.sql.Connection)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 PatternSyntaxException (java.util.regex.PatternSyntaxException)1