diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java index 1de59a353..f82021634 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java @@ -262,7 +262,6 @@ public class BaseTableDdl implements TableDdl { DdlBuffer apply = writer.apply(); apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(tableName).append(" ("); writeTableColumns(apply, columns, useIdentity); - writeCheckConstraints(apply, createTable); writeUniqueConstraints(apply, createTable); writeCompoundUniqueConstraints(apply, createTable); if (!pk.isEmpty()) { @@ -506,31 +505,6 @@ public class BaseTableDdl implements TableDdl { buffer.appendStatement(platformDdl.dropSequence(sequenceName)); } - /** - * Write all the check constraints. - */ - protected void writeCheckConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { - - for (Column column : createTable.getColumn()) { - String checkConstraint = column.getCheckConstraint(); - if (hasValue(checkConstraint)) { - writeCheckConstraint(apply, column, checkConstraint); - } - } - } - - /** - * Write a check constraint. - */ - protected void writeCheckConstraint(DdlBuffer buffer, Column column, String checkConstraint) throws IOException { - - String ckName = column.getCheckConstraintName(); - - buffer.append(",").newLine(); - buffer.append(" constraint ").append(ckName); - buffer.append(" ").append(checkConstraint); - } - protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { boolean inlineUniqueWhenNull = platformDdl.isInlineUniqueWhenNullable(); diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java index 0c680f3eb..bb96d613a 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java @@ -64,6 +64,11 @@ public class ClickHouseDdl extends PlatformDdl { return null; } + @Override + public String createCheckConstraint(String ckName, String checkConstraint) { + return null; + } + @Override protected void writeColumnNotNull(DdlBuffer buffer) { // do nothing diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseTableDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseTableDdl.java index b959d1ff7..c8c432856 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseTableDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseTableDdl.java @@ -25,10 +25,4 @@ public class ClickHouseTableDdl extends BaseTableDdl { // do nothing } - - @Override - protected void writeCheckConstraints(DdlBuffer apply, CreateTable createTable) { - // do nothing - } - } diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java index eb69d3be3..46ed420eb 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java @@ -14,6 +14,10 @@ import java.util.Collection; */ public class MySqlDdl extends PlatformDdl { + // check constraint support is disabled by default. See https://groups.google.com/forum/#!topic/ebean/luFN-2xBkUw + // this flag is for compatibility. Use it with care. + private static final boolean USE_CHECK_CONSTRAINT = Boolean.getBoolean("ebean.mysql.useCheckConstraint"); + public MySqlDdl(DatabasePlatform platform) { super(platform); this.alterColumn = "modify"; @@ -48,11 +52,40 @@ public class MySqlDdl extends PlatformDdl { buffer.append("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')").endOfStatement(); } + @Override + public String createCheckConstraint(String ckName, String checkConstraint) { + if (USE_CHECK_CONSTRAINT) { + return super.createCheckConstraint(ckName, checkConstraint); + } else { + return null; + } + } + @Override + public String alterTableAddCheckConstraint(String tableName, String checkConstraintName, String checkConstraint) { + if (USE_CHECK_CONSTRAINT) { + return super.alterTableAddCheckConstraint(tableName, checkConstraintName, checkConstraint); + } else { + return null; + } + } + @Override public String alterTableDropConstraint(String tableName, String constraintName) { - // drop constraint not supported in MySQL 5.7 and 8.0 but starting with MariaDB 10.2.1 CHECK is evaluated - // TODO: Implement for MariaDB >= 10.2.1 - return null; + // drop constraint not supported in MySQL 5.7 and 8.0 but starting with MariaDB + // 10.2.1 CHECK is evaluated + if (USE_CHECK_CONSTRAINT) { + StringBuilder sb = new StringBuilder(); + // statement for MySQL >= 8.0.16 + sb.append("/*!80016 alter table ").append(tableName); + sb.append(" drop check ").append(constraintName).append(" */;\n"); + // statement for MariaDB >= 10.2.1 + sb.append("/*M!100201 "); + sb.append(super.alterTableDropConstraint(tableName, constraintName)); + sb.append(" */"); + return sb.toString(); + } else { + return null; + } } @Override diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java index d76c6bd44..2ca3d3ccc 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java @@ -213,10 +213,22 @@ public class PlatformDdl { */ public void writeTableColumns(DdlBuffer apply, List columns, boolean useIdentity) throws IOException { for (int i = 0; i < columns.size(); i++) { + if (i > 0) { + apply.append(","); + } apply.newLine(); writeColumnDefinition(apply, columns.get(i), useIdentity); - if (i < columns.size() - 1) { - apply.append(","); + } + + for (Column column : columns) { + String checkConstraint = column.getCheckConstraint(); + if (hasValue(checkConstraint)) { + checkConstraint = createCheckConstraint(maxConstraintName(column.getCheckConstraintName()), + checkConstraint); + if (hasValue(checkConstraint)) { + apply.append(",").newLine(); + apply.append(checkConstraint); + } } } } @@ -253,6 +265,13 @@ public class PlatformDdl { buffer.append(" not null"); } + /** + * Returns the check constraint. + */ + public String createCheckConstraint(String ckName, String checkConstraint) { + return " constraint " + ckName + " " + checkConstraint; + } + /** * Convert the DB column default literal to platform specific. */ @@ -494,7 +513,9 @@ public class PlatformDdl { if (!StringHelper.isNull(column.getCheckConstraint())) { String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), column.getCheckConstraint()); - buffer.append(ddl).endOfStatement(); + if (hasValue(ddl)) { + buffer.append(ddl).endOfStatement(); + } } } else { buffer.append(addColumnSuffix); @@ -580,7 +601,7 @@ public class PlatformDdl { } protected void appendWithSpace(String content, StringBuilder buffer) { - if (content != null && !content.isEmpty()) { + if (hasValue(content)) { buffer.append(" ").append(content); } } @@ -613,6 +634,13 @@ public class PlatformDdl { return updateNullWithDefault; } + /** + * Return true if null or trimmed string is empty. + */ + protected boolean hasValue(String value) { + return value != null && !value.trim().isEmpty(); + } + /** * Null safe Boolean true test. */ diff --git a/src/test/resources/dbmigration/migrationtest/db2/1.0__initial.sql b/src/test/resources/dbmigration/migrationtest/db2/1.0__initial.sql index b1046c7bf..239b28462 100644 --- a/src/test/resources/dbmigration/migrationtest/db2/1.0__initial.sql +++ b/src/test/resources/dbmigration/migrationtest/db2/1.0__initial.sql @@ -70,7 +70,7 @@ create table migtest_e_basic ( indextest5 varchar(127), indextest6 varchar(127), user_id integer not null, - constraint ck_migtest_e_basic_status check ( status in ('N','A','I')), + constraint ck_mgtst__bsc_stts check ( status in ('N','A','I')), constraint pk_migtest_e_basic primary key (id) ); -- NOT SUPPORTED alter table migtest_e_basic add constraint uq_mgtst__b_4aybzy unique (indextest2); @@ -79,7 +79,7 @@ create table migtest_e_basic ( create table migtest_e_enum ( id integer generated by default as identity not null, test_status varchar(1), - constraint ck_migtest_e_enum_test_status check ( test_status in ('N','A','I')), + constraint ck_mgtst__n_773sok check ( test_status in ('N','A','I')), constraint pk_migtest_e_enum primary key (id) ); diff --git a/src/test/resources/dbmigration/migrationtest/mysql/1.0__initial.sql b/src/test/resources/dbmigration/migrationtest/mysql/1.0__initial.sql index ef52ebb7c..e5e98049b 100644 --- a/src/test/resources/dbmigration/migrationtest/mysql/1.0__initial.sql +++ b/src/test/resources/dbmigration/migrationtest/mysql/1.0__initial.sql @@ -70,7 +70,6 @@ create table migtest_e_basic ( indextest5 varchar(127), indextest6 varchar(127), user_id integer not null, - constraint ck_migtest_e_basic_status check ( status in ('N','A','I')), constraint uq_migtest_e_basic_indextest2 unique (indextest2), constraint uq_migtest_e_basic_indextest6 unique (indextest6), constraint pk_migtest_e_basic primary key (id) @@ -79,7 +78,6 @@ create table migtest_e_basic ( create table migtest_e_enum ( id integer auto_increment not null, test_status varchar(1), - constraint ck_migtest_e_enum_test_status check ( test_status in ('N','A','I')), constraint pk_migtest_e_enum primary key (id) ); diff --git a/src/test/resources/dbmigration/migrationtest/mysql/1.1.sql b/src/test/resources/dbmigration/migrationtest/mysql/1.1.sql index 45ea3f4b6..ecc42a6ef 100644 --- a/src/test/resources/dbmigration/migrationtest/mysql/1.1.sql +++ b/src/test/resources/dbmigration/migrationtest/mysql/1.1.sql @@ -39,7 +39,6 @@ alter table migtest_fk_set_null add constraint fk_migtest_fk_set_null_one_id for update migtest_e_basic set status = 'A' where status is null; alter table migtest_e_basic alter status set default 'A'; alter table migtest_e_basic modify status varchar(1) not null; -alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?')); -- rename all collisions; alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description); @@ -53,7 +52,6 @@ update migtest_e_basic set new_boolean_field = old_boolean; alter table migtest_e_basic add column new_boolean_field2 tinyint(1) default 1 not null; 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 index uq_migtest_e_basic_indextest2; diff --git a/src/test/resources/dbmigration/migrationtest/mysql/1.3.sql b/src/test/resources/dbmigration/migrationtest/mysql/1.3.sql index 7365a52ce..da05d955b 100644 --- a/src/test/resources/dbmigration/migrationtest/mysql/1.3.sql +++ b/src/test/resources/dbmigration/migrationtest/mysql/1.3.sql @@ -20,7 +20,6 @@ alter table migtest_fk_none_via_join drop foreign key fk_migtest_fk_none_via_joi alter table migtest_fk_set_null drop foreign key fk_migtest_fk_set_null_one_id; 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 on update set null; alter table migtest_e_basic alter status drop default; -alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I')); alter table migtest_e_basic drop index uq_migtest_e_basic_description; update migtest_e_basic set user_id = 23 where user_id is null; @@ -37,7 +36,6 @@ alter table migtest_e_basic drop index uq_migtest_e_basic_indextest4; alter table migtest_e_basic drop index uq_migtest_e_basic_indextest5; alter table migtest_e_basic add constraint uq_migtest_e_basic_indextest2 unique (indextest2); alter table migtest_e_basic add constraint uq_migtest_e_basic_indextest6 unique (indextest6); -alter table migtest_e_enum add constraint ck_migtest_e_enum_test_status check ( test_status in ('N','A','I')); alter table migtest_e_history comment = ''; alter table migtest_e_history2 alter test_string drop default; alter table migtest_e_history2 add column obsolete_string1 varchar(255);