#2206 - Postgres DDL generation - for create index use "if not exists" clause

This commit is contained in:
Robin Bygrave
2021-03-25 16:45:44 +13:00
parent f341ff0167
commit 8992980689
4 changed files with 116 additions and 1 deletions
@@ -3,7 +3,6 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.annotation.ConstraintMode;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbConstraintNaming;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbDefaultValue;
import io.ebean.config.dbplatform.DbIdentity;
@@ -113,6 +112,7 @@ public class PlatformDdl {
protected String uniqueIndex = "unique";
protected String indexConcurrent = "";
protected String createIndexIfNotExists = "";
/**
* Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
@@ -414,6 +414,9 @@ public class PlatformDdl {
if (create.isConcurrent()) {
buffer.append(indexConcurrent);
}
if (create.isNotExistsCheck()) {
buffer.append(createIndexIfNotExists);
}
buffer.append(maxConstraintName(create.getIndexName())).append(" on ").append(create.getTableName());
appendColumns(create.getColumns(), buffer);
return buffer.toString();
@@ -18,6 +18,7 @@ public class PostgresDdl extends PlatformDdl {
this.dropTableCascade = " cascade";
this.columnSetType = "type ";
this.alterTableIfExists = "if exists ";
this.createIndexIfNotExists = "if not exists ";
this.columnSetNull = "drop not null";
this.addForeignKeySkipCheck = " not valid";
this.indexConcurrent = "concurrently ";
@@ -12,7 +12,11 @@ class WriteCreateIndex {
private final boolean unique;
private final boolean concurrent;
private final String definition;
private final boolean notExistsCheck;
/**
* Create index for foreign key.
*/
WriteCreateIndex(String indexName, String tableName, String[] columns, boolean unique) {
this.indexName = indexName;
this.tableName = tableName;
@@ -20,8 +24,12 @@ class WriteCreateIndex {
this.unique = unique;
this.concurrent = false;
this.definition = null;
this.notExistsCheck = false;
}
/**
* Create non-foreign key index.
*/
public WriteCreateIndex(CreateIndex index) {
this.indexName = index.getIndexName();
this.tableName = index.getTableName();
@@ -29,6 +37,7 @@ class WriteCreateIndex {
this.unique = Boolean.TRUE.equals(index.isUnique());
this.concurrent = Boolean.TRUE.equals(index.isConcurrent());
this.definition = index.getDefinition();
this.notExistsCheck = true;
}
public String getIndexName() {
@@ -58,4 +67,8 @@ class WriteCreateIndex {
public boolean useDefinition() {
return definition != null && !definition.isEmpty();
}
public boolean isNotExistsCheck() {
return notExistsCheck;
}
}
@@ -0,0 +1,98 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.DB;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.h2.H2Platform;
import io.ebean.config.dbplatform.hana.HanaPlatform;
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
import io.ebean.config.dbplatform.oracle.OraclePlatform;
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
import io.ebeaninternal.dbmigration.migration.CreateIndex;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
public class PlatformDdl_CreateIndexTest {
private final PlatformDdl h2Ddl = PlatformDdlBuilder.create(new H2Platform());
private final PlatformDdl pgDdl = PlatformDdlBuilder.create(new PostgresPlatform());
private final PlatformDdl mysqlDdl = PlatformDdlBuilder.create(new MySqlPlatform());
private final PlatformDdl oraDdl = PlatformDdlBuilder.create(new OraclePlatform());
private final PlatformDdl sqlServerDdl = PlatformDdlBuilder.create(new SqlServer17Platform());
private final PlatformDdl hanaDdl = PlatformDdlBuilder.create(new HanaPlatform());
{
DatabaseConfig config = DB.getDefault().getPluginApi().getServerConfig();
h2Ddl.configure(config);
pgDdl.configure(config);
mysqlDdl.configure(config);
oraDdl.configure(config);
sqlServerDdl.configure(config);
hanaDdl.configure(config);
}
WriteCreateIndex writeCreateIndex() {
return writeCreateIndex(true, true);
}
WriteCreateIndex writeCreateIndex(boolean unique, boolean concurrent) {
CreateIndex createIndex = new CreateIndex();
createIndex.setIndexName("ix_mytab_acol");
createIndex.setTableName("mytab");
createIndex.setColumns("acol");
createIndex.setUnique(unique);
createIndex.setConcurrent(concurrent);
return new WriteCreateIndex(createIndex);
}
WriteCreateIndex fkeyCreateIndex(boolean unique) {
return new WriteCreateIndex("ix_mytab_acol", "mytab", new String[]{"acol"}, unique);
}
@Test
public void createUniqueIndex() {
WriteCreateIndex createIndex = writeCreateIndex();
String sql = h2Ddl.createIndex(createIndex);
assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql);
sql = pgDdl.createIndex(createIndex);
assertEquals("create unique index concurrently if not exists ix_mytab_acol on mytab (acol)", sql);
sql = mysqlDdl.createIndex(createIndex);
assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql);
sql = sqlServerDdl.createIndex(createIndex);
assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql);
sql = oraDdl.createIndex(createIndex);
assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql);
sql = hanaDdl.createIndex(createIndex);
assertThat(sql).isEqualTo("-- explicit index \"ix_mytab_acol\" for single column \"acol\" of table \"mytab\" is not necessary");
}
@Test
public void postgres_createIndex() {
String sql = pgDdl.createIndex(writeCreateIndex(true, true));
assertEquals("create unique index concurrently if not exists ix_mytab_acol on mytab (acol)", sql);
sql = pgDdl.createIndex(writeCreateIndex(false, false));
assertEquals("create index if not exists ix_mytab_acol on mytab (acol)", sql);
sql = pgDdl.createIndex(writeCreateIndex(true, false));
assertEquals("create unique index if not exists ix_mytab_acol on mytab (acol)", sql);
sql = pgDdl.createIndex(writeCreateIndex(false, true));
assertEquals("create index concurrently if not exists ix_mytab_acol on mytab (acol)", sql);
}
@Test
public void postgres_fkeyCreateIndex() {
String sql = pgDdl.createIndex(fkeyCreateIndex(true));
assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql);
sql = pgDdl.createIndex(fkeyCreateIndex(false));
assertEquals("create index ix_mytab_acol on mytab (acol)", sql);
}
}