DB2: Migration generation with Reorg table support (#54)

* prototype for reorg table

* DB2 Migration fixes

* Reorg handled by BaseTableDdl

Co-authored-by: Roland Praml <roland.praml@foconis.de>
This commit is contained in:
Roland Praml
2022-01-20 08:22:35 +01:00
committed by GitHub
co-authored by Roland Praml
parent 9f463437c2
commit 68f0c83603
16 changed files with 471 additions and 75 deletions
+7
View File
@@ -76,6 +76,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>jcc</artifactId>
<version>11.5.6.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@@ -35,9 +35,11 @@ import io.ebeaninternal.server.deploy.IdentityMode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static io.ebean.util.StringHelper.replace;
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
@@ -87,7 +89,11 @@ public class BaseTableDdl implements TableDdl {
* columns have been added, removed, included or excluded.
*/
protected final Map<String, HistoryTableUpdate> regenerateHistoryTriggers = new LinkedHashMap<>();
private final Set<String> needsReorg = new HashSet<>();
private int reorgCount;
private final boolean strictMode;
private final HistorySupport historySupport;
@@ -144,25 +150,28 @@ public class BaseTableDdl implements TableDdl {
void writeBefore(DdlBuffer buffer) throws IOException {
if (!before.isEmpty()) {
buffer.end();
flushReorgTables(buffer);
if (withHistory) {
buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
}
for (String ddlScript : before) {
buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
}
}
if (!before.isEmpty() && withHistory) {
buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
}
for (String ddlScript : before) {
buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
}
}
void writeAfter(DdlBuffer buffer) throws IOException {
if (!after.isEmpty() && withHistory) {
buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
}
// here we run post migration scripts
for (String ddlScript : after) {
buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
}
if (!after.isEmpty()) {
if (withHistory) {
buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
}
flushReorgTables(buffer);
// here we run post migration scripts
for (String ddlScript : after) {
buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
}
buffer.end();
}
}
@@ -577,6 +586,7 @@ public class BaseTableDdl implements TableDdl {
@Override
public void generate(DdlWrite writer, CreateIndex index) throws IOException {
if (platformInclude(index.getPlatforms())) {
flushReorgTables(writer.apply());
writer.apply().appendStatement(platformDdl.createIndex(new WriteCreateIndex(index)));
writer.dropAll().appendStatement(platformDdl.dropIndex(index.getIndexName(), index.getTableName(), Boolean.TRUE.equals(index.isConcurrent())));
}
@@ -585,6 +595,7 @@ public class BaseTableDdl implements TableDdl {
@Override
public void generate(DdlWrite writer, DropIndex dropIndex) throws IOException {
if (platformInclude(dropIndex.getPlatforms())) {
flushReorgTables(writer.apply());
writer.apply().appendStatement(platformDdl.dropIndex(dropIndex.getIndexName(), dropIndex.getTableName(), Boolean.TRUE.equals(dropIndex.isConcurrent())));
}
}
@@ -596,6 +607,7 @@ public class BaseTableDdl implements TableDdl {
writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(constraint.getTableName(), constraint.getConstraintName()));
} else {
flushReorgTables(writer.apply());
String[] cols = split(constraint.getColumnNames());
String[] nullableColumns = split(constraint.getNullableColumns());
writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(constraint.getTableName(), constraint.getConstraintName(), cols, nullableColumns));
@@ -648,6 +660,7 @@ public class BaseTableDdl implements TableDdl {
platformDdl.unlockTables(write.applyHistoryTrigger(), regenerateHistoryTriggers.keySet());
}
platformDdl.generateEpilog(write);
flushReorgTables(write.apply());
}
@Override
@@ -838,11 +851,13 @@ public class BaseTableDdl implements TableDdl {
protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) throws IOException {
writer.apply().appendStatement(platformDdl.alterColumnNotnull(alter.getTableName(), alter.getColumnName(), alter.isNotnull()));
needsReorg.add(alter.getTableName());
}
protected void alterColumnType(DdlWrite writer, AlterColumn alter) throws IOException {
String ddl = platformDdl.alterColumnType(alter.getTableName(), alter.getColumnName(), alter.getType());
if (hasValue(ddl)) {
needsReorg.add(alter.getTableName());
writer.apply().appendStatement(ddl);
if (isTrue(alter.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
regenerateHistoryTriggers(alter.getTableName(), HistoryTableUpdate.Change.ALTER, alter.getColumnName());
@@ -884,6 +899,7 @@ public class BaseTableDdl implements TableDdl {
protected void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
platformDdl.alterTableDropColumn(buffer, tableName, columnName);
needsReorg.add(tableName);
}
protected void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable, boolean withHistory) throws IOException {
@@ -903,6 +919,13 @@ public class BaseTableDdl implements TableDdl {
}
}
protected void flushReorgTables(DdlBuffer buffer) throws IOException {
for (String table : needsReorg) {
buffer.appendStatement(platformDdl.reorgTable(table, ++reorgCount));
}
needsReorg.clear();
}
protected boolean isFalse(Boolean value) {
return value != null && !value;
}
@@ -5,44 +5,137 @@ import io.ebean.config.dbplatform.DatabasePlatform;
/**
* DB2 platform specific DDL.
*
* according to the list
* https://datageek.blog/en/2014/05/06/db2-basics-what-is-a-reorg/ a reorg is
* necessary after
* <ol>
* <li>Data type changes that increase the size of a varchar or vargraphic
* column
* <li>Data type changes that decrease the size of a varchar or vargraphic
* column
* <li>Altering a column to include NOT NULL
* <li>Altering a column to inline LOBS
* <li>Altering a column to compress the system default or turn off compression
* for the system default
* <li>Altering a table to enable value compression
* <li>Altering a table to drop a column
* <li>Changing the PCTFREE for a table
* <li>Altering a table to turn APEND mode off
* <li>Altering a table or index to turn compression on
* </ol>
*
* This is currently handled by BaseTableDdl
*
*/
public class DB2Ddl extends PlatformDdl {
public DB2Ddl(DatabasePlatform platform) {
super(platform);
this.dropTableIfExists = "drop table ";
this.dropSequenceIfExists = "drop sequence ";
this.dropConstraintIfExists = "drop constraint";
this.dropIndexIfExists = "drop index ";
this.dropConstraintIfExists = "NOT USED";
this.dropIndexIfExists = "NOT USED";
this.identitySuffix = " generated by default as identity";
this.columnSetNull = "drop not null";
this.columnSetType = "set data type ";
this.inlineUniqueWhenNullable = false;
}
@Override
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns,
String[] nullableColumns) {
StringBuilder sb = new StringBuilder(300);
if (nullableColumns == null || nullableColumns.length == 0) {
return super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
}
sb.append("alter table ").append(lowerTableName(tableName));
sb.append(" add constraint ").append(maxConstraintName(uqName)).append(" unique ");
appendColumns(columns, sb);
return sb.toString();
}
if (uqName == null) {
throw new NullPointerException();
}
StringBuilder sb = new StringBuilder("create unique index ");
sb.append(uqName).append(" on ").append(tableName).append('(');
sb.append("create unique index ").append(maxConstraintName(uqName));
sb.append(" on ").append(lowerTableName(tableName)).append('(');
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
sb.append(",");
}
sb.append(columns[i]);
sb.append(lowerColumnName(columns[i]));
}
sb.append(") exclude null keys");
return sb.toString();
}
@Override
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
return alterTableDropConstraint(tableName, uniqueConstraintName) + "\n"
+ dropIndex(uniqueConstraintName, tableName);
}
@Override
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
// do nothing, no on update clause for db2
}
@Override
public String dropSequence(String sequenceName) {
StringBuilder sb = new StringBuilder(300);
sb.append("delimiter $$\n");
sb.append("begin\n");
sb.append("if exists (select seqschema from syscat.sequences where seqschema = current_schema and seqname = '")
.append(maxConstraintName(sequenceName).toUpperCase()).append("') then\n");
sb.append(" prepare stmt from 'drop sequence ").append(maxConstraintName(sequenceName)).append("';\n");
sb.append(" execute stmt;\n");
sb.append("end if;\n");
sb.append("end$$");
return sb.toString();
}
@Override
public String alterTableDropForeignKey(String tableName, String fkName) {
return alterTableDropConstraint(tableName, fkName);
}
@Override
public String alterTableDropConstraint(String tableName, String constraintName) {
StringBuilder sb = new StringBuilder(300);
sb.append("delimiter $$\n");
sb.append("begin\n");
sb.append("if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = '");
sb.append(maxConstraintName(constraintName).toUpperCase());
sb.append("' and tabname = '").append(lowerTableName(tableName).toUpperCase()).append("') then\n");
sb.append(" prepare stmt from 'alter table ").append(lowerTableName(tableName));
sb.append(" drop constraint ").append(maxConstraintName(constraintName)).append("';\n");
sb.append(" execute stmt;\n");
sb.append("end if;\n");
sb.append("end$$");
return sb.toString();
}
@Override
public String dropIndex(String indexName, String tableName, boolean concurrent) {
StringBuilder sb = new StringBuilder(300);
sb.append("delimiter $$\n");
sb.append("begin\n");
sb.append("if exists (select indname from syscat.indexes where indschema = current_schema and indname = '");
sb.append(maxConstraintName(indexName).toUpperCase()).append("') then\n");
sb.append(" prepare stmt from 'drop index ").append(maxConstraintName(indexName)).append("';\n");
sb.append(" execute stmt;\n");
sb.append("end if;\n");
sb.append("end$$");
return sb.toString();
}
@Override
public String reorgTable(String table, int counter) {
// TODO Auto-generated method stub
return "call sysproc.admin_cmd('reorg table " + lowerTableName(table) + "') /* reorg #" + counter + " */";
}
}
@@ -307,7 +307,7 @@ public class PlatformDdl {
* Return the drop foreign key clause.
*/
public String alterTableDropForeignKey(String tableName, String fkName) {
return "alter table " + alterTableIfExists + tableName + " " + dropConstraintIfExists + " " + maxConstraintName(fkName);
return "alter table " + alterTableIfExists + lowerTableName(tableName) + " " + dropConstraintIfExists + " " + maxConstraintName(fkName);
}
/**
@@ -772,4 +772,15 @@ public class PlatformDdl {
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) throws IOException {
// only supported by postgres initially
}
/**
* Returns a statement to reorganize the table. This is required mainly for DB2.
*
* @param table the table name
* @param counter to make statements unique.
*/
public String reorgTable(String table, int counter) {
return null;
}
}
@@ -108,7 +108,7 @@ public class DbMigrationTest extends BaseTestCase {
// Oracle caches the statement and does not detect schema change. It fails with
// an ORA-01007
if (isOracle()) {
if (isOracle() || isDB2()) {
result = server().sqlQuery("select * from migtest_e_basic order by id,id").findList();
} else {
result = server().sqlQuery("select * from migtest_e_basic order by id").findList();
@@ -51,6 +51,10 @@ public abstract class BaseTestCase {
public boolean isSqlServer() {
return Platform.SQLSERVER == platform();
}
public boolean isDB2() {
return Platform.DB2 == platform();
}
public boolean isH2() {
return Platform.H2 == platform();
@@ -5,6 +5,7 @@ import io.ebean.annotation.DbMigration;
import io.ebean.annotation.EnumValue;
import io.ebean.annotation.Index;
import io.ebean.annotation.NotNull;
import io.ebean.annotation.Platform;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -59,10 +60,11 @@ public class EBasic {
@Size(max=127)
String name;
@DbMigration(preAlter = { "-- db2 does not support parial null indices :( - so we have to clean",
"update ${table} set status = 'N' where id = 1" }, platforms = Platform.DB2)
@DbMigration(preAlter = "-- rename all collisions")
@Column(unique = true)
@Size(max=127)
@Size(max = 127)
String description;
//@NotNull
@@ -1,12 +1,16 @@
ebean.ddl.header=-- Generated by ebean ${version} at ${timestamp}
ebean.ddl.generate=true
ebean.ddl.run=true
datasource.default=h2
ebean.ddl.generate=false
ebean.ddl.run=false
datasource.default=db2
datasource.h2.username=sa
datasource.h2.password=
datasource.h2.url=jdbc:h2:mem:h2AutoTune
datasource.db2.username=migtest
datasource.db2.password=migtest
datasource.db2.url=jdbc:db2://localhost:50005/migtest
datasource.pg.username=sa
datasource.pg.password=
datasource.pg.url=jdbc:h2:mem:h2AutoTune
@@ -75,7 +75,9 @@ create table migtest_e_basic (
constraint ck_migtest_e_basic_status2 check ( status2 in ('N','A','I')),
constraint pk_migtest_e_basic primary key (id)
);
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_indextest2 on migtest_e_basic(indextest2) exclude null keys;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_indextest6 on migtest_e_basic(indextest6) exclude null keys;
create table migtest_e_enum (
@@ -129,6 +131,7 @@ create table migtest_e_ref (
name varchar(127) not null,
constraint pk_migtest_e_ref primary key (id)
);
-- alterTableAddUniqueConstraint
alter table migtest_e_ref add constraint uq_migtest_e_ref_name unique (name);
create table migtest_e_softdelete (
@@ -75,7 +75,9 @@ create table migtest_e_basic (
constraint ck_migtest_e_basic_status2 check ( status2 in ('N','A','I')),
constraint pk_migtest_e_basic primary key (id)
);
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_indextest2 on migtest_e_basic(indextest2) exclude null keys;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_indextest6 on migtest_e_basic(indextest6) exclude null keys;
create table migtest_e_enum (
@@ -129,6 +131,7 @@ create table migtest_e_ref (
name varchar(127) not null,
constraint pk_migtest_e_ref primary key (id)
);
-- alterTableAddUniqueConstraint
alter table migtest_e_ref add constraint uq_migtest_e_ref_name unique (name);
create table migtest_e_softdelete (
@@ -23,31 +23,59 @@ alter table migtest_ckey_detail add column two_key varchar(127);
alter table migtest_ckey_detail add constraint fk_migtest_ckey_detail_parent foreign key (one_key,two_key) references migtest_ckey_parent (one_key,two_key) on delete restrict;
alter table migtest_ckey_parent add column assoc_id integer;
alter table migtest_fk_cascade drop constraint fk_migtest_fk_cascade_one_id;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'FK_MIGTEST_FK_CASCADE_ONE_ID' and tabname = 'MIGTEST_FK_CASCADE') then
prepare stmt from 'alter table migtest_fk_cascade drop constraint fk_migtest_fk_cascade_one_id';
execute stmt;
end if;
end$$;
alter table migtest_fk_cascade add constraint fk_migtest_fk_cascade_one_id foreign key (one_id) references migtest_fk_cascade_one (id) on delete restrict;
alter table migtest_fk_none add constraint fk_migtest_fk_none_one_id foreign key (one_id) references migtest_fk_one (id) on delete restrict;
alter table migtest_fk_none_via_join add constraint fk_migtest_fk_none_via_join_one_id foreign key (one_id) references migtest_fk_one (id) on delete restrict;
alter table migtest_fk_set_null drop constraint fk_migtest_fk_set_null_one_id;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'FK_MIGTEST_FK_SET_NULL_ONE_ID' and tabname = 'MIGTEST_FK_SET_NULL') then
prepare stmt from 'alter table migtest_fk_set_null drop constraint fk_migtest_fk_set_null_one_id';
execute stmt;
end if;
end$$;
alter table migtest_fk_set_null add constraint fk_migtest_fk_set_null_one_id foreign key (one_id) references migtest_fk_one (id) on delete restrict;
update migtest_e_basic set status = 'A' where status is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'CK_MIGTEST_E_BASIC_STATUS' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint ck_migtest_e_basic_status';
execute stmt;
end if;
end$$;
alter table migtest_e_basic alter column status set default 'A';
alter table migtest_e_basic alter column status set not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status2;
alter table migtest_e_basic alter column status2 varchar(127);
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'CK_MIGTEST_E_BASIC_STATUS2' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint ck_migtest_e_basic_status2';
execute stmt;
end if;
end$$;
alter table migtest_e_basic alter column status2 set data type varchar(127);
alter table migtest_e_basic alter column status2 drop default;
alter table migtest_e_basic alter column status2 set null;
alter table migtest_e_basic alter column status2 drop not null;
-- rename all collisions;
call sysproc.admin_cmd('reorg table migtest_e_basic') /* reorg #1 */;
-- db2 does not support parial null indices :( - so we have to clean;
update migtest_e_basic set status = 'N' where id = 1;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_description on migtest_e_basic(description) exclude null keys;
insert into migtest_e_user (id) select distinct user_id from migtest_e_basic;
alter table migtest_e_basic add constraint fk_migtest_e_basic_user_id foreign key (user_id) references migtest_e_user (id) on delete restrict;
alter table migtest_e_basic alter column user_id set null;
alter table migtest_e_basic alter column user_id drop not null;
alter table migtest_e_basic add column new_string_field varchar(255) default 'foo''bar' not null;
alter table migtest_e_basic add column new_boolean_field boolean default true not null;
call sysproc.admin_cmd('reorg table migtest_e_basic') /* reorg #2 */;
update migtest_e_basic set new_boolean_field = old_boolean;
alter table migtest_e_basic add column new_boolean_field2 boolean default true not null;
@@ -55,17 +83,54 @@ alter table migtest_e_basic add column progress integer default 0 not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_progress check ( progress in (0,1,2));
alter table migtest_e_basic add column new_integer integer default 42 not null;
alter table migtest_e_basic drop constraint uq_migtest_e_basic_indextest2;
alter table migtest_e_basic drop constraint uq_migtest_e_basic_indextest6;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'UQ_MIGTEST_E_BASIC_INDEXTEST2' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint uq_migtest_e_basic_indextest2';
execute stmt;
end if;
end$$
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'UQ_MIGTEST_E_BASIC_INDEXTEST2') then
prepare stmt from 'drop index uq_migtest_e_basic_indextest2';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'UQ_MIGTEST_E_BASIC_INDEXTEST6' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint uq_migtest_e_basic_indextest6';
execute stmt;
end if;
end$$
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'UQ_MIGTEST_E_BASIC_INDEXTEST6') then
prepare stmt from 'drop index uq_migtest_e_basic_indextest6';
execute stmt;
end if;
end$$;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_status_indextest1 on migtest_e_basic(status,indextest1) exclude null keys;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_name on migtest_e_basic(name) exclude null keys;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_indextest4 on migtest_e_basic(indextest4) exclude null keys;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_indextest5 on migtest_e_basic(indextest5) exclude null keys;
alter table migtest_e_enum drop constraint ck_migtest_e_enum_test_status;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'CK_MIGTEST_E_ENUM_TEST_STATUS' and tabname = 'MIGTEST_E_ENUM') then
prepare stmt from 'alter table migtest_e_enum drop constraint ck_migtest_e_enum_test_status';
execute stmt;
end if;
end$$;
comment on column migtest_e_history.test_string is 'Column altered to long now';
alter table migtest_e_history alter column test_string bigint;
alter table migtest_e_history alter column test_string set data type bigint;
comment on table migtest_e_history is 'We have history now';
call sysproc.admin_cmd('reorg table migtest_e_history') /* reorg #3 */;
-- NOTE: table has @History - special migration may be necessary
update migtest_e_history2 set test_string = 'unknown' where test_string is null;
alter table migtest_e_history2 alter column test_string set default 'unknown';
@@ -74,23 +139,38 @@ alter table migtest_e_history2 add column test_string2 varchar(255);
alter table migtest_e_history2 add column test_string3 varchar(255) default 'unknown' not null;
alter table migtest_e_history2 add column new_column varchar(20);
alter table migtest_e_history4 alter column test_number bigint;
alter table migtest_e_history4 alter column test_number set data type bigint;
alter table migtest_e_history5 add column test_boolean boolean default false not null;
call sysproc.admin_cmd('reorg table migtest_e_history2') /* reorg #4 */;
call sysproc.admin_cmd('reorg table migtest_e_history4') /* reorg #5 */;
-- NOTE: table has @History - special migration may be necessary
update migtest_e_history6 set test_number1 = 42 where test_number1 is null;
alter table migtest_e_history6 alter column test_number1 set default 42;
alter table migtest_e_history6 alter column test_number1 set not null;
alter table migtest_e_history6 alter column test_number2 set null;
alter table migtest_e_history6 alter column test_number2 drop not null;
alter table migtest_e_softdelete add column deleted boolean default false not null;
alter table migtest_oto_child add column master_id bigint;
call sysproc.admin_cmd('reorg table migtest_e_history6') /* reorg #6 */;
create index ix_migtest_e_basic_indextest3 on migtest_e_basic (indextest3);
create index ix_migtest_e_basic_indextest6 on migtest_e_basic (indextest6);
drop index ix_migtest_e_basic_indextest1;
drop index ix_migtest_e_basic_indextest5;
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'IX_MIGTEST_E_BASIC_INDEXTEST1') then
prepare stmt from 'drop index ix_migtest_e_basic_indextest1';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'IX_MIGTEST_E_BASIC_INDEXTEST5') then
prepare stmt from 'drop index ix_migtest_e_basic_indextest5';
execute stmt;
end if;
end$$;
create index ix_migtest_mtm_c_migtest_mtm_m_migtest_mtm_c on migtest_mtm_c_migtest_mtm_m (migtest_mtm_c_id);
alter table migtest_mtm_c_migtest_mtm_m add constraint fk_migtest_mtm_c_migtest_mtm_m_migtest_mtm_c foreign key (migtest_mtm_c_id) references migtest_mtm_c (id) on delete restrict;
@@ -11,4 +11,12 @@ alter table migtest_e_history2 drop column obsolete_string1;
alter table migtest_e_history2 drop column obsolete_string2;
drop table migtest_e_ref;
drop sequence migtest_e_ref_seq;
delimiter $$
begin
if exists (select seqschema from syscat.sequences where seqschema = current_schema and seqname = 'MIGTEST_E_REF_SEQ') then
prepare stmt from 'drop sequence migtest_e_ref_seq';
execute stmt;
end if;
end$$;
call sysproc.admin_cmd('reorg table migtest_e_history2') /* reorg #1 */;
call sysproc.admin_cmd('reorg table migtest_e_basic') /* reorg #2 */;
@@ -5,63 +5,204 @@ create table migtest_e_ref (
name varchar(127) not null,
constraint pk_migtest_e_ref primary key (id)
);
-- alterTableAddUniqueConstraint
alter table migtest_e_ref add constraint uq_migtest_e_ref_name unique (name);
alter table migtest_ckey_detail drop constraint fk_migtest_ckey_detail_parent;
alter table migtest_fk_cascade drop constraint fk_migtest_fk_cascade_one_id;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'FK_MIGTEST_CKEY_DETAIL_PARENT' and tabname = 'MIGTEST_CKEY_DETAIL') then
prepare stmt from 'alter table migtest_ckey_detail drop constraint fk_migtest_ckey_detail_parent';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'FK_MIGTEST_FK_CASCADE_ONE_ID' and tabname = 'MIGTEST_FK_CASCADE') then
prepare stmt from 'alter table migtest_fk_cascade drop constraint fk_migtest_fk_cascade_one_id';
execute stmt;
end if;
end$$;
alter table migtest_fk_cascade add constraint fk_migtest_fk_cascade_one_id foreign key (one_id) references migtest_fk_cascade_one (id) on delete cascade;
alter table migtest_fk_none drop constraint fk_migtest_fk_none_one_id;
alter table migtest_fk_none_via_join drop constraint fk_migtest_fk_none_via_join_one_id;
alter table migtest_fk_set_null drop constraint fk_migtest_fk_set_null_one_id;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'FK_MIGTEST_FK_NONE_ONE_ID' and tabname = 'MIGTEST_FK_NONE') then
prepare stmt from 'alter table migtest_fk_none drop constraint fk_migtest_fk_none_one_id';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'FK_MIGTEST_FK_NONE_VIA_JOIN_ONE_ID' and tabname = 'MIGTEST_FK_NONE_VIA_JOIN') then
prepare stmt from 'alter table migtest_fk_none_via_join drop constraint fk_migtest_fk_none_via_join_one_id';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'FK_MIGTEST_FK_SET_NULL_ONE_ID' and tabname = 'MIGTEST_FK_SET_NULL') then
prepare stmt from 'alter table migtest_fk_set_null drop constraint fk_migtest_fk_set_null_one_id';
execute stmt;
end if;
end$$;
alter table migtest_fk_set_null add constraint fk_migtest_fk_set_null_one_id foreign key (one_id) references migtest_fk_one (id) on delete set null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'CK_MIGTEST_E_BASIC_STATUS' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint ck_migtest_e_basic_status';
execute stmt;
end if;
end$$;
alter table migtest_e_basic alter column status drop default;
alter table migtest_e_basic alter column status set null;
alter table migtest_e_basic alter column status drop not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I'));
call sysproc.admin_cmd('reorg table migtest_e_basic') /* reorg #1 */;
update migtest_e_basic set status2 = 'N' where status2 is null;
alter table migtest_e_basic drop constraint ck_migtest_e_basic_status2;
alter table migtest_e_basic alter column status2 varchar(1);
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'CK_MIGTEST_E_BASIC_STATUS2' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint ck_migtest_e_basic_status2';
execute stmt;
end if;
end$$;
alter table migtest_e_basic alter column status2 set data type varchar(1);
alter table migtest_e_basic alter column status2 set default 'N';
alter table migtest_e_basic alter column status2 set not null;
alter table migtest_e_basic add constraint ck_migtest_e_basic_status2 check ( status2 in ('N','A','I'));
alter table migtest_e_basic drop constraint uq_migtest_e_basic_description;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'UQ_MIGTEST_E_BASIC_DESCRIPTION' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint uq_migtest_e_basic_description';
execute stmt;
end if;
end$$
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'UQ_MIGTEST_E_BASIC_DESCRIPTION') then
prepare stmt from 'drop index uq_migtest_e_basic_description';
execute stmt;
end if;
end$$;
call sysproc.admin_cmd('reorg table migtest_e_basic') /* reorg #2 */;
update migtest_e_basic set user_id = 23 where user_id is null;
alter table migtest_e_basic drop constraint fk_migtest_e_basic_user_id;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'FK_MIGTEST_E_BASIC_USER_ID' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint fk_migtest_e_basic_user_id';
execute stmt;
end if;
end$$;
alter table migtest_e_basic alter column user_id set default 23;
alter table migtest_e_basic alter column user_id set not null;
alter table migtest_e_basic add column old_boolean boolean default false not null;
alter table migtest_e_basic add column old_boolean2 boolean;
alter table migtest_e_basic add column eref_id integer;
alter table migtest_e_basic drop constraint uq_migtest_e_basic_status_indextest1;
alter table migtest_e_basic drop constraint uq_migtest_e_basic_name;
alter table migtest_e_basic drop constraint uq_migtest_e_basic_indextest4;
alter table migtest_e_basic drop constraint uq_migtest_e_basic_indextest5;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'UQ_MIGTEST_E_BASIC_STATUS_INDEXTEST1' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint uq_migtest_e_basic_status_indextest1';
execute stmt;
end if;
end$$
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'UQ_MIGTEST_E_BASIC_STATUS_INDEXTEST1') then
prepare stmt from 'drop index uq_migtest_e_basic_status_indextest1';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'UQ_MIGTEST_E_BASIC_NAME' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint uq_migtest_e_basic_name';
execute stmt;
end if;
end$$
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'UQ_MIGTEST_E_BASIC_NAME') then
prepare stmt from 'drop index uq_migtest_e_basic_name';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'UQ_MIGTEST_E_BASIC_INDEXTEST4' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint uq_migtest_e_basic_indextest4';
execute stmt;
end if;
end$$
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'UQ_MIGTEST_E_BASIC_INDEXTEST4') then
prepare stmt from 'drop index uq_migtest_e_basic_indextest4';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'UQ_MIGTEST_E_BASIC_INDEXTEST5' and tabname = 'MIGTEST_E_BASIC') then
prepare stmt from 'alter table migtest_e_basic drop constraint uq_migtest_e_basic_indextest5';
execute stmt;
end if;
end$$
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'UQ_MIGTEST_E_BASIC_INDEXTEST5') then
prepare stmt from 'drop index uq_migtest_e_basic_indextest5';
execute stmt;
end if;
end$$;
call sysproc.admin_cmd('reorg table migtest_e_basic') /* reorg #3 */;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_indextest2 on migtest_e_basic(indextest2) exclude null keys;
-- alterTableAddUniqueConstraint
create unique index uq_migtest_e_basic_indextest6 on migtest_e_basic(indextest6) exclude null keys;
alter table migtest_e_enum drop constraint ck_migtest_e_enum_test_status;
delimiter $$
begin
if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = 'CK_MIGTEST_E_ENUM_TEST_STATUS' and tabname = 'MIGTEST_E_ENUM') then
prepare stmt from 'alter table migtest_e_enum drop constraint ck_migtest_e_enum_test_status';
execute stmt;
end if;
end$$;
alter table migtest_e_enum add constraint ck_migtest_e_enum_test_status check ( test_status in ('N','A','I'));
comment on column migtest_e_history.test_string is '';
comment on table migtest_e_history is '';
alter table migtest_e_history2 alter column test_string drop default;
alter table migtest_e_history2 alter column test_string set null;
alter table migtest_e_history2 alter column test_string drop not null;
alter table migtest_e_history2 add column obsolete_string1 varchar(255);
alter table migtest_e_history2 add column obsolete_string2 varchar(255);
alter table migtest_e_history4 alter column test_number integer;
alter table migtest_e_history4 alter column test_number set data type integer;
alter table migtest_e_history6 alter column test_number1 drop default;
alter table migtest_e_history6 alter column test_number1 set null;
alter table migtest_e_history6 alter column test_number1 drop not null;
call sysproc.admin_cmd('reorg table migtest_e_history2') /* reorg #4 */;
call sysproc.admin_cmd('reorg table migtest_e_history6') /* reorg #5 */;
call sysproc.admin_cmd('reorg table migtest_e_history4') /* reorg #6 */;
-- NOTE: table has @History - special migration may be necessary
update migtest_e_history6 set test_number2 = 7 where test_number2 is null;
alter table migtest_e_history6 alter column test_number2 set default 7;
alter table migtest_e_history6 alter column test_number2 set not null;
call sysproc.admin_cmd('reorg table migtest_e_history6') /* reorg #7 */;
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
drop index ix_migtest_e_basic_indextest3;
drop index ix_migtest_e_basic_indextest6;
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'IX_MIGTEST_E_BASIC_INDEXTEST3') then
prepare stmt from 'drop index ix_migtest_e_basic_indextest3';
execute stmt;
end if;
end$$;
delimiter $$
begin
if exists (select indname from syscat.indexes where indschema = current_schema and indname = 'IX_MIGTEST_E_BASIC_INDEXTEST6') then
prepare stmt from 'drop index ix_migtest_e_basic_indextest6';
execute stmt;
end if;
end$$;
create index ix_migtest_e_basic_eref_id on migtest_e_basic (eref_id);
alter table migtest_e_basic add constraint fk_migtest_e_basic_eref_id foreign key (eref_id) references migtest_e_ref (id) on delete restrict;
@@ -29,6 +29,19 @@ alter table migtest_e_softdelete drop column deleted;
alter table migtest_oto_child drop column master_id;
drop table migtest_e_user;
drop sequence migtest_e_user_seq;
delimiter $$
begin
if exists (select seqschema from syscat.sequences where seqschema = current_schema and seqname = 'MIGTEST_E_USER_SEQ') then
prepare stmt from 'drop sequence migtest_e_user_seq';
execute stmt;
end if;
end$$;
drop table migtest_mtm_c_migtest_mtm_m;
drop table migtest_mtm_m_migtest_mtm_c;
call sysproc.admin_cmd('reorg table migtest_e_history2') /* reorg #1 */;
call sysproc.admin_cmd('reorg table migtest_e_softdelete') /* reorg #2 */;
call sysproc.admin_cmd('reorg table migtest_oto_child') /* reorg #3 */;
call sysproc.admin_cmd('reorg table migtest_ckey_parent') /* reorg #4 */;
call sysproc.admin_cmd('reorg table migtest_e_history5') /* reorg #5 */;
call sysproc.admin_cmd('reorg table migtest_ckey_detail') /* reorg #6 */;
call sysproc.admin_cmd('reorg table migtest_e_basic') /* reorg #7 */;
@@ -1,6 +1,6 @@
1580812656, 1.0__initial.sql
-522424232, 1.1.sql
578073685, 1.2__dropsFor_1.1.sql
-1685257725, 1.3.sql
-1475628451, 1.4__dropsFor_1.3.sql
997100585, 1.0__initial.sql
855187652, 1.1.sql
1091886546, 1.2__dropsFor_1.1.sql
-364921922, 1.3.sql
2020621716, 1.4__dropsFor_1.3.sql
@@ -16,6 +16,10 @@
<alterColumn columnName="status" tableName="migtest_e_basic" currentType="varchar(1)" defaultValue="'A'" notnull="true" currentNotnull="false" checkConstraint="check ( status in ('N','A','I','?'))" checkConstraintName="ck_migtest_e_basic_status"/>
<alterColumn columnName="status2" tableName="migtest_e_basic" type="varchar(127)" currentType="varchar(1)" defaultValue="DROP DEFAULT" notnull="false" currentNotnull="true" dropCheckConstraint="ck_migtest_e_basic_status2"/>
<alterColumn columnName="description" tableName="migtest_e_basic" unique="uq_migtest_e_basic_description">
<before platforms="db2">
<ddl>-- db2 does not support parial null indices :( - so we have to clean</ddl>
<ddl>update ${table} set status = 'N' where id = 1</ddl>
</before>
<before>
<ddl>-- rename all collisions</ddl>
</before>