Fix check constraint support for MariaDB >= 10.2.1 (#1668)

* fixed the check constraint support for mysql/mariadb

* update migration scripts
This commit is contained in:
Roland Praml
2019-04-09 19:38:57 +12:00
committed by Rob Bygrave
parent f4db7ca0bb
commit 65a62bf683
9 changed files with 75 additions and 47 deletions
@@ -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();
@@ -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
@@ -25,10 +25,4 @@ public class ClickHouseTableDdl extends BaseTableDdl {
// do nothing
}
@Override
protected void writeCheckConstraints(DdlBuffer apply, CreateTable createTable) {
// do nothing
}
}
@@ -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
@@ -213,10 +213,22 @@ public class PlatformDdl {
*/
public void writeTableColumns(DdlBuffer apply, List<Column> 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.
*/
@@ -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)
);
@@ -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)
);
@@ -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;
@@ -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);