Search in sources :

Example 6 with Expression

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

the class Parser method parseColumnForTable.

private Column parseColumnForTable(String columnName, boolean defaultNullable) {
    Column column;
    boolean isIdentity = readIf("IDENTITY");
    if (isIdentity || readIf("BIGSERIAL")) {
        // Check if any of them are disallowed in the current Mode
        if (isIdentity && database.getMode().disallowedTypes.contains("IDENTITY")) {
            throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, currentToken);
        }
        column = new Column(columnName, Value.LONG);
        column.setOriginalSQL("IDENTITY");
        parseAutoIncrement(column);
        // PostgreSQL compatibility
        if (!database.getMode().serialColumnIsNotPK) {
            column.setPrimaryKey(true);
        }
    } else if (readIf("SERIAL")) {
        column = new Column(columnName, Value.INT);
        column.setOriginalSQL("SERIAL");
        parseAutoIncrement(column);
        // PostgreSQL compatibility
        if (!database.getMode().serialColumnIsNotPK) {
            column.setPrimaryKey(true);
        }
    } else {
        column = parseColumnWithType(columnName);
    }
    if (readIf("INVISIBLE")) {
        column.setVisible(false);
    } else if (readIf("VISIBLE")) {
        column.setVisible(true);
    }
    NullConstraintType nullConstraint = parseNotNullConstraint();
    switch(nullConstraint) {
        case NULL_IS_ALLOWED:
            column.setNullable(true);
            break;
        case NULL_IS_NOT_ALLOWED:
            column.setNullable(false);
            break;
        case NO_NULL_CONSTRAINT_FOUND:
            // domains may be defined as not nullable
            column.setNullable(defaultNullable & column.isNullable());
            break;
        default:
            throw DbException.get(ErrorCode.UNKNOWN_MODE_1, "Internal Error - unhandled case: " + nullConstraint.name());
    }
    if (readIf("AS")) {
        if (isIdentity) {
            getSyntaxError();
        }
        Expression expr = readExpression();
        column.setComputedExpression(expr);
    } else if (readIf("DEFAULT")) {
        Expression defaultExpression = readExpression();
        column.setDefaultExpression(session, defaultExpression);
    } else if (readIf("GENERATED")) {
        if (!readIf("ALWAYS")) {
            read("BY");
            read("DEFAULT");
        }
        read("AS");
        read("IDENTITY");
        long start = 1, increment = 1;
        if (readIf("(")) {
            read("START");
            readIf("WITH");
            start = readLong();
            readIf(",");
            if (readIf("INCREMENT")) {
                readIf("BY");
                increment = readLong();
            }
            read(")");
        }
        column.setPrimaryKey(true);
        column.setAutoIncrement(true, start, increment);
    }
    if (readIf("ON")) {
        read("UPDATE");
        Expression onUpdateExpression = readExpression();
        column.setOnUpdateExpression(session, onUpdateExpression);
    }
    if (NullConstraintType.NULL_IS_NOT_ALLOWED == parseNotNullConstraint()) {
        column.setNullable(false);
    }
    if (readIf("AUTO_INCREMENT") || readIf("BIGSERIAL") || readIf("SERIAL")) {
        parseAutoIncrement(column);
        parseNotNullConstraint();
    } else if (readIf("IDENTITY")) {
        parseAutoIncrement(column);
        column.setPrimaryKey(true);
        parseNotNullConstraint();
    }
    if (readIf("NULL_TO_DEFAULT")) {
        column.setConvertNullToDefault(true);
    }
    if (readIf("SEQUENCE")) {
        Sequence sequence = readSequence();
        column.setSequence(sequence);
    }
    if (readIf("SELECTIVITY")) {
        int value = readPositiveInt();
        column.setSelectivity(value);
    }
    String comment = readCommentIf();
    if (comment != null) {
        column.setComment(comment);
    }
    return column;
}
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) DropSequence(org.h2.command.ddl.DropSequence) CreateSequence(org.h2.command.ddl.CreateSequence) Sequence(org.h2.schema.Sequence) AlterSequence(org.h2.command.dml.AlterSequence) ValueString(org.h2.value.ValueString) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint)

Example 7 with Expression

use of de.neemann.digital.hdl.model2.expression.Expression 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 8 with Expression

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

the class Parser method parseColumnWithType.

private Column parseColumnWithType(String columnName) {
    String original = currentToken;
    boolean regular = false;
    int originalScale = -1;
    if (readIf("LONG")) {
        if (readIf("RAW")) {
            original += " RAW";
        }
    } else if (readIf("DOUBLE")) {
        if (readIf("PRECISION")) {
            original += " PRECISION";
        }
    } else if (readIf("CHARACTER")) {
        if (readIf("VARYING")) {
            original += " VARYING";
        }
    } else if (readIf("TIME")) {
        if (readIf("(")) {
            originalScale = readPositiveInt();
            if (originalScale > ValueTime.MAXIMUM_SCALE) {
                throw DbException.get(ErrorCode.INVALID_VALUE_SCALE_PRECISION, Integer.toString(originalScale));
            }
            read(")");
        }
        if (readIf("WITHOUT")) {
            read("TIME");
            read("ZONE");
            original += " WITHOUT TIME ZONE";
        }
    } else if (readIf("TIMESTAMP")) {
        if (readIf("(")) {
            originalScale = readPositiveInt();
            // Allow non-standard TIMESTAMP(..., ...) syntax
            if (readIf(",")) {
                originalScale = readPositiveInt();
            }
            if (originalScale > ValueTimestamp.MAXIMUM_SCALE) {
                throw DbException.get(ErrorCode.INVALID_VALUE_SCALE_PRECISION, Integer.toString(originalScale));
            }
            read(")");
        }
        if (readIf("WITH")) {
            read("TIME");
            read("ZONE");
            original += " WITH TIME ZONE";
        } else if (readIf("WITHOUT")) {
            read("TIME");
            read("ZONE");
            original += " WITHOUT TIME ZONE";
        }
    } else {
        regular = true;
    }
    long precision = -1;
    int displaySize = -1;
    String[] enumerators = null;
    int scale = -1;
    String comment = null;
    Column templateColumn = null;
    DataType dataType;
    if (!identifiersToUpper) {
        original = StringUtils.toUpperEnglish(original);
    }
    UserDataType userDataType = database.findUserDataType(original);
    if (userDataType != null) {
        templateColumn = userDataType.getColumn();
        dataType = DataType.getDataType(templateColumn.getType());
        comment = templateColumn.getComment();
        original = templateColumn.getOriginalSQL();
        precision = templateColumn.getPrecision();
        displaySize = templateColumn.getDisplaySize();
        scale = templateColumn.getScale();
        enumerators = templateColumn.getEnumerators();
    } else {
        Mode mode = database.getMode();
        dataType = DataType.getTypeByName(original, mode);
        if (dataType == null || mode.disallowedTypes.contains(original)) {
            throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, currentToken);
        }
    }
    if (database.getIgnoreCase() && dataType.type == Value.STRING && !equalsToken("VARCHAR_CASESENSITIVE", original)) {
        original = "VARCHAR_IGNORECASE";
        dataType = DataType.getTypeByName(original, database.getMode());
    }
    if (regular) {
        read();
    }
    precision = precision == -1 ? dataType.defaultPrecision : precision;
    displaySize = displaySize == -1 ? dataType.defaultDisplaySize : displaySize;
    scale = scale == -1 ? dataType.defaultScale : scale;
    if (dataType.supportsPrecision || dataType.supportsScale) {
        int t = dataType.type;
        if (t == Value.TIME || t == Value.TIMESTAMP || t == Value.TIMESTAMP_TZ) {
            if (originalScale >= 0) {
                scale = originalScale;
                switch(t) {
                    case Value.TIME:
                        if (original.equals("TIME WITHOUT TIME ZONE")) {
                            original = "TIME(" + originalScale + ") WITHOUT TIME ZONE";
                        } else {
                            original = original + '(' + originalScale + ')';
                        }
                        precision = displaySize = ValueTime.getDisplaySize(originalScale);
                        break;
                    case Value.TIMESTAMP:
                        if (original.equals("TIMESTAMP WITHOUT TIME ZONE")) {
                            original = "TIMESTAMP(" + originalScale + ") WITHOUT TIME ZONE";
                        } else {
                            original = original + '(' + originalScale + ')';
                        }
                        precision = displaySize = ValueTimestamp.getDisplaySize(originalScale);
                        break;
                    case Value.TIMESTAMP_TZ:
                        original = "TIMESTAMP(" + originalScale + ") WITH TIME ZONE";
                        precision = displaySize = ValueTimestampTimeZone.getDisplaySize(originalScale);
                        break;
                }
            }
        } else if (readIf("(")) {
            if (!readIf("MAX")) {
                long p = readLong();
                if (readIf("K")) {
                    p *= 1024;
                } else if (readIf("M")) {
                    p *= 1024 * 1024;
                } else if (readIf("G")) {
                    p *= 1024 * 1024 * 1024;
                }
                if (p > Long.MAX_VALUE) {
                    p = Long.MAX_VALUE;
                }
                original += "(" + p;
                // Oracle syntax
                if (!readIf("CHAR")) {
                    readIf("BYTE");
                }
                if (dataType.supportsScale) {
                    if (readIf(",")) {
                        scale = readInt();
                        original += ", " + scale;
                    } else {
                        scale = 0;
                    }
                }
                precision = p;
                displaySize = MathUtils.convertLongToInt(precision);
                original += ")";
            }
            read(")");
        }
    } else if (dataType.type == Value.DOUBLE && original.equals("FLOAT")) {
        if (readIf("(")) {
            int p = readPositiveInt();
            read(")");
            if (p > 53) {
                throw DbException.get(ErrorCode.INVALID_VALUE_SCALE_PRECISION, Integer.toString(p));
            }
            if (p <= 24) {
                dataType = DataType.getDataType(Value.FLOAT);
            }
            original = original + '(' + p + ')';
        }
    } else if (dataType.type == Value.ENUM) {
        if (readIf("(")) {
            java.util.List<String> enumeratorList = new ArrayList<>();
            original += '(';
            String enumerator0 = readString();
            enumeratorList.add(enumerator0);
            original += "'" + enumerator0 + "'";
            while (readIfMore(true)) {
                original += ',';
                String enumeratorN = readString();
                original += "'" + enumeratorN + "'";
                enumeratorList.add(enumeratorN);
            }
            original += ')';
            enumerators = enumeratorList.toArray(new String[0]);
        }
        try {
            ValueEnum.check(enumerators);
        } catch (DbException e) {
            throw e.addSQL(original);
        }
    } else if (readIf("(")) {
        // Support for MySQL: INT(11), MEDIUMINT(8) and so on.
        // Just ignore the precision.
        readPositiveInt();
        read(")");
    }
    if (readIf("FOR")) {
        read("BIT");
        read("DATA");
        if (dataType.type == Value.STRING) {
            dataType = DataType.getTypeByName("BINARY", database.getMode());
        }
    }
    // MySQL compatibility
    readIf("UNSIGNED");
    int type = dataType.type;
    if (scale > precision) {
        throw DbException.get(ErrorCode.INVALID_VALUE_SCALE_PRECISION, Integer.toString(scale), Long.toString(precision));
    }
    Column column = new Column(columnName, type, precision, scale, displaySize, enumerators);
    if (templateColumn != null) {
        column.setNullable(templateColumn.isNullable());
        column.setDefaultExpression(session, templateColumn.getDefaultExpression());
        int selectivity = templateColumn.getSelectivity();
        if (selectivity != Constants.SELECTIVITY_DEFAULT) {
            column.setSelectivity(selectivity);
        }
        Expression checkConstraint = templateColumn.getCheckConstraint(session, columnName);
        column.addCheckConstraint(session, checkConstraint);
    }
    column.setComment(comment);
    column.setOriginalSQL(original);
    return column;
}
Also used : CreateUserDataType(org.h2.command.ddl.CreateUserDataType) DropUserDataType(org.h2.command.ddl.DropUserDataType) UserDataType(org.h2.engine.UserDataType) Mode(org.h2.engine.Mode) CompareMode(org.h2.value.CompareMode) ArrayList(java.util.ArrayList) ValueString(org.h2.value.ValueString) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint) DbException(org.h2.message.DbException) 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) DataType(org.h2.value.DataType) DropUserDataType(org.h2.command.ddl.DropUserDataType) UserDataType(org.h2.engine.UserDataType)

Example 9 with Expression

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

the class Parser method parseMergeUsing.

private MergeUsing parseMergeUsing(Merge oldCommand, int start) {
    MergeUsing command = new MergeUsing(oldCommand);
    currentPrepared = command;
    if (readIf("(")) {
        /* a select query is supplied */
        if (isSelect()) {
            command.setQuery(parseSelect());
            read(")");
        }
        command.setQueryAlias(readFromAlias(null, Collections.singletonList("ON")));
        String[] querySQLOutput = { null };
        List<Column> columnTemplateList = TableView.createQueryColumnTemplateList(null, command.getQuery(), querySQLOutput);
        TableView temporarySourceTableView = createCTEView(command.getQueryAlias(), querySQLOutput[0], columnTemplateList, false, /* no recursion */
        false, /* do not add to session */
        false, /* isPersistent */
        session);
        TableFilter sourceTableFilter = new TableFilter(session, temporarySourceTableView, command.getQueryAlias(), rightsChecked, (Select) command.getQuery(), 0, null);
        command.setSourceTableFilter(sourceTableFilter);
    } else {
        /* Its a table name, simulate a query by building a select query for the table */
        List<String> excludeIdentifiers = Collections.singletonList("ON");
        TableFilter sourceTableFilter = readSimpleTableFilter(0, excludeIdentifiers);
        command.setSourceTableFilter(sourceTableFilter);
        StringBuilder buff = new StringBuilder("SELECT * FROM ");
        appendTableWithSchemaAndAlias(buff, sourceTableFilter.getTable(), sourceTableFilter.getTableAlias());
        Prepared preparedQuery = prepare(session, buff.toString(), null);
        command.setQuery((Select) preparedQuery);
    }
    read("ON");
    read("(");
    Expression condition = readExpression();
    command.setOnCondition(condition);
    read(")");
    if (readIfAll("WHEN", "MATCHED", "THEN")) {
        int startMatched = lastParseIndex;
        if (readIf("UPDATE")) {
            Update updateCommand = new Update(session);
            // currentPrepared = updateCommand;
            TableFilter filter = command.getTargetTableFilter();
            updateCommand.setTableFilter(filter);
            parseUpdateSetClause(updateCommand, filter, startMatched);
            command.setUpdateCommand(updateCommand);
        }
        startMatched = lastParseIndex;
        if (readIf("DELETE")) {
            Delete deleteCommand = new Delete(session);
            TableFilter filter = command.getTargetTableFilter();
            deleteCommand.setTableFilter(filter);
            parseDeleteGivenTable(deleteCommand, null, startMatched);
            command.setDeleteCommand(deleteCommand);
        }
    }
    if (readIfAll("WHEN", "NOT", "MATCHED", "THEN")) {
        if (readIf("INSERT")) {
            Insert insertCommand = new Insert(session);
            insertCommand.setTable(command.getTargetTable());
            parseInsertGivenTable(insertCommand, command.getTargetTable());
            command.setInsertCommand(insertCommand);
        }
    }
    setSQL(command, "MERGE", start);
    // build and prepare the targetMatchQuery ready to test each rows
    // existence in the target table (using source row to match)
    StringBuilder targetMatchQuerySQL = new StringBuilder("SELECT _ROWID_ FROM ");
    appendTableWithSchemaAndAlias(targetMatchQuerySQL, command.getTargetTable(), command.getTargetTableFilter().getTableAlias());
    targetMatchQuerySQL.append(" WHERE ").append(command.getOnCondition().getSQL());
    command.setTargetMatchQuery((Select) parse(targetMatchQuerySQL.toString()));
    return command;
}
Also used : Delete(org.h2.command.dml.Delete) ValueString(org.h2.value.ValueString) Update(org.h2.command.dml.Update) Insert(org.h2.command.dml.Insert) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint) 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) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) MergeUsing(org.h2.command.dml.MergeUsing) TableView(org.h2.table.TableView)

Example 10 with Expression

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

the class Parser method parsePrepared.

private Prepared parsePrepared() {
    int start = lastParseIndex;
    Prepared c = null;
    String token = currentToken;
    if (token.length() == 0) {
        c = new NoOperation(session);
    } else {
        char first = token.charAt(0);
        switch(first) {
            case '?':
                // read the ? as a parameter
                readTerm();
                // this is an 'out' parameter - set a dummy value
                parameters.get(0).setValue(ValueNull.INSTANCE);
                read("=");
                read("CALL");
                c = parseCall();
                break;
            case '(':
                c = parseSelect();
                break;
            case 'a':
            case 'A':
                if (readIf("ALTER")) {
                    c = parseAlter();
                } else if (readIf("ANALYZE")) {
                    c = parseAnalyze();
                }
                break;
            case 'b':
            case 'B':
                if (readIf("BACKUP")) {
                    c = parseBackup();
                } else if (readIf("BEGIN")) {
                    c = parseBegin();
                }
                break;
            case 'c':
            case 'C':
                if (readIf("COMMIT")) {
                    c = parseCommit();
                } else if (readIf("CREATE")) {
                    c = parseCreate();
                } else if (readIf("CALL")) {
                    c = parseCall();
                } else if (readIf("CHECKPOINT")) {
                    c = parseCheckpoint();
                } else if (readIf("COMMENT")) {
                    c = parseComment();
                }
                break;
            case 'd':
            case 'D':
                if (readIf("DELETE")) {
                    c = parseDelete();
                } else if (readIf("DROP")) {
                    c = parseDrop();
                } else if (readIf("DECLARE")) {
                    // support for DECLARE GLOBAL TEMPORARY TABLE...
                    c = parseCreate();
                } else if (readIf("DEALLOCATE")) {
                    c = parseDeallocate();
                }
                break;
            case 'e':
            case 'E':
                if (readIf("EXPLAIN")) {
                    c = parseExplain();
                } else if (readIf("EXECUTE")) {
                    c = parseExecute();
                }
                break;
            case 'f':
            case 'F':
                if (isToken("FROM")) {
                    c = parseSelect();
                }
                break;
            case 'g':
            case 'G':
                if (readIf("GRANT")) {
                    c = parseGrantRevoke(CommandInterface.GRANT);
                }
                break;
            case 'h':
            case 'H':
                if (readIf("HELP")) {
                    c = parseHelp();
                }
                break;
            case 'i':
            case 'I':
                if (readIf("INSERT")) {
                    c = parseInsert();
                }
                break;
            case 'm':
            case 'M':
                if (readIf("MERGE")) {
                    c = parseMerge();
                }
                break;
            case 'p':
            case 'P':
                if (readIf("PREPARE")) {
                    c = parsePrepare();
                }
                break;
            case 'r':
            case 'R':
                if (readIf("ROLLBACK")) {
                    c = parseRollback();
                } else if (readIf("REVOKE")) {
                    c = parseGrantRevoke(CommandInterface.REVOKE);
                } else if (readIf("RUNSCRIPT")) {
                    c = parseRunScript();
                } else if (readIf("RELEASE")) {
                    c = parseReleaseSavepoint();
                } else if (readIf("REPLACE")) {
                    c = parseReplace();
                }
                break;
            case 's':
            case 'S':
                if (isToken("SELECT")) {
                    c = parseSelect();
                } else if (readIf("SET")) {
                    c = parseSet();
                } else if (readIf("SAVEPOINT")) {
                    c = parseSavepoint();
                } else if (readIf("SCRIPT")) {
                    c = parseScript();
                } else if (readIf("SHUTDOWN")) {
                    c = parseShutdown();
                } else if (readIf("SHOW")) {
                    c = parseShow();
                }
                break;
            case 't':
            case 'T':
                if (readIf("TRUNCATE")) {
                    c = parseTruncate();
                }
                break;
            case 'u':
            case 'U':
                if (readIf("UPDATE")) {
                    c = parseUpdate();
                } else if (readIf("USE")) {
                    c = parseUse();
                }
                break;
            case 'v':
            case 'V':
                if (readIf("VALUES")) {
                    c = parseValues();
                }
                break;
            case 'w':
            case 'W':
                if (readIf("WITH")) {
                    c = parseWithStatementOrQuery();
                }
                break;
            case ';':
                c = new NoOperation(session);
                break;
            default:
                throw getSyntaxError();
        }
        if (indexedParameterList != null) {
            for (int i = 0, size = indexedParameterList.size(); i < size; i++) {
                if (indexedParameterList.get(i) == null) {
                    indexedParameterList.set(i, new Parameter(i));
                }
            }
            parameters = indexedParameterList;
        }
        if (readIf("{")) {
            do {
                int index = (int) readLong() - 1;
                if (index < 0 || index >= parameters.size()) {
                    throw getSyntaxError();
                }
                Parameter p = parameters.get(index);
                if (p == null) {
                    throw getSyntaxError();
                }
                read(":");
                Expression expr = readExpression();
                expr = expr.optimize(session);
                p.setValue(expr.getValue(session));
            } while (readIf(","));
            read("}");
            for (Parameter p : parameters) {
                p.checkSet();
            }
            parameters.clear();
        }
    }
    if (c == null) {
        throw getSyntaxError();
    }
    setSQL(c, null, start);
    return c;
}
Also used : NoOperation(org.h2.command.dml.NoOperation) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) Parameter(org.h2.expression.Parameter) ConditionInParameter(org.h2.expression.ConditionInParameter) ValueString(org.h2.value.ValueString) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint)

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