public void check(Database database, DatabaseChangeLog changeLog, ChangeSet changeSet)
      throws PreconditionFailedException, PreconditionErrorException {
    Column example = new Column();
    if (StringUtils.trimToNull(getTableName()) != null) {
      example.setRelation(
          new Table()
              .setName(database.correctObjectName(getTableName(), Table.class))
              .setSchema(new Schema(getCatalogName(), getSchemaName())));
    }
    example.setName(database.correctObjectName(getColumnName(), Column.class));

    try {
      if (!SnapshotGeneratorFactory.getInstance().has(example, database)) {
        throw new PreconditionFailedException(
            "Column '"
                + database.escapeColumnName(
                    catalogName, schemaName, getTableName(), getColumnName())
                + "' does not exist",
            changeLog,
            this);
      }
    } catch (LiquibaseException e) {
      throw new PreconditionErrorException(e, changeLog, this);
    }
  }
 @Override
 public void check(Database database, DatabaseChangeLog changeLog, ChangeSet changeSet)
     throws PreconditionFailedException, PreconditionErrorException {
   String currentSchemaName;
   String currentCatalogName;
   try {
     currentCatalogName = getCatalogName();
     currentSchemaName = getSchemaName();
     if (!SnapshotGeneratorFactory.getInstance()
         .has(
             new View()
                 .setName(getViewName())
                 .setSchema(new Schema(currentCatalogName, currentSchemaName)),
             database)) {
       throw new PreconditionFailedException(
           "View "
               + database.escapeTableName(currentCatalogName, currentSchemaName, getViewName())
               + " does not exist",
           changeLog,
           this);
     }
   } catch (PreconditionFailedException e) {
     throw e;
   } catch (Exception e) {
     throw new PreconditionErrorException(e, changeLog, this);
   }
 }
 public boolean hasDatabaseChangeLogLockTable() throws DatabaseException {
   boolean hasTable = false;
   try {
     hasTable = SnapshotGeneratorFactory.getInstance().hasDatabaseChangeLogLockTable(database);
   } catch (LiquibaseException e) {
     throw new UnexpectedLiquibaseException(e);
   }
   return hasTable;
 }
  @Override
  public ChangeStatus checkStatus(Database database) {
    ChangeStatus result = new ChangeStatus();
    try {
      Column column =
          SnapshotGeneratorFactory.getInstance()
              .createSnapshot(
                  new Column(
                      Table.class,
                      getCatalogName(),
                      getSchemaName(),
                      getTableName(),
                      getColumnName()),
                  database);
      if (column == null) {
        return result.unknown("Column " + getColumnName() + " does not exist");
      }

      result.assertComplete(
          column.getDefaultValue() != null, "Column " + getColumnName() + " has no default value");
      if (column.getDefaultValue() == null) {
        return result;
      }

      if (getDefaultValue() != null) {
        return result.assertCorrect(
            getDefaultValue().equals(column.getDefaultValue()),
            "Default value was " + column.getDefaultValue());
      } else if (getDefaultValueDate() != null) {
        return result.assertCorrect(
            getDefaultValueDate()
                .equals(new ISODateFormat().format((Date) column.getDefaultValue())),
            "Default value was " + column.getDefaultValue());
      } else if (getDefaultValueNumeric() != null) {
        return result.assertCorrect(
            getDefaultValueNumeric().equals(column.getDefaultValue().toString()),
            "Default value was " + column.getDefaultValue());
      } else if (getDefaultValueBoolean() != null) {
        return result.assertCorrect(
            getDefaultValueBoolean().equals(column.getDefaultValue()),
            "Default value was " + column.getDefaultValue());
      } else if (getDefaultValueComputed() != null) {
        return result.assertCorrect(
            getDefaultValueComputed().equals(column.getDefaultValue()),
            "Default value was " + column.getDefaultValue());
      } else if (getDefaultValueSequenceNext() != null) {
        return result.assertCorrect(
            getDefaultValueSequenceNext().equals(column.getDefaultValue()),
            "Default value was " + column.getDefaultValue());
      } else {
        return result.unknown("Unknown default value type");
      }
    } catch (Exception e) {
      return result.unknown(e);
    }
  }
  public static void main(String[] args) {

    VerticaDatabase verticaDatabase = new VerticaDatabase();
    liquibase.database.DatabaseFactory.getInstance().register(verticaDatabase);
    liquibase.snapshot.SnapshotGeneratorFactory.getInstance()
        .unregister(UniqueConstraintSnapshotGenerator.class);
    ChangeGeneratorFactory.getInstance().unregister(MissingColumnChangeGenerator.class);
    Properties myProp = new Properties();

    String defaultCatalogName = "yaron_secondary";
    String defaultSchemaName = defaultCatalogName;
    String password = defaultCatalogName + "_123";
    String changeLogFilePath = "c:\\liquibaseChangeSet.xml";
    String dataOutputDirectory = "c:\\liquibase_output";
    String connectionString = "jdbc:vertica://mydphdb0082.hpswlabs.adapps.hp.com:5433/eummobile";
    String changeSetAuthor = "jony";

    myProp.put("user", defaultCatalogName);
    myProp.put("password", password);

    Connection conn = null;
    try {
      File changeLogFile = new File(changeLogFilePath);
      changeLogFile.delete();

      conn = DriverManager.getConnection(connectionString, myProp);
      conn.setAutoCommit(false);
      DatabaseConnection dc = new JdbcConnection(conn);
      verticaDatabase.setConnection(dc);
      String diffTypes = null;
      String changeSetContext = null;
      boolean includeCatalog =
          false; // Boolean.parseBoolean(getCommandParam("includeCatalog", "false"));
      boolean includeSchema =
          false; // Boolean.parseBoolean(getCommandParam("includeSchema", "false"));
      boolean includeTablespace =
          false; // Boolean.parseBoolean(getCommandParam("includeTablespace", "false"));
      DiffOutputControl diffOutputControl =
          new DiffOutputControl(includeCatalog, includeSchema, includeTablespace);
      CommandLineUtils.doGenerateChangeLog(
          changeLogFilePath,
          verticaDatabase,
          defaultCatalogName,
          defaultSchemaName,
          StringUtils.trimToNull(diffTypes),
          StringUtils.trimToNull(changeSetAuthor),
          StringUtils.trimToNull(changeSetContext),
          StringUtils.trimToNull(dataOutputDirectory),
          diffOutputControl);
      postChangeSetGenerationProcessing(changeLogFile);
    } catch (Exception e) {
      e.printStackTrace(); // To change body of catch statement use File | Settings | File
      // Templates.
    }
  }
Beispiel #6
0
 @Override
 public ChangeStatus checkStatus(Database database) {
   try {
     return new ChangeStatus()
         .assertComplete(
             !SnapshotGeneratorFactory.getInstance()
                 .has(new View(getCatalogName(), getSchemaName(), getViewName()), database),
             "View exists");
   } catch (Exception e) {
     return new ChangeStatus().unknown(e);
   }
 }
  @Test
  public void snapshot() throws Exception {
    if (getDatabase() == null) {
      return;
    }

    runCompleteChangeLog();
    DatabaseSnapshot snapshot =
        SnapshotGeneratorFactory.getInstance()
            .createSnapshot(
                getDatabase().getDefaultSchema(),
                getDatabase(),
                new SnapshotControl(getDatabase()));
    System.out.println(snapshot);
  }
 @Override
 public void destroy() throws DatabaseException {
   try {
     if (SnapshotGeneratorFactory.getInstance()
         .has(
             new Table()
                 .setName(database.getDatabaseChangeLogLockTableName())
                 .setSchema(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName()),
             database)) {
       ExecutorService.getInstance()
           .getExecutor(database)
           .execute(
               new DropTableStatement(
                   database.getLiquibaseCatalogName(),
                   database.getLiquibaseSchemaName(),
                   database.getDatabaseChangeLogLockTableName(),
                   false));
     }
   } catch (InvalidExampleException e) {
     throw new UnexpectedLiquibaseException(e);
   }
 }
Beispiel #9
0
  public static List<SqlStatement> getAlterTableStatements(
      AlterTableVisitor alterTableVisitor,
      Database database,
      String catalogName,
      String schemaName,
      String tableName)
      throws DatabaseException {

    DatabaseSnapshot snapshot = null; // todo
    List<SqlStatement> statements = new ArrayList<SqlStatement>();

    Table table = null;
    try {
      table =
          SnapshotGeneratorFactory.getInstance()
              .createSnapshot(
                  (Table)
                      new Table().setName(tableName).setSchema(new Schema(new Catalog(null), null)),
                  database);
    } catch (InvalidExampleException e) {
      throw new UnexpectedLiquibaseException(e);
    }

    List<ColumnConfig> createColumns = new Vector<ColumnConfig>();
    List<ColumnConfig> copyColumns = new Vector<ColumnConfig>();
    if (table != null) {
      for (Column column : table.getColumns()) {
        ColumnConfig new_column = new ColumnConfig(column);
        if (alterTableVisitor.createThisColumn(new_column)) {
          createColumns.add(new_column);
        }
        ColumnConfig copy_column = new ColumnConfig(column);
        if (alterTableVisitor.copyThisColumn(copy_column)) {
          copyColumns.add(copy_column);
        }
      }
    }
    for (ColumnConfig column : alterTableVisitor.getColumnsToAdd()) {
      if (alterTableVisitor.createThisColumn(column)) {
        createColumns.add(column);
      }
      if (alterTableVisitor.copyThisColumn(column)) {
        copyColumns.add(column);
      }
    }

    List<Index> newIndices = new Vector<Index>();
    for (Index index :
        new ArrayList<
            Index>()) { // todo SnapshotGeneratorFactory.getInstance().getGenerator(Index.class,
                        // database).get(new Schema(new Catalog(null), schemaName), database)) {
      if (index.getTable().getName().equalsIgnoreCase(tableName)) {
        if (alterTableVisitor.createThisIndex(index)) {
          newIndices.add(index);
        }
      }
    }

    // rename table
    String temp_table_name = tableName + "_temporary";
    statements.add(new RenameTableStatement(catalogName, schemaName, tableName, temp_table_name));
    // create temporary table
    CreateTableChange ct_change_tmp = new CreateTableChange();
    ct_change_tmp.setSchemaName(schemaName);
    ct_change_tmp.setTableName(tableName);
    for (ColumnConfig column : createColumns) {
      ct_change_tmp.addColumn(column);
    }
    statements.addAll(Arrays.asList(ct_change_tmp.generateStatements(database)));
    // copy rows to temporary table
    statements.add(new CopyRowsStatement(temp_table_name, tableName, copyColumns));
    // delete original table
    statements.add(new DropTableStatement(catalogName, schemaName, temp_table_name, false));
    // validate indices
    statements.add(new ReindexStatement(catalogName, schemaName, tableName));
    // add remaining indices
    for (Index index_config : newIndices) {
      statements.add(
          new CreateIndexStatement(
              index_config.getName(),
              catalogName,
              schemaName,
              tableName,
              index_config.isUnique(),
              index_config.getAssociatedWithAsString(),
              index_config.getColumns().toArray(new String[index_config.getColumns().size()])));
    }

    return statements;
  }
  @Override
  public void checkDatabaseChangeLogTable(
      final boolean updateExistingNullChecksums,
      final DatabaseChangeLog databaseChangeLog,
      final Contexts contexts)
      throws DatabaseException {
    if (updateExistingNullChecksums && databaseChangeLog == null) {
      throw new DatabaseException("changeLog parameter is required if updating existing checksums");
    }

    Executor executor = ExecutorService.getInstance().getExecutor(this);

    Table changeLogTable =
        SnapshotGeneratorFactory.getInstance()
            .getDatabaseChangeLogTable(new SnapshotControl(this, Table.class, Column.class), this);

    List<SqlStatement> statementsToExecute = new ArrayList<SqlStatement>();

    boolean changeLogCreateAttempted = false;
    if (changeLogTable != null) {
      boolean hasDescription = changeLogTable.getColumn("DESCRIPTION") != null;
      boolean hasComments = changeLogTable.getColumn("COMMENTS") != null;
      boolean hasTag = changeLogTable.getColumn("TAG") != null;
      boolean hasLiquibase = changeLogTable.getColumn("LIQUIBASE") != null;
      boolean liquibaseColumnNotRightSize = false;
      if (!getConnection().getDatabaseProductName().equals("SQLite")) {
        liquibaseColumnNotRightSize =
            changeLogTable.getColumn("LIQUIBASE").getType().getColumnSize() != 20;
      }
      boolean hasOrderExecuted = changeLogTable.getColumn("ORDEREXECUTED") != null;
      boolean checksumNotRightSize = false;
      boolean hasExecTypeColumn = changeLogTable.getColumn("EXECTYPE") != null;

      if (!hasDescription) {
        executor.comment("Adding missing databasechangelog.description column");
        statementsToExecute.add(
            new AddColumnStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "DESCRIPTION",
                "VARCHAR(255)",
                null));
      }
      if (!hasTag) {
        executor.comment("Adding missing databasechangelog.tag column");
        statementsToExecute.add(
            new AddColumnStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "TAG",
                "VARCHAR(255)",
                null));
      }
      if (!hasComments) {
        executor.comment("Adding missing databasechangelog.comments column");
        statementsToExecute.add(
            new AddColumnStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "COMMENTS",
                "VARCHAR(255)",
                null));
      }
      if (!hasLiquibase) {
        executor.comment("Adding missing databasechangelog.liquibase column");
        statementsToExecute.add(
            new AddColumnStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "LIQUIBASE",
                "VARCHAR(255)",
                null));
      }
      if (!hasOrderExecuted) {
        executor.comment("Adding missing databasechangelog.orderexecuted column");
        statementsToExecute.add(
            new AddColumnStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "ORDEREXECUTED",
                "INT",
                null));
        statementsToExecute.add(
            new UpdateStatement(
                    getLiquibaseCatalogName(),
                    getLiquibaseSchemaName(),
                    getDatabaseChangeLogTableName())
                .addNewColumnValue("ORDEREXECUTED", -1));
        statementsToExecute.add(
            new SetNullableStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "ORDEREXECUTED",
                "INT",
                false));
      }
      if (checksumNotRightSize) {
        executor.comment("Modifying size of databasechangelog.md5sum column");

        statementsToExecute.add(
            new ModifyDataTypeStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "MD5SUM",
                "VARCHAR(35)"));
      }
      if (liquibaseColumnNotRightSize) {
        executor.comment("Modifying size of databasechangelog.liquibase column");

        statementsToExecute.add(
            new ModifyDataTypeStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "LIQUIBASE",
                "VARCHAR(20)"));
      }
      if (!hasExecTypeColumn) {
        executor.comment("Adding missing databasechangelog.exectype column");
        statementsToExecute.add(
            new AddColumnStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "EXECTYPE",
                "VARCHAR(10)",
                null));
        statementsToExecute.add(
            new UpdateStatement(
                    getLiquibaseCatalogName(),
                    getLiquibaseSchemaName(),
                    getDatabaseChangeLogTableName())
                .addNewColumnValue("EXECTYPE", "EXECUTED"));
        statementsToExecute.add(
            new SetNullableStatement(
                getLiquibaseCatalogName(),
                getLiquibaseSchemaName(),
                getDatabaseChangeLogTableName(),
                "EXECTYPE",
                "VARCHAR(10)",
                false));
      }

      List<Map> md5sumRS =
          ExecutorService.getInstance()
              .getExecutor(this)
              .queryForList(
                  new SelectFromDatabaseChangeLogStatement(
                      new SelectFromDatabaseChangeLogStatement.ByNotNullCheckSum(), "MD5SUM"));
      if (md5sumRS.size() > 0) {
        String md5sum = md5sumRS.get(0).get("MD5SUM").toString();
        if (!md5sum.startsWith(CheckSum.getCurrentVersion() + ":")) {
          executor.comment(
              "DatabaseChangeLog checksums are an incompatible version.  Setting them to null so they will be updated on next database update");
          statementsToExecute.add(
              new RawSqlStatement(
                  "UPDATE "
                      + escapeTableName(
                          getLiquibaseCatalogName(),
                          getLiquibaseSchemaName(),
                          getDatabaseChangeLogTableName())
                      + " SET MD5SUM=null"));
        }
      }

    } else if (!changeLogCreateAttempted) {
      executor.comment("Create Database Change Log Table");
      SqlStatement createTableStatement = new CreateDatabaseChangeLogTableStatement();
      if (!canCreateChangeLogTable()) {
        throw new DatabaseException(
            "Cannot create "
                + escapeTableName(
                    getLiquibaseCatalogName(),
                    getLiquibaseSchemaName(),
                    getDatabaseChangeLogTableName())
                + " table for your database.\n\n"
                + "Please construct it manually using the following SQL as a base and re-run Liquibase:\n\n"
                + createTableStatement);
      }
      // If there is no table in the database for recording change history create one.
      statementsToExecute.add(createTableStatement);
      LogFactory.getLogger()
          .info(
              "Creating database history table with name: "
                  + escapeTableName(
                      getLiquibaseCatalogName(),
                      getLiquibaseSchemaName(),
                      getDatabaseChangeLogTableName()));
      //                }
    }

    for (SqlStatement sql : statementsToExecute) {
      executor.execute(sql);
      this.commit();
    }

    if (updateExistingNullChecksums) {
      for (RanChangeSet ranChangeSet : this.getRanChangeSetList()) {
        if (ranChangeSet.getLastCheckSum() == null) {
          ChangeSet changeSet = databaseChangeLog.getChangeSet(ranChangeSet);
          if (changeSet != null
              && new ContextChangeSetFilter(contexts).accepts(changeSet)
              && new DbmsChangeSetFilter(this).accepts(changeSet)) {
            LogFactory.getLogger()
                .info(
                    "Updating null or out of date checksum on changeSet "
                        + changeSet
                        + " to correct value");
            executor.execute(new UpdateChangeSetChecksumStatement(changeSet));
          }
        }
      }
      commit();
      resetRanChangeSetList();
    }
  }
  /** Drops all objects owned by the connected user. */
  @Override
  public void dropDatabaseObjects(final CatalogAndSchema schemaToDrop) throws LiquibaseException {
    ObjectQuotingStrategy currentStrategy = this.getObjectQuotingStrategy();
    this.setObjectQuotingStrategy(ObjectQuotingStrategy.QUOTE_ALL_OBJECTS);
    try {
      DatabaseSnapshot snapshot;
      try {
        final SnapshotControl snapshotControl = new SnapshotControl(this);
        final Set<Class<? extends DatabaseObject>> typesToInclude =
            snapshotControl.getTypesToInclude();

        // We do not need to remove indexes and primary/unique keys explicitly. They should be
        // removed
        // as part of tables.
        typesToInclude.remove(Index.class);
        typesToInclude.remove(PrimaryKey.class);
        typesToInclude.remove(UniqueConstraint.class);

        if (supportsForeignKeyDisable()) {
          // We do not remove ForeignKey because they will be disabled and removed as parts of
          // tables.
          typesToInclude.remove(ForeignKey.class);
        }

        final long createSnapshotStarted = System.currentTimeMillis();
        snapshot =
            SnapshotGeneratorFactory.getInstance()
                .createSnapshot(schemaToDrop, this, snapshotControl);
        LogFactory.getLogger()
            .debug(
                String.format(
                    "Database snapshot generated in %d ms. Snapshot includes: %s",
                    System.currentTimeMillis() - createSnapshotStarted, typesToInclude));
      } catch (LiquibaseException e) {
        throw new UnexpectedLiquibaseException(e);
      }

      final long changeSetStarted = System.currentTimeMillis();
      DiffResult diffResult =
          DiffGeneratorFactory.getInstance()
              .compare(
                  new EmptyDatabaseSnapshot(this),
                  snapshot,
                  new CompareControl(snapshot.getSnapshotControl().getTypesToInclude()));
      List<ChangeSet> changeSets =
          new DiffToChangeLog(
                  diffResult,
                  new DiffOutputControl(true, true, false).addIncludedSchema(schemaToDrop))
              .generateChangeSets();
      LogFactory.getLogger()
          .debug(
              String.format(
                  "ChangeSet to Remove Database Objects generated in %d ms.",
                  System.currentTimeMillis() - changeSetStarted));

      boolean previousAutoCommit = this.getAutoCommitMode();
      this.commit(); // clear out currently executed statements
      this.setAutoCommit(false); // some DDL doesn't work in autocommit mode
      final boolean reEnableFK = supportsForeignKeyDisable() && disableForeignKeyChecks();
      try {
        for (ChangeSet changeSet : changeSets) {
          changeSet.setFailOnError(false);
          for (Change change : changeSet.getChanges()) {
            if (change instanceof DropTableChange) {
              ((DropTableChange) change).setCascadeConstraints(true);
            }
            SqlStatement[] sqlStatements = change.generateStatements(this);
            for (SqlStatement statement : sqlStatements) {
              ExecutorService.getInstance().getExecutor(this).execute(statement);
            }
          }
          this.commit();
        }
      } finally {
        if (reEnableFK) {
          enableForeignKeyChecks();
        }
      }

      ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(this).destroy();
      LockServiceFactory.getInstance().getLockService(this).destroy();

      this.setAutoCommit(previousAutoCommit);

    } finally {
      this.setObjectQuotingStrategy(currentStrategy);
      this.commit();
    }
  }
  @Override
  public Change[] fixMissing(
      DatabaseObject missingObject,
      DiffOutputControl control,
      Database referenceDatabase,
      Database comparisonDatabase,
      ChangeGeneratorChain chain) {
    List<Change> returnList = new ArrayList<Change>();

    PrimaryKey pk = (PrimaryKey) missingObject;

    AddPrimaryKeyChange change = new AddPrimaryKeyChange();
    change.setTableName(pk.getTable().getName());
    if (control.getIncludeCatalog()) {
      change.setCatalogName(pk.getTable().getSchema().getCatalogName());
    }
    if (control.getIncludeSchema()) {
      change.setSchemaName(pk.getTable().getSchema().getName());
    }
    change.setConstraintName(pk.getName());
    change.setColumnNames(pk.getColumnNames());
    if (control.getIncludeTablespace()) {
      change.setTablespace(pk.getTablespace());
    }

    if (referenceDatabase instanceof MSSQLDatabase
        && pk.getBackingIndex() != null
        && pk.getBackingIndex().getClustered() != null
        && !pk.getBackingIndex().getClustered()) {
      change.setClustered(false);
    }

    if (comparisonDatabase instanceof OracleDatabase
        || (comparisonDatabase instanceof DB2Database
            && pk.getBackingIndex() != null
            && !comparisonDatabase.isSystemObject(pk.getBackingIndex()))) {
      Index backingIndex = pk.getBackingIndex();
      if (backingIndex != null && backingIndex.getName() != null) {
        try {
          if (!control.getIncludeCatalog() && !control.getIncludeSchema()) {
            CatalogAndSchema schema =
                comparisonDatabase.getDefaultSchema().customize(comparisonDatabase);
            backingIndex
                .getTable()
                .setSchema(
                    schema.getCatalogName(),
                    schema
                        .getSchemaName()); // set table schema so it is found in the correct schema
          }
          if (referenceDatabase.equals(comparisonDatabase)
              || !SnapshotGeneratorFactory.getInstance().has(backingIndex, comparisonDatabase)) {
            Change[] fixes =
                ChangeGeneratorFactory.getInstance()
                    .fixMissing(backingIndex, control, referenceDatabase, comparisonDatabase);

            if (fixes != null) {
              for (Change fix : fixes) {
                if (fix != null) {
                  returnList.add(fix);
                }
              }
            }
          }
        } catch (Exception e) {
          throw new UnexpectedLiquibaseException(e);
        }

        change.setForIndexName(backingIndex.getName());
        Schema schema = backingIndex.getSchema();
        if (schema != null) {
          if (control.getIncludeCatalog()) {
            change.setForIndexCatalogName(schema.getCatalogName());
          }
          if (control.getIncludeSchema()) {
            change.setForIndexSchemaName(schema.getName());
          }
        }
      }
    }

    control.setAlreadyHandledMissing(pk.getBackingIndex());
    returnList.add(change);

    return returnList.toArray(new Change[returnList.size()]);
  }