[jOOQ/jOOQ#9483] Support materialized views in Diff

This commit is contained in:
Lukas Eder 2023-09-19 08:47:54 +02:00
parent 5a02c0cd48
commit 8e83af8c8b
3 changed files with 77 additions and 14 deletions

View File

@ -57,6 +57,7 @@ public final class MigrationConfiguration {
private final boolean dropTableCascade;
private final boolean alterTableDropCascade;
private final boolean createOrReplaceView;
private final boolean createOrReplaceMaterializedView;
private final boolean respectColumnOrder;
/**
@ -70,6 +71,7 @@ public final class MigrationConfiguration {
false,
false,
false,
false,
false
);
}
@ -81,6 +83,7 @@ public final class MigrationConfiguration {
boolean dropTableCascade,
boolean alterTableDropCascade,
boolean createOrReplaceView,
boolean createOrReplaceMaterializedView,
boolean respectColumnOrder
) {
this.alterTableAddMultiple = alterTableAddMultiple;
@ -89,6 +92,7 @@ public final class MigrationConfiguration {
this.dropTableCascade = dropTableCascade;
this.alterTableDropCascade = alterTableDropCascade;
this.createOrReplaceView = createOrReplaceView;
this.createOrReplaceMaterializedView = createOrReplaceMaterializedView;
this.respectColumnOrder = respectColumnOrder;
}
@ -112,6 +116,7 @@ public final class MigrationConfiguration {
dropTableCascade,
alterTableDropCascade,
createOrReplaceView,
createOrReplaceMaterializedView,
respectColumnOrder
);
}
@ -136,6 +141,7 @@ public final class MigrationConfiguration {
dropTableCascade,
alterTableDropCascade,
createOrReplaceView,
createOrReplaceMaterializedView,
respectColumnOrder
);
}
@ -160,6 +166,7 @@ public final class MigrationConfiguration {
dropTableCascade,
alterTableDropCascade,
createOrReplaceView,
createOrReplaceMaterializedView,
respectColumnOrder
);
}
@ -184,6 +191,7 @@ public final class MigrationConfiguration {
newDropTableCascade,
alterTableDropCascade,
createOrReplaceView,
createOrReplaceMaterializedView,
respectColumnOrder
);
}
@ -208,6 +216,7 @@ public final class MigrationConfiguration {
dropTableCascade,
newAlterTableDropCascade,
createOrReplaceView,
createOrReplaceMaterializedView,
respectColumnOrder
);
}
@ -230,6 +239,30 @@ public final class MigrationConfiguration {
dropTableCascade,
alterTableDropCascade,
newCreateOrReplaceView,
createOrReplaceMaterializedView,
respectColumnOrder
);
}
/**
* Whether the materialized views should be (create-or-)replaced or dropped and re-created.
*/
public final boolean createOrReplaceMaterializedView() {
return createOrReplaceMaterializedView;
}
/**
* Whether the materialized views should be (create-or-)replaced or dropped and re-created.
*/
public final MigrationConfiguration createOrReplaceMaterializedView(boolean newCreateOrReplaceMaterializedView) {
return new MigrationConfiguration(
alterTableAddMultiple,
alterTableDropMultiple,
dropSchemaCascade,
dropTableCascade,
alterTableDropCascade,
createOrReplaceView,
newCreateOrReplaceMaterializedView,
respectColumnOrder
);
}
@ -252,6 +285,7 @@ public final class MigrationConfiguration {
dropTableCascade,
alterTableDropCascade,
createOrReplaceView,
createOrReplaceMaterializedView,
newRespectColumnOrder
);
}

View File

@ -44,6 +44,8 @@ import static org.jooq.SQLDialect.IGNITE;
import static org.jooq.SQLDialect.MARIADB;
// ...
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.TableOptions.TableType.MATERIALIZED_VIEW;
import static org.jooq.TableOptions.TableType.VIEW;
import static org.jooq.impl.Comparators.CHECK_COMP;
import static org.jooq.impl.Comparators.FOREIGN_KEY_COMP;
import static org.jooq.impl.Comparators.INDEX_COMP;
@ -114,7 +116,10 @@ final class Diff {
Diff(Configuration configuration, MigrationConfiguration migrateConf, Meta meta1, Meta meta2) {
this.migrateConf = migrateConf;
this.exportConf = new DDLExportConfiguration().createOrReplaceView(migrateConf.createOrReplaceView());
this.exportConf = new DDLExportConfiguration()
.createOrReplaceView(migrateConf.createOrReplaceView())
.createOrReplaceMaterializedView(migrateConf.createOrReplaceMaterializedView());
this.ctx = configuration.dsl();
this.meta1 = meta1;
this.meta2 = meta2;
@ -255,8 +260,10 @@ final class Diff {
if (r.droppedFks.add(fk) && !migrateConf.dropTableCascade())
r.queries.add(ctx.alterTable(fk.getTable()).dropForeignKey(fk.constraint()));
if (t.getTableType().isView())
if (t.getTableType() == VIEW)
r.queries.add(ctx.dropView(t));
else if (t.getTableType() == MATERIALIZED_VIEW)
r.queries.add(ctx.dropMaterializedView(t));
else if (t.getTableType() == TableType.TEMPORARY)
r.queries.add(ctx.dropTemporaryTable(t));
else
@ -269,19 +276,21 @@ final class Diff {
private final Merge<Table<?>> MERGE_TABLE = new Merge<Table<?>>() {
@Override
public void merge(DiffResult r, Table<?> t1, Table<?> t2) {
boolean v1 = t1.getTableType().isView();
boolean v2 = t2.getTableType().isView();
boolean m1 = t1.getTableType() == MATERIALIZED_VIEW;
boolean m2 = t2.getTableType() == MATERIALIZED_VIEW;
boolean v1 = t1.getTableType() == VIEW;
boolean v2 = t2.getTableType() == VIEW;
if (v1 && v2) {
if (v1 && v2 || m1 && m2) {
if (!Arrays.equals(t1.fields(), t2.fields())
|| t2.getOptions().select() != null && !t2.getOptions().select().equals(t1.getOptions().select())
|| t2.getOptions().source() != null && !t2.getOptions().source().equals(t1.getOptions().source())) {
replaceView(r, t1, t2);
replaceView(r, t1, t2, true);
return;
}
}
else if (v1 != v2) {
replaceView(r, t1, t2);
else if (v1 != v2 || m1 != m2) {
replaceView(r, t1, t2, false);
return;
}
else {
@ -306,8 +315,10 @@ final class Diff {
r.queries.add(ctx.commentOnTable(t2).is(c2));
}
private void replaceView(DiffResult r, Table<?> v1, Table<?> v2) {
if (!migrateConf.createOrReplaceView())
private void replaceView(DiffResult r, Table<?> v1, Table<?> v2, boolean canReplace) {
if (!canReplace
|| v2.getTableType() == VIEW && !migrateConf.createOrReplaceView()
|| v2.getTableType() == MATERIALIZED_VIEW && !migrateConf.createOrReplaceMaterializedView())
dropTable().drop(r, v1);
createTable().create(r, v2);

View File

@ -806,8 +806,10 @@ final class Interpreter {
MutableTable existing = schema.table(table);
if (existing != null) {
if (!existing.options.type().isView())
if (existing.options.type() != VIEW && !query.$materialized())
throw objectNotView(table);
else if (existing.options.type() != MATERIALIZED_VIEW && query.$materialized())
throw objectNotMaterializedView(table);
else if (query.$orReplace())
drop(schema.tables, existing, RESTRICT);
else if (!query.$ifNotExists())
@ -834,7 +836,10 @@ final class Interpreter {
MutableTable existing = schema.table(table);
if (existing == null) {
if (!query.$ifExists())
throw viewNotExists(table);
if (query.$materialized())
throw materializedViewNotExists(table);
else
throw viewNotExists(table);
return;
}
@ -858,7 +863,10 @@ final class Interpreter {
MutableTable existing = schema.table(table);
if (existing == null) {
if (!query.$ifExists())
throw viewNotExists(table);
if (query.$materialized())
throw materializedViewNotExists(table);
else
throw viewNotExists(table);
return;
}
@ -1197,10 +1205,18 @@ final class Interpreter {
return new DataDefinitionException("View does not exist: " + view.getQualifiedName());
}
private static final DataDefinitionException materializedViewNotExists(Table<?> view) {
return new DataDefinitionException("Materialized view does not exist: " + view.getQualifiedName());
}
private static final DataDefinitionException viewAlreadyExists(Table<?> view) {
return new DataDefinitionException("View already exists: " + view.getQualifiedName());
}
private static final DataDefinitionException materializedViewAlreadyExists(Table<?> view) {
return new DataDefinitionException("Materialized view already exists: " + view.getQualifiedName());
}
private static final DataDefinitionException columnAlreadyExists(Name name) {
return new DataDefinitionException("Column already exists: " + name);
}
@ -1363,8 +1379,10 @@ final class Interpreter {
}
private static final DataDefinitionException alreadyExists(Table<?> t, MutableTable mt) {
if (mt.options.type().isView())
if (mt.options.type() == VIEW)
return viewAlreadyExists(t);
else if (mt.options.type() == MATERIALIZED_VIEW)
return materializedViewAlreadyExists(t);
else
return alreadyExists(t);
}