Use unique index rather than constraint when using formula [like lower(column)]

This commit is contained in:
rob bygrave
2020-01-15 16:58:55 +13:00
parent 099adcf6cd
commit bb56725b12
14 changed files with 84 additions and 39 deletions
@@ -451,7 +451,7 @@ public class BaseTableDdl implements TableDdl {
String tableName = lowerTableName(request.table());
if (request.indexName() != null) {
// no matching unique constraint so add the index
fkeyBuffer.appendStatement(platformDdl.createIndex(request.indexName(), tableName, request.cols()));
fkeyBuffer.appendStatement(platformDdl.createIndex(request.indexName(), tableName, request.cols(), false));
}
alterTableAddForeignKey(write.getOptions(), fkeyBuffer, request);
@@ -609,10 +609,10 @@ public class BaseTableDdl implements TableDdl {
}
@Override
public void generate(DdlWrite writer, CreateIndex createIndex) throws IOException {
if (platformInclude(createIndex.getPlatforms())) {
writer.apply().appendStatement(platformDdl.createIndex(createIndex.getIndexName(), createIndex.getTableName(), split(createIndex.getColumns())));
writer.dropAll().appendStatement(platformDdl.dropIndex(createIndex.getIndexName(), createIndex.getTableName()));
public void generate(DdlWrite writer, CreateIndex index) throws IOException {
if (platformInclude(index.getPlatforms())) {
writer.apply().appendStatement(platformDdl.createIndex(index.getIndexName(), index.getTableName(), split(index.getColumns()), Boolean.TRUE.equals(index.isUnique())));
writer.dropAll().appendStatement(platformDdl.dropIndex(index.getIndexName(), index.getTableName()));
}
}
@@ -61,7 +61,7 @@ public class ClickHouseDdl extends PlatformDdl {
}
@Override
public String createIndex(String indexName, String tableName, String[] columns) {
public String createIndex(String indexName, String tableName, String[] columns, boolean unique) {
return null;
}
@@ -13,7 +13,7 @@ public class HanaColumnStoreDdl extends AbstractHanaDdl {
}
@Override
public String createIndex(String indexName, String tableName, String[] columns) {
public String createIndex(String indexName, String tableName, String[] columns, boolean unique) {
if (columns == null || columns.length == 0) {
return "-- cannot create index: no columns given";
}
@@ -109,6 +109,8 @@ public class PlatformDdl {
protected String addForeignKeySkipCheck = "";
protected String uniqueIndex = "unique";
/**
* Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
*/
@@ -389,12 +391,14 @@ public class PlatformDdl {
/**
* Return the create index statement.
*/
public String createIndex(String indexName, String tableName, String[] columns) {
public String createIndex(String indexName, String tableName, String[] columns, boolean unique) {
StringBuilder buffer = new StringBuilder();
buffer.append("create index ").append(maxConstraintName(indexName)).append(" on ").append(tableName);
buffer.append("create ");
if (unique) {
buffer.append(uniqueIndex).append(" ");
}
buffer.append("index ").append(maxConstraintName(indexName)).append(" on ").append(tableName);
appendColumns(columns, buffer);
return buffer.toString();
}
@@ -19,6 +19,7 @@ import javax.xml.bind.annotation.XmlType;
* <attribute name="indexName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="columns" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}boolean" />
* <attribute name="platforms" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
@@ -36,6 +37,8 @@ public class CreateIndex {
protected String tableName;
@XmlAttribute(name = "columns", required = true)
protected String columns;
@XmlAttribute(name = "unique")
protected Boolean unique;
@XmlAttribute(name = "platforms")
protected String platforms;
@@ -99,6 +102,20 @@ public class CreateIndex {
this.columns = value;
}
/**
* Return the unique property.
*/
public Boolean isUnique() {
return unique;
}
/**
* Set the unique property.
*/
public void setUnique(Boolean unique) {
this.unique = unique;
}
/**
* Return the platforms.
*/
@@ -20,6 +20,8 @@ public class MIndex {
private List<String> columns = new ArrayList<>();
private boolean unique;
/**
* Create a single column non unique index.
*/
@@ -29,9 +31,10 @@ public class MIndex {
this.columns.add(columnName);
}
public MIndex(String indexName, String tableName, String[] columnNames, String platforms) {
public MIndex(String indexName, String tableName, String[] columnNames, String platforms, boolean unique) {
this(indexName, tableName, columnNames);
this.platforms = platforms;
this.unique = unique;
}
/**
@@ -48,6 +51,7 @@ public class MIndex {
this.tableName = createIndex.getTableName();
this.columns = split(createIndex.getColumns());
this.platforms = createIndex.getPlatforms();
this.unique = Boolean.TRUE.equals(createIndex.isUnique());
}
public String getKey() {
@@ -85,6 +89,9 @@ public class MIndex {
create.setTableName(tableName);
create.setColumns(join());
create.setPlatforms(platforms);
if (Boolean.TRUE.equals(unique)) {
create.setUnique(Boolean.TRUE);
}
return create;
}
@@ -117,6 +124,9 @@ public class MIndex {
if (!tableName.equals(newIndex.getTableName())) {
return true;
}
if (unique != newIndex.unique) {
return true;
}
List<String> newColumns = newIndex.getColumns();
if (columns.size() != newColumns.size()) {
return true;
@@ -61,7 +61,7 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
for (IndexDefinition index : indexes) {
String[] columns = index.getColumns();
indexSet.add(columns);
if (index.isUnique()) {
if (index.isUniqueConstraint()) {
table.addUniqueConstraint(createMUniqueConstraint(index, columns));
} else {
// 'just' an index (not a unique constraint)
@@ -92,7 +92,7 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
}
private MIndex createMIndex(String indexName, String tableName, IndexDefinition index) {
return new MIndex(indexName, tableName, index.getColumns(), platforms(index.getPlatforms()));
return new MIndex(indexName, tableName, index.getColumns(), platforms(index.getPlatforms()), index.isUnique());
}
private String platforms(Platform[] platforms) {
@@ -35,6 +35,22 @@ public class IndexDefinition {
this.platforms = null;
}
/**
* Return true if this can be used as a unique constraint.
*/
public boolean isUniqueConstraint() {
return unique && noColumnFormulas();
}
private boolean noColumnFormulas() {
for (String column : columns) {
if (column.contains("(")) {
return false;
}
}
return true;
}
/**
* Return true if this is a unique constraint.
*/