Search in sources :

Example 16 with Update

use of org.h2.command.dml.Update 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)

Example 17 with Update

use of org.h2.command.dml.Update in project h2database by h2database.

the class Parser method parseEndOfQuery.

private void parseEndOfQuery(Query command) {
    if (readIf("ORDER")) {
        read("BY");
        Select oldSelect = currentSelect;
        if (command instanceof Select) {
            currentSelect = (Select) command;
        }
        ArrayList<SelectOrderBy> orderList = New.arrayList();
        do {
            boolean canBeNumber = true;
            if (readIf("=")) {
                canBeNumber = false;
            }
            SelectOrderBy order = new SelectOrderBy();
            Expression expr = readExpression();
            if (canBeNumber && expr instanceof ValueExpression && expr.getType() == Value.INT) {
                order.columnIndexExpr = expr;
            } else if (expr instanceof Parameter) {
                recompileAlways = true;
                order.columnIndexExpr = expr;
            } else {
                order.expression = expr;
            }
            if (readIf("DESC")) {
                order.descending = true;
            } else {
                readIf("ASC");
            }
            if (readIf("NULLS")) {
                if (readIf("FIRST")) {
                    order.nullsFirst = true;
                } else {
                    read("LAST");
                    order.nullsLast = true;
                }
            }
            orderList.add(order);
        } while (readIf(","));
        command.setOrder(orderList);
        currentSelect = oldSelect;
    }
    // make sure aggregate functions will not work here
    Select temp = currentSelect;
    currentSelect = null;
    // http://sqlpro.developpez.com/SQL2008/
    if (readIf("OFFSET")) {
        command.setOffset(readExpression().optimize(session));
        if (!readIf("ROW")) {
            readIf("ROWS");
        }
    }
    if (readIf("FETCH")) {
        if (!readIf("FIRST")) {
            read("NEXT");
        }
        if (readIf("ROW")) {
            command.setLimit(ValueExpression.get(ValueInt.get(1)));
        } else {
            Expression limit = readExpression().optimize(session);
            command.setLimit(limit);
            if (!readIf("ROW")) {
                read("ROWS");
            }
        }
        read("ONLY");
    }
    currentSelect = temp;
    if (readIf("LIMIT")) {
        temp = currentSelect;
        // make sure aggregate functions will not work here
        currentSelect = null;
        Expression limit = readExpression().optimize(session);
        command.setLimit(limit);
        if (readIf("OFFSET")) {
            Expression offset = readExpression().optimize(session);
            command.setOffset(offset);
        } else if (readIf(",")) {
            // MySQL: [offset, ] rowcount
            Expression offset = limit;
            limit = readExpression().optimize(session);
            command.setOffset(offset);
            command.setLimit(limit);
        }
        if (readIf("SAMPLE_SIZE")) {
            Expression sampleSize = readExpression().optimize(session);
            command.setSampleSize(sampleSize);
        }
        currentSelect = temp;
    }
    if (readIf("FOR")) {
        if (readIf("UPDATE")) {
            if (readIf("OF")) {
                do {
                    readIdentifierWithSchema();
                } while (readIf(","));
            } else if (readIf("NOWAIT")) {
            // TODO parser: select for update nowait: should not wait
            }
            command.setForUpdate(true);
        } else if (readIf("READ") || readIf("FETCH")) {
            read("ONLY");
        }
    }
    if (database.getMode().isolationLevelInSelectOrInsertStatement) {
        parseIsolationClause();
    }
}
Also used : SelectOrderBy(org.h2.command.dml.SelectOrderBy) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) ValueExpression(org.h2.expression.ValueExpression) ConditionInSelect(org.h2.expression.ConditionInSelect) Select(org.h2.command.dml.Select) Parameter(org.h2.expression.Parameter) ConditionInParameter(org.h2.expression.ConditionInParameter)

Example 18 with Update

use of org.h2.command.dml.Update in project h2database by h2database.

the class AlterSchemaRename method update.

@Override
public int update() {
    session.commit(true);
    Database db = session.getDatabase();
    if (!oldSchema.canDrop()) {
        throw DbException.get(ErrorCode.SCHEMA_CAN_NOT_BE_DROPPED_1, oldSchema.getName());
    }
    if (db.findSchema(newSchemaName) != null || newSchemaName.equals(oldSchema.getName())) {
        throw DbException.get(ErrorCode.SCHEMA_ALREADY_EXISTS_1, newSchemaName);
    }
    session.getUser().checkSchemaAdmin();
    db.renameDatabaseObject(session, oldSchema, newSchemaName);
    ArrayList<SchemaObject> all = db.getAllSchemaObjects();
    for (SchemaObject schemaObject : all) {
        db.updateMeta(session, schemaObject);
    }
    return 0;
}
Also used : SchemaObject(org.h2.schema.SchemaObject) Database(org.h2.engine.Database)

Example 19 with Update

use of org.h2.command.dml.Update in project h2database by h2database.

the class AlterTableAlterColumn method update.

@Override
public int update() {
    session.commit(true);
    Database db = session.getDatabase();
    Table table = getSchema().resolveTableOrView(session, tableName);
    if (table == null) {
        if (ifTableExists) {
            return 0;
        }
        throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
    }
    session.getUser().checkRight(table, Right.ALL);
    table.checkSupportAlter();
    table.lock(session, true, true);
    if (newColumn != null) {
        checkDefaultReferencesTable(table, newColumn.getDefaultExpression());
        checkClustering(newColumn);
    }
    if (columnsToAdd != null) {
        for (Column column : columnsToAdd) {
            checkDefaultReferencesTable(table, column.getDefaultExpression());
            checkClustering(column);
        }
    }
    switch(type) {
        case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL:
            {
                if (!oldColumn.isNullable()) {
                    // no change
                    break;
                }
                checkNoNullValues(table);
                oldColumn.setNullable(false);
                db.updateMeta(session, table);
                break;
            }
        case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL:
            {
                if (oldColumn.isNullable()) {
                    // no change
                    break;
                }
                checkNullable(table);
                oldColumn.setNullable(true);
                db.updateMeta(session, table);
                break;
            }
        case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT:
            {
                Sequence sequence = oldColumn == null ? null : oldColumn.getSequence();
                checkDefaultReferencesTable(table, defaultExpression);
                oldColumn.setSequence(null);
                oldColumn.setDefaultExpression(session, defaultExpression);
                removeSequence(table, sequence);
                db.updateMeta(session, table);
                break;
            }
        case CommandInterface.ALTER_TABLE_ALTER_COLUMN_ON_UPDATE:
            {
                checkDefaultReferencesTable(table, defaultExpression);
                oldColumn.setOnUpdateExpression(session, defaultExpression);
                db.updateMeta(session, table);
                break;
            }
        case CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE:
            {
                // and does not affect the storage structure.
                if (oldColumn.isWideningConversion(newColumn)) {
                    convertAutoIncrementColumn(table, newColumn);
                    oldColumn.copy(newColumn);
                    db.updateMeta(session, table);
                } else {
                    oldColumn.setSequence(null);
                    oldColumn.setDefaultExpression(session, null);
                    oldColumn.setConvertNullToDefault(false);
                    if (oldColumn.isNullable() && !newColumn.isNullable()) {
                        checkNoNullValues(table);
                    } else if (!oldColumn.isNullable() && newColumn.isNullable()) {
                        checkNullable(table);
                    }
                    if (oldColumn.getVisible() ^ newColumn.getVisible()) {
                        oldColumn.setVisible(newColumn.getVisible());
                    }
                    convertAutoIncrementColumn(table, newColumn);
                    copyData(table);
                }
                table.setModified();
                break;
            }
        case CommandInterface.ALTER_TABLE_ADD_COLUMN:
            {
                // ifNotExists only supported for single column add
                if (ifNotExists && columnsToAdd != null && columnsToAdd.size() == 1 && table.doesColumnExist(columnsToAdd.get(0).getName())) {
                    break;
                }
                ArrayList<Sequence> sequences = generateSequences(columnsToAdd, false);
                if (columnsToAdd != null) {
                    changePrimaryKeysToNotNull(columnsToAdd);
                }
                copyData(table, sequences, true);
                break;
            }
        case CommandInterface.ALTER_TABLE_DROP_COLUMN:
            {
                if (table.getColumns().length - columnsToRemove.size() < 1) {
                    throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, columnsToRemove.get(0).getSQL());
                }
                table.dropMultipleColumnsConstraintsAndIndexes(session, columnsToRemove);
                copyData(table);
                break;
            }
        case CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY:
            {
                int value = newSelectivity.optimize(session).getValue(session).getInt();
                oldColumn.setSelectivity(value);
                db.updateMeta(session, table);
                break;
            }
        case CommandInterface.ALTER_TABLE_ALTER_COLUMN_VISIBILITY:
            {
                oldColumn.setVisible(newVisibility);
                table.setModified();
                db.updateMeta(session, table);
                break;
            }
        default:
            DbException.throwInternalError("type=" + type);
    }
    return 0;
}
Also used : Table(org.h2.table.Table) Column(org.h2.table.Column) Database(org.h2.engine.Database) ArrayList(java.util.ArrayList) Sequence(org.h2.schema.Sequence)

Example 20 with Update

use of org.h2.command.dml.Update in project h2database by h2database.

the class AlterTableAddConstraint method tryUpdate.

/**
 * Try to execute the statement.
 *
 * @return the update count
 */
private int tryUpdate() {
    if (!transactional) {
        session.commit(true);
    }
    Database db = session.getDatabase();
    Table table = getSchema().findTableOrView(session, tableName);
    if (table == null) {
        if (ifTableExists) {
            return 0;
        }
        throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
    }
    if (getSchema().findConstraint(session, constraintName) != null) {
        if (ifNotExists) {
            return 0;
        }
        throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, constraintName);
    }
    session.getUser().checkRight(table, Right.ALL);
    db.lockMeta(session);
    table.lock(session, true, true);
    Constraint constraint;
    switch(type) {
        case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY:
            {
                IndexColumn.mapColumns(indexColumns, table);
                index = table.findPrimaryKey();
                ArrayList<Constraint> constraints = table.getConstraints();
                for (int i = 0; constraints != null && i < constraints.size(); i++) {
                    Constraint c = constraints.get(i);
                    if (Constraint.Type.PRIMARY_KEY == c.getConstraintType()) {
                        throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
                    }
                }
                if (index != null) {
                    // if there is an index, it must match with the one declared
                    // we don't test ascending / descending
                    IndexColumn[] pkCols = index.getIndexColumns();
                    if (pkCols.length != indexColumns.length) {
                        throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
                    }
                    for (int i = 0; i < pkCols.length; i++) {
                        if (pkCols[i].column != indexColumns[i].column) {
                            throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
                        }
                    }
                }
                if (index == null) {
                    IndexType indexType = IndexType.createPrimaryKey(table.isPersistIndexes(), primaryKeyHash);
                    String indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_PRIMARY_KEY);
                    int id = getObjectId();
                    try {
                        index = table.addIndex(session, indexName, id, indexColumns, indexType, true, null);
                    } finally {
                        getSchema().freeUniqueName(indexName);
                    }
                }
                index.getIndexType().setBelongsToConstraint(true);
                int constraintId = getObjectId();
                String name = generateConstraintName(table);
                ConstraintUnique pk = new ConstraintUnique(getSchema(), constraintId, name, table, true);
                pk.setColumns(indexColumns);
                pk.setIndex(index, true);
                constraint = pk;
                break;
            }
        case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_UNIQUE:
            {
                IndexColumn.mapColumns(indexColumns, table);
                boolean isOwner = false;
                if (index != null && canUseUniqueIndex(index, table, indexColumns)) {
                    isOwner = true;
                    index.getIndexType().setBelongsToConstraint(true);
                } else {
                    index = getUniqueIndex(table, indexColumns);
                    if (index == null) {
                        index = createIndex(table, indexColumns, true);
                        isOwner = true;
                    }
                }
                int id = getObjectId();
                String name = generateConstraintName(table);
                ConstraintUnique unique = new ConstraintUnique(getSchema(), id, name, table, false);
                unique.setColumns(indexColumns);
                unique.setIndex(index, isOwner);
                constraint = unique;
                break;
            }
        case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_CHECK:
            {
                int id = getObjectId();
                String name = generateConstraintName(table);
                ConstraintCheck check = new ConstraintCheck(getSchema(), id, name, table);
                TableFilter filter = new TableFilter(session, table, null, false, null, 0, null);
                checkExpression.mapColumns(filter, 0);
                checkExpression = checkExpression.optimize(session);
                check.setExpression(checkExpression);
                check.setTableFilter(filter);
                constraint = check;
                if (checkExisting) {
                    check.checkExistingData(session);
                }
                break;
            }
        case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_REFERENTIAL:
            {
                Table refTable = refSchema.resolveTableOrView(session, refTableName);
                if (refTable == null) {
                    throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, refTableName);
                }
                session.getUser().checkRight(refTable, Right.ALL);
                if (!refTable.canReference()) {
                    throw DbException.getUnsupportedException("Reference " + refTable.getSQL());
                }
                boolean isOwner = false;
                IndexColumn.mapColumns(indexColumns, table);
                if (index != null && canUseIndex(index, table, indexColumns, false)) {
                    isOwner = true;
                    index.getIndexType().setBelongsToConstraint(true);
                } else {
                    index = getIndex(table, indexColumns, false);
                    if (index == null) {
                        index = createIndex(table, indexColumns, false);
                        isOwner = true;
                    }
                }
                if (refIndexColumns == null) {
                    Index refIdx = refTable.getPrimaryKey();
                    refIndexColumns = refIdx.getIndexColumns();
                } else {
                    IndexColumn.mapColumns(refIndexColumns, refTable);
                }
                if (refIndexColumns.length != indexColumns.length) {
                    throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
                }
                boolean isRefOwner = false;
                if (refIndex != null && refIndex.getTable() == refTable && canUseIndex(refIndex, refTable, refIndexColumns, false)) {
                    isRefOwner = true;
                    refIndex.getIndexType().setBelongsToConstraint(true);
                } else {
                    refIndex = null;
                }
                if (refIndex == null) {
                    refIndex = getIndex(refTable, refIndexColumns, false);
                    if (refIndex == null) {
                        refIndex = createIndex(refTable, refIndexColumns, true);
                        isRefOwner = true;
                    }
                }
                int id = getObjectId();
                String name = generateConstraintName(table);
                ConstraintReferential refConstraint = new ConstraintReferential(getSchema(), id, name, table);
                refConstraint.setColumns(indexColumns);
                refConstraint.setIndex(index, isOwner);
                refConstraint.setRefTable(refTable);
                refConstraint.setRefColumns(refIndexColumns);
                refConstraint.setRefIndex(refIndex, isRefOwner);
                if (checkExisting) {
                    refConstraint.checkExistingData(session);
                }
                refTable.addConstraint(refConstraint);
                refConstraint.setDeleteAction(deleteAction);
                refConstraint.setUpdateAction(updateAction);
                constraint = refConstraint;
                break;
            }
        default:
            throw DbException.throwInternalError("type=" + type);
    }
    // parent relationship is already set with addConstraint
    constraint.setComment(comment);
    if (table.isTemporary() && !table.isGlobalTemporary()) {
        session.addLocalTempTableConstraint(constraint);
    } else {
        db.addSchemaObject(session, constraint);
    }
    table.addConstraint(constraint);
    return 0;
}
Also used : Table(org.h2.table.Table) Constraint(org.h2.constraint.Constraint) TableFilter(org.h2.table.TableFilter) Database(org.h2.engine.Database) ArrayList(java.util.ArrayList) ConstraintUnique(org.h2.constraint.ConstraintUnique) Index(org.h2.index.Index) ConstraintCheck(org.h2.constraint.ConstraintCheck) IndexType(org.h2.index.IndexType) ConstraintReferential(org.h2.constraint.ConstraintReferential)

Aggregations

SQLException (java.sql.SQLException)44 DbException (org.h2.message.DbException)40 Database (org.h2.engine.Database)39 Connection (java.sql.Connection)37 PreparedStatement (java.sql.PreparedStatement)35 Value (org.h2.value.Value)34 ResultSet (java.sql.ResultSet)32 Statement (java.sql.Statement)31 Column (org.h2.table.Column)30 Table (org.h2.table.Table)23 JdbcConnection (org.h2.jdbc.JdbcConnection)22 Expression (org.h2.expression.Expression)19 StatementBuilder (org.h2.util.StatementBuilder)14 ValueExpression (org.h2.expression.ValueExpression)13 ValueString (org.h2.value.ValueString)13 ArrayList (java.util.ArrayList)10 Constraint (org.h2.constraint.Constraint)10 Index (org.h2.index.Index)10 IndexColumn (org.h2.table.IndexColumn)10 Task (org.h2.util.Task)10