mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
FIX: optimized unique constraint handling for platforms that does support them on nullable columns (#1095)
This commit is contained in:
committed by
Rob Bygrave
parent
f471961f06
commit
d14529b602
@@ -207,9 +207,12 @@ public class BaseTableDdl implements TableDdl {
|
||||
String tableName = createTable.getName();
|
||||
for (Column col : externalUnique) {
|
||||
String uqName = col.getUniqueOneToOne();
|
||||
if (uqName == null) {
|
||||
uqName = col.getUnique();
|
||||
}
|
||||
String[] columnNames = {col.getName()};
|
||||
write.apply()
|
||||
.append(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames))
|
||||
.append(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, Boolean.TRUE.equals(col.isNotnull())))
|
||||
.endOfStatement();
|
||||
|
||||
write.dropAllForeignKeys()
|
||||
@@ -221,7 +224,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
String uqName = constraint.getName();
|
||||
String[] columnNames = StringHelper.delimitedToArray(constraint.getColumnNames(), ",", false);
|
||||
write.apply()
|
||||
.append(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames))
|
||||
.append(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, false)) // TODO: check if nullable
|
||||
.endOfStatement();
|
||||
|
||||
write.dropAllForeignKeys()
|
||||
@@ -421,9 +424,9 @@ public class BaseTableDdl implements TableDdl {
|
||||
protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
|
||||
List<UniqueConstraint> uniqueConstraints = createTable.getUniqueConstraint();
|
||||
boolean inlineUniqueCompound = platformDdl.isInlineUniqueOneToOne();
|
||||
boolean inlineUniqueWhenNull = platformDdl.isInlineUniqueWhenNullable();
|
||||
for (UniqueConstraint uniqueConstraint : uniqueConstraints) {
|
||||
if (inlineUniqueCompound) {
|
||||
if (inlineUniqueWhenNull) {
|
||||
String uqName = uniqueConstraint.getName();
|
||||
String[] columns = toColumnNamesSplit(uniqueConstraint.getColumnNames());
|
||||
apply.append(",").newLine();
|
||||
@@ -440,17 +443,18 @@ public class BaseTableDdl implements TableDdl {
|
||||
*/
|
||||
protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
|
||||
boolean inlineUniqueOneToOne = platformDdl.isInlineUniqueOneToOne();
|
||||
boolean inlineUniqueWhenNullable = platformDdl.isInlineUniqueWhenNullable();
|
||||
|
||||
List<Column> columns = createTable.getColumn();
|
||||
for (Column column : columns) {
|
||||
if (hasValue(column.getUnique()) || (inlineUniqueOneToOne && hasValue(column.getUniqueOneToOne()))) {
|
||||
// normal mechanism for adding unique constraint
|
||||
inlineUniqueConstraintSingle(apply, column);
|
||||
|
||||
} else if (!inlineUniqueOneToOne && hasValue(column.getUniqueOneToOne())) {
|
||||
// MsSqlServer specific mechanism for adding unique constraints (that allow nulls)
|
||||
externalUnique.add(column);
|
||||
if (hasValue(column.getUnique()) || hasValue(column.getUniqueOneToOne())) {
|
||||
if (Boolean.TRUE.equals(column.isNotnull()) || inlineUniqueWhenNullable) {
|
||||
// normal mechanism for adding unique constraint
|
||||
inlineUniqueConstraintSingle(apply, column);
|
||||
} else {
|
||||
// MsSqlServer & DB2 specific mechanism for adding unique constraints (that allow nulls)
|
||||
externalUnique.add(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -834,9 +838,9 @@ public class BaseTableDdl implements TableDdl {
|
||||
protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter, String uqName) throws IOException {
|
||||
|
||||
String[] cols = {alter.getColumnName()};
|
||||
|
||||
boolean notNull = alter.isNotnull() != null ? alter.isNotnull() : Boolean.TRUE.equals(alter.isNotnull());
|
||||
writer.apply()
|
||||
.append(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols))
|
||||
.append(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols, notNull))
|
||||
.endOfStatement();
|
||||
|
||||
writer.dropAllForeignKeys()
|
||||
|
||||
@@ -10,6 +10,16 @@ public class DB2Ddl extends PlatformDdl {
|
||||
public DB2Ddl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.identitySuffix = " generated by default as identity";
|
||||
this.inlineUniqueWhenNullable = false;
|
||||
}
|
||||
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, boolean notNull) {
|
||||
if (notNull) {
|
||||
return super.alterTableAddUniqueConstraint(tableName, uqName, columns, true);
|
||||
} else {
|
||||
// Hmm: Complex workaround: https://www.ibm.com/developerworks/mydeveloperworks/blogs/SQLTips4DB2LUW/entry/unique_where_not_null_indexes26?lang=en
|
||||
return "-- NOT SUPPORTED " + super.alterTableAddUniqueConstraint(tableName, uqName, columns, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public class PlatformDdl {
|
||||
/**
|
||||
* Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
|
||||
*/
|
||||
protected boolean inlineUniqueOneToOne = true;
|
||||
protected boolean inlineUniqueWhenNullable = true;
|
||||
|
||||
protected DbConstraintNaming naming;
|
||||
|
||||
@@ -371,7 +371,7 @@ public class PlatformDdl {
|
||||
* <p>
|
||||
* Overridden by MsSqlServer for specific null handling on unique constraints.
|
||||
*/
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns) {
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, boolean notNull) {
|
||||
|
||||
StringBuilder buffer = new StringBuilder(90);
|
||||
buffer.append("alter table ").append(tableName).append(" add constraint ").append(uqName).append(" unique ");
|
||||
@@ -401,11 +401,12 @@ public class PlatformDdl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if unique constraints for OneToOne can be inlined as normal.
|
||||
* Returns false for MsSqlServer due to it's null handling for unique constraints.
|
||||
* Return true if unique constraints for nullable columns can be inlined as normal.
|
||||
* Returns false for MsSqlServer & DB2 due to it's not possible to to put a constraint
|
||||
* on a nullable column
|
||||
*/
|
||||
public boolean isInlineUniqueOneToOne() {
|
||||
return inlineUniqueOneToOne;
|
||||
public boolean isInlineUniqueWhenNullable() {
|
||||
return inlineUniqueWhenNullable;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
this.foreignKeyRestrict = "";
|
||||
this.alterTableIfExists = "";
|
||||
this.addColumn = "add";
|
||||
this.inlineUniqueOneToOne = false;
|
||||
this.inlineUniqueWhenNullable = false;
|
||||
this.columnSetDefault = "add default";
|
||||
this.dropConstraintIfExists = "drop constraint";
|
||||
this.historyDdl = new SqlServerHistoryDdl();
|
||||
@@ -51,8 +51,13 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
* MsSqlServer specific null handling on unique constraints.
|
||||
*/
|
||||
@Override
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns) {
|
||||
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, boolean notNull) {
|
||||
if (notNull) {
|
||||
return super.alterTableAddUniqueConstraint(tableName, uqName, columns, notNull);
|
||||
}
|
||||
if (uqName == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
// issues#233
|
||||
String start = "create unique nonclustered index " + uqName + " on " + tableName + "(";
|
||||
StringBuilder sb = new StringBuilder(start);
|
||||
|
||||
Reference in New Issue
Block a user