Search in sources :

Example 16 with Index

use of org.h2.index.Index in project h2database by h2database.

the class Parser method parseAlterTable.

private Prepared parseAlterTable() {
    boolean ifTableExists = readIfExists(false);
    String tableName = readIdentifierWithSchema();
    Schema schema = getSchema();
    if (readIf("ADD")) {
        Prepared command = parseAlterTableAddConstraintIf(tableName, schema, ifTableExists);
        if (command != null) {
            return command;
        }
        return parseAlterTableAddColumn(tableName, schema, ifTableExists);
    } else if (readIf("SET")) {
        read("REFERENTIAL_INTEGRITY");
        int type = CommandInterface.ALTER_TABLE_SET_REFERENTIAL_INTEGRITY;
        boolean value = readBooleanSetting();
        AlterTableSet command = new AlterTableSet(session, schema, type, value);
        command.setTableName(tableName);
        command.setIfTableExists(ifTableExists);
        if (readIf("CHECK")) {
            command.setCheckExisting(true);
        } else if (readIf("NOCHECK")) {
            command.setCheckExisting(false);
        }
        return command;
    } else if (readIf("RENAME")) {
        if (readIf("COLUMN")) {
            // PostgreSQL syntax
            String columnName = readColumnIdentifier();
            read("TO");
            AlterTableRenameColumn command = new AlterTableRenameColumn(session, schema);
            command.setTableName(tableName);
            command.setIfTableExists(ifTableExists);
            command.setOldColumnName(columnName);
            String newName = readColumnIdentifier();
            command.setNewColumnName(newName);
            return command;
        } else if (readIf("CONSTRAINT")) {
            String constraintName = readIdentifierWithSchema(schema.getName());
            checkSchema(schema);
            read("TO");
            AlterTableRenameConstraint command = new AlterTableRenameConstraint(session, schema);
            command.setConstraintName(constraintName);
            String newName = readColumnIdentifier();
            command.setNewConstraintName(newName);
            return commandIfTableExists(schema, tableName, ifTableExists, command);
        } else {
            read("TO");
            String newName = readIdentifierWithSchema(schema.getName());
            checkSchema(schema);
            AlterTableRename command = new AlterTableRename(session, getSchema());
            command.setOldTableName(tableName);
            command.setNewTableName(newName);
            command.setIfTableExists(ifTableExists);
            command.setHidden(readIf("HIDDEN"));
            return command;
        }
    } else if (readIf("DROP")) {
        if (readIf("CONSTRAINT")) {
            boolean ifExists = readIfExists(false);
            String constraintName = readIdentifierWithSchema(schema.getName());
            ifExists = readIfExists(ifExists);
            checkSchema(schema);
            AlterTableDropConstraint command = new AlterTableDropConstraint(session, getSchema(), ifExists);
            command.setConstraintName(constraintName);
            return commandIfTableExists(schema, tableName, ifTableExists, command);
        } else if (readIf("FOREIGN")) {
            // MySQL compatibility
            read("KEY");
            String constraintName = readIdentifierWithSchema(schema.getName());
            checkSchema(schema);
            AlterTableDropConstraint command = new AlterTableDropConstraint(session, getSchema(), false);
            command.setConstraintName(constraintName);
            return commandIfTableExists(schema, tableName, ifTableExists, command);
        } else if (readIf("INDEX")) {
            // MySQL compatibility
            String indexOrConstraintName = readIdentifierWithSchema();
            final SchemaCommand command;
            if (schema.findIndex(session, indexOrConstraintName) != null) {
                DropIndex dropIndexCommand = new DropIndex(session, getSchema());
                dropIndexCommand.setIndexName(indexOrConstraintName);
                command = dropIndexCommand;
            } else {
                AlterTableDropConstraint dropCommand = new AlterTableDropConstraint(session, getSchema(), false);
                dropCommand.setConstraintName(indexOrConstraintName);
                command = dropCommand;
            }
            return commandIfTableExists(schema, tableName, ifTableExists, command);
        } else if (readIf("PRIMARY")) {
            read("KEY");
            Table table = tableIfTableExists(schema, tableName, ifTableExists);
            if (table == null) {
                return new NoOperation(session);
            }
            Index idx = table.getPrimaryKey();
            DropIndex command = new DropIndex(session, schema);
            command.setIndexName(idx.getName());
            return command;
        } else {
            readIf("COLUMN");
            boolean ifExists = readIfExists(false);
            ArrayList<Column> columnsToRemove = New.arrayList();
            Table table = tableIfTableExists(schema, tableName, ifTableExists);
            // For Oracle compatibility - open bracket required
            boolean openingBracketDetected = readIf("(");
            do {
                String columnName = readColumnIdentifier();
                if (table != null) {
                    if (!ifExists || table.doesColumnExist(columnName)) {
                        Column column = table.getColumn(columnName);
                        columnsToRemove.add(column);
                    }
                }
            } while (readIf(","));
            if (openingBracketDetected) {
                // For Oracle compatibility - close bracket
                read(")");
            }
            if (table == null || columnsToRemove.isEmpty()) {
                return new NoOperation(session);
            }
            AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
            command.setType(CommandInterface.ALTER_TABLE_DROP_COLUMN);
            command.setTableName(tableName);
            command.setIfTableExists(ifTableExists);
            command.setColumnsToRemove(columnsToRemove);
            return command;
        }
    } else if (readIf("CHANGE")) {
        // MySQL compatibility
        readIf("COLUMN");
        String columnName = readColumnIdentifier();
        String newColumnName = readColumnIdentifier();
        Column column = columnIfTableExists(schema, tableName, columnName, ifTableExists);
        boolean nullable = column == null ? true : column.isNullable();
        // new column type ignored. RENAME and MODIFY are
        // a single command in MySQL but two different commands in H2.
        parseColumnForTable(newColumnName, nullable);
        AlterTableRenameColumn command = new AlterTableRenameColumn(session, schema);
        command.setTableName(tableName);
        command.setIfTableExists(ifTableExists);
        command.setOldColumnName(columnName);
        command.setNewColumnName(newColumnName);
        return command;
    } else if (readIf("MODIFY")) {
        // MySQL compatibility (optional)
        readIf("COLUMN");
        // Oracle specifies (but will not require) an opening parenthesis
        boolean hasOpeningBracket = readIf("(");
        String columnName = readColumnIdentifier();
        AlterTableAlterColumn command = null;
        NullConstraintType nullConstraint = parseNotNullConstraint();
        switch(nullConstraint) {
            case NULL_IS_ALLOWED:
            case NULL_IS_NOT_ALLOWED:
                command = new AlterTableAlterColumn(session, schema);
                command.setTableName(tableName);
                command.setIfTableExists(ifTableExists);
                Column column = columnIfTableExists(schema, tableName, columnName, ifTableExists);
                command.setOldColumn(column);
                if (nullConstraint == NullConstraintType.NULL_IS_ALLOWED) {
                    command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL);
                } else {
                    command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL);
                }
                break;
            case NO_NULL_CONSTRAINT_FOUND:
                command = parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
                break;
            default:
                throw DbException.get(ErrorCode.UNKNOWN_MODE_1, "Internal Error - unhandled case: " + nullConstraint.name());
        }
        if (hasOpeningBracket) {
            read(")");
        }
        return command;
    } else if (readIf("ALTER")) {
        readIf("COLUMN");
        String columnName = readColumnIdentifier();
        Column column = columnIfTableExists(schema, tableName, columnName, ifTableExists);
        if (readIf("RENAME")) {
            read("TO");
            AlterTableRenameColumn command = new AlterTableRenameColumn(session, schema);
            command.setTableName(tableName);
            command.setIfTableExists(ifTableExists);
            command.setOldColumnName(columnName);
            String newName = readColumnIdentifier();
            command.setNewColumnName(newName);
            return command;
        } else if (readIf("DROP")) {
            // PostgreSQL compatibility
            if (readIf("DEFAULT")) {
                AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
                command.setTableName(tableName);
                command.setIfTableExists(ifTableExists);
                command.setOldColumn(column);
                command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT);
                command.setDefaultExpression(null);
                return command;
            }
            if (readIf("ON")) {
                read("UPDATE");
                AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
                command.setTableName(tableName);
                command.setIfTableExists(ifTableExists);
                command.setOldColumn(column);
                command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_ON_UPDATE);
                command.setDefaultExpression(null);
                return command;
            }
            read("NOT");
            read("NULL");
            AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
            command.setTableName(tableName);
            command.setIfTableExists(ifTableExists);
            command.setOldColumn(column);
            command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL);
            return command;
        } else if (readIf("TYPE")) {
            // PostgreSQL compatibility
            return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
        } else if (readIf("SET")) {
            if (readIf("DATA")) {
                // Derby compatibility
                read("TYPE");
                return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
            }
            AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
            command.setTableName(tableName);
            command.setIfTableExists(ifTableExists);
            command.setOldColumn(column);
            NullConstraintType nullConstraint = parseNotNullConstraint();
            switch(nullConstraint) {
                case NULL_IS_ALLOWED:
                    command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL);
                    break;
                case NULL_IS_NOT_ALLOWED:
                    command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL);
                    break;
                case NO_NULL_CONSTRAINT_FOUND:
                    if (readIf("DEFAULT")) {
                        Expression defaultExpression = readExpression();
                        command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT);
                        command.setDefaultExpression(defaultExpression);
                    } else if (readIf("ON")) {
                        read("UPDATE");
                        Expression onUpdateExpression = readExpression();
                        command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_ON_UPDATE);
                        command.setDefaultExpression(onUpdateExpression);
                    } else if (readIf("INVISIBLE")) {
                        command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_VISIBILITY);
                        command.setVisible(false);
                    } else if (readIf("VISIBLE")) {
                        command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_VISIBILITY);
                        command.setVisible(true);
                    }
                    break;
                default:
                    throw DbException.get(ErrorCode.UNKNOWN_MODE_1, "Internal Error - unhandled case: " + nullConstraint.name());
            }
            return command;
        } else if (readIf("RESTART")) {
            readIf("WITH");
            Expression start = readExpression();
            AlterSequence command = new AlterSequence(session, schema);
            command.setColumn(column);
            command.setStartWith(start);
            return commandIfTableExists(schema, tableName, ifTableExists, command);
        } else if (readIf("SELECTIVITY")) {
            AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
            command.setTableName(tableName);
            command.setIfTableExists(ifTableExists);
            command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY);
            command.setOldColumn(column);
            command.setSelectivity(readExpression());
            return command;
        } else {
            return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
        }
    }
    throw getSyntaxError();
}
Also used : AlterSequence(org.h2.command.dml.AlterSequence) RangeTable(org.h2.table.RangeTable) TruncateTable(org.h2.command.ddl.TruncateTable) CreateTable(org.h2.command.ddl.CreateTable) FunctionTable(org.h2.table.FunctionTable) CreateLinkedTable(org.h2.command.ddl.CreateLinkedTable) Table(org.h2.table.Table) DropTable(org.h2.command.ddl.DropTable) DropSchema(org.h2.command.ddl.DropSchema) CreateSchema(org.h2.command.ddl.CreateSchema) Schema(org.h2.schema.Schema) AlterTableRename(org.h2.command.ddl.AlterTableRename) DropIndex(org.h2.command.ddl.DropIndex) Index(org.h2.index.Index) CreateIndex(org.h2.command.ddl.CreateIndex) ValueString(org.h2.value.ValueString) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) SchemaCommand(org.h2.command.ddl.SchemaCommand) AlterTableSet(org.h2.command.dml.AlterTableSet) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) NoOperation(org.h2.command.dml.NoOperation) 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) AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) DropIndex(org.h2.command.ddl.DropIndex)

Example 17 with Index

use of org.h2.index.Index 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 18 with Index

use of org.h2.index.Index in project h2database by h2database.

the class AlterTableAlterColumn method cloneTableStructure.

private Table cloneTableStructure(Table table, Column[] columns, Database db, String tempName, ArrayList<Column> newColumns) {
    for (Column col : columns) {
        newColumns.add(col.getClone());
    }
    if (type == CommandInterface.ALTER_TABLE_DROP_COLUMN) {
        for (Column removeCol : columnsToRemove) {
            Column foundCol = null;
            for (Column newCol : newColumns) {
                if (newCol.getName().equals(removeCol.getName())) {
                    foundCol = newCol;
                    break;
                }
            }
            if (foundCol == null) {
                throw DbException.throwInternalError(removeCol.getCreateSQL());
            }
            newColumns.remove(foundCol);
        }
    } else if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN) {
        int position;
        if (addFirst) {
            position = 0;
        } else if (addBefore != null) {
            position = table.getColumn(addBefore).getColumnId();
        } else if (addAfter != null) {
            position = table.getColumn(addAfter).getColumnId() + 1;
        } else {
            position = columns.length;
        }
        if (columnsToAdd != null) {
            for (Column column : columnsToAdd) {
                newColumns.add(position++, column);
            }
        }
    } else if (type == CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE) {
        int position = oldColumn.getColumnId();
        newColumns.set(position, newColumn);
    }
    // create a table object in order to get the SQL statement
    // can't just use this table, because most column objects are 'shared'
    // with the old table
    // still need a new id because using 0 would mean: the new table tries
    // to use the rows of the table 0 (the meta table)
    int id = db.allocateObjectId();
    CreateTableData data = new CreateTableData();
    data.tableName = tempName;
    data.id = id;
    data.columns = newColumns;
    data.temporary = table.isTemporary();
    data.persistData = table.isPersistData();
    data.persistIndexes = table.isPersistIndexes();
    data.isHidden = table.isHidden();
    data.create = true;
    data.session = session;
    Table newTable = getSchema().createTable(data);
    newTable.setComment(table.getComment());
    StringBuilder buff = new StringBuilder();
    buff.append(newTable.getCreateSQL());
    StringBuilder columnList = new StringBuilder();
    for (Column nc : newColumns) {
        if (columnList.length() > 0) {
            columnList.append(", ");
        }
        if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN && columnsToAdd != null && columnsToAdd.contains(nc)) {
            Expression def = nc.getDefaultExpression();
            columnList.append(def == null ? "NULL" : def.getSQL());
        } else {
            columnList.append(nc.getSQL());
        }
    }
    buff.append(" AS SELECT ");
    if (columnList.length() == 0) {
        // special case: insert into test select * from
        buff.append('*');
    } else {
        buff.append(columnList);
    }
    buff.append(" FROM ").append(table.getSQL());
    String newTableSQL = buff.toString();
    String newTableName = newTable.getName();
    Schema newTableSchema = newTable.getSchema();
    newTable.removeChildrenAndResources(session);
    execute(newTableSQL, true);
    newTable = newTableSchema.getTableOrView(session, newTableName);
    ArrayList<String> triggers = New.arrayList();
    for (DbObject child : table.getChildren()) {
        if (child instanceof Sequence) {
            continue;
        } else if (child instanceof Index) {
            Index idx = (Index) child;
            if (idx.getIndexType().getBelongsToConstraint()) {
                continue;
            }
        }
        String createSQL = child.getCreateSQL();
        if (createSQL == null) {
            continue;
        }
        if (child instanceof TableView) {
            continue;
        } else if (child.getType() == DbObject.TABLE_OR_VIEW) {
            DbException.throwInternalError();
        }
        String quotedName = Parser.quoteIdentifier(tempName + "_" + child.getName());
        String sql = null;
        if (child instanceof ConstraintReferential) {
            ConstraintReferential r = (ConstraintReferential) child;
            if (r.getTable() != table) {
                sql = r.getCreateSQLForCopy(r.getTable(), newTable, quotedName, false);
            }
        }
        if (sql == null) {
            sql = child.getCreateSQLForCopy(newTable, quotedName);
        }
        if (sql != null) {
            if (child instanceof TriggerObject) {
                triggers.add(sql);
            } else {
                execute(sql, true);
            }
        }
    }
    table.setModified();
    // otherwise the sequence is dropped if the table is dropped
    for (Column col : newColumns) {
        Sequence seq = col.getSequence();
        if (seq != null) {
            table.removeSequence(seq);
            col.setSequence(null);
        }
    }
    for (String sql : triggers) {
        execute(sql, true);
    }
    return newTable;
}
Also used : Table(org.h2.table.Table) DbObject(org.h2.engine.DbObject) Schema(org.h2.schema.Schema) TriggerObject(org.h2.schema.TriggerObject) Index(org.h2.index.Index) Sequence(org.h2.schema.Sequence) ConstraintReferential(org.h2.constraint.ConstraintReferential) Constraint(org.h2.constraint.Constraint) Column(org.h2.table.Column) Expression(org.h2.expression.Expression) TableView(org.h2.table.TableView)

Example 19 with Index

use of org.h2.index.Index in project h2database by h2database.

the class AlterTableAlterColumn method copyData.

private void copyData(Table table, ArrayList<Sequence> sequences, boolean createConstraints) {
    if (table.isTemporary()) {
        throw DbException.getUnsupportedException("TEMP TABLE");
    }
    Database db = session.getDatabase();
    String baseName = table.getName();
    String tempName = db.getTempTableName(baseName, session);
    Column[] columns = table.getColumns();
    ArrayList<Column> newColumns = New.arrayList();
    Table newTable = cloneTableStructure(table, columns, db, tempName, newColumns);
    if (sequences != null) {
        for (Sequence sequence : sequences) {
            table.addSequence(sequence);
        }
    }
    try {
        // check if a view would become invalid
        // (because the column to drop is referenced or so)
        checkViews(table, newTable);
    } catch (DbException e) {
        execute("DROP TABLE " + newTable.getName(), true);
        throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage());
    }
    String tableName = table.getName();
    ArrayList<TableView> dependentViews = new ArrayList<>(table.getDependentViews());
    for (TableView view : dependentViews) {
        table.removeDependentView(view);
    }
    execute("DROP TABLE " + table.getSQL() + " IGNORE", true);
    db.renameSchemaObject(session, newTable, tableName);
    for (DbObject child : newTable.getChildren()) {
        if (child instanceof Sequence) {
            continue;
        }
        String name = child.getName();
        if (name == null || child.getCreateSQL() == null) {
            continue;
        }
        if (name.startsWith(tempName + "_")) {
            name = name.substring(tempName.length() + 1);
            SchemaObject so = (SchemaObject) child;
            if (so instanceof Constraint) {
                if (so.getSchema().findConstraint(session, name) != null) {
                    name = so.getSchema().getUniqueConstraintName(session, newTable);
                }
            } else if (so instanceof Index) {
                if (so.getSchema().findIndex(session, name) != null) {
                    name = so.getSchema().getUniqueIndexName(session, newTable, name);
                }
            }
            db.renameSchemaObject(session, so, name);
        }
    }
    if (createConstraints) {
        createConstraints();
    }
    for (TableView view : dependentViews) {
        String sql = view.getCreateSQL(true, true);
        execute(sql, true);
    }
}
Also used : SchemaObject(org.h2.schema.SchemaObject) Table(org.h2.table.Table) DbObject(org.h2.engine.DbObject) Constraint(org.h2.constraint.Constraint) ArrayList(java.util.ArrayList) Index(org.h2.index.Index) Sequence(org.h2.schema.Sequence) DbException(org.h2.message.DbException) Column(org.h2.table.Column) Database(org.h2.engine.Database) TableView(org.h2.table.TableView)

Example 20 with Index

use of org.h2.index.Index 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

ResultSet (java.sql.ResultSet)77 Index (org.h2.index.Index)75 Statement (java.sql.Statement)64 SimpleResultSet (org.h2.tools.SimpleResultSet)61 SQLException (java.sql.SQLException)60 Value (org.h2.value.Value)58 DbException (org.h2.message.DbException)57 Connection (java.sql.Connection)56 PreparedStatement (java.sql.PreparedStatement)56 Column (org.h2.table.Column)53 IndexColumn (org.h2.table.IndexColumn)45 ArrayList (java.util.ArrayList)31 ValueString (org.h2.value.ValueString)29 Constraint (org.h2.constraint.Constraint)25 Row (org.h2.result.Row)22 MultiVersionIndex (org.h2.index.MultiVersionIndex)19 JdbcConnection (org.h2.jdbc.JdbcConnection)19 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)18 Table (org.h2.table.Table)18 HashSet (java.util.HashSet)17