diff --git a/jOOQ-migrations-maven/src/main/java/org/jooq/migrations/maven/AbstractMigrationsMojo.java b/jOOQ-migrations-maven/src/main/java/org/jooq/migrations/maven/AbstractMigrationsMojo.java index 0257944ad7..6b946e5c92 100644 --- a/jOOQ-migrations-maven/src/main/java/org/jooq/migrations/maven/AbstractMigrationsMojo.java +++ b/jOOQ-migrations-maven/src/main/java/org/jooq/migrations/maven/AbstractMigrationsMojo.java @@ -214,8 +214,14 @@ abstract class AbstractMigrationsMojo extends AbstractMojo { ); - ctx.settings().setMigrationSchemataCreateSchemaIfNotExists(schemataCreateSchemaIfNotExists); - ctx.settings().setMigrationHistorySchemaCreateSchemaIfNotExists(historySchemaCreateSchemaIfNotExists); + ctx.settings() + .withMigrationSchemataCreateSchemaIfNotExists(schemataCreateSchemaIfNotExists) + .withMigrationHistorySchemaCreateSchemaIfNotExists(historySchemaCreateSchemaIfNotExists) + + // [#9506] [#17646] Users may use unnamed constraints in migration scripts. + // When comparing the schema with the existing schema in the database, + // we must ignore the database's synthetic constraint names. + .withMigrationIgnoreUnnamedConstraintDiffs(true); // Initialise connection // --------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index 7ff4a73bbe..e53a77b7d4 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -491,6 +491,8 @@ public class Settings protected Boolean migrationAutoVerification = true; @XmlElement(defaultValue = "true") protected Boolean migrationIgnoreDefaultTimestampPrecisionDiffs = true; + @XmlElement(defaultValue = "false") + protected Boolean migrationIgnoreUnnamedConstraintDiffs = false; @XmlElement(type = String.class) @XmlJavaTypeAdapter(LocaleAdapter.class) protected Locale locale; @@ -6312,6 +6314,30 @@ public class Settings this.migrationIgnoreDefaultTimestampPrecisionDiffs = value; } + /** + * Various migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the difference between (possibly synthetically) name constraints and unnamed constraints, if the structure of the constraint is the same. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public Boolean isMigrationIgnoreUnnamedConstraintDiffs() { + return migrationIgnoreUnnamedConstraintDiffs; + } + + /** + * Various migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the difference between (possibly synthetically) name constraints and unnamed constraints, if the structure of the constraint is the same. + * + * @param value + * allowed object is + * {@link Boolean } + * + */ + public void setMigrationIgnoreUnnamedConstraintDiffs(Boolean value) { + this.migrationIgnoreUnnamedConstraintDiffs = value; + } + /** * The Locale to be used with any locale dependent logic if there is not a more specific locale available. More specific locales include e.g. {@link #getRenderLocale()}, {@link #getParseLocale()}, or {@link #getInterpreterLocale()}. * @@ -9376,6 +9402,15 @@ public class Settings return this; } + /** + * Various migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the difference between (possibly synthetically) name constraints and unnamed constraints, if the structure of the constraint is the same. + * + */ + public Settings withMigrationIgnoreUnnamedConstraintDiffs(Boolean value) { + setMigrationIgnoreUnnamedConstraintDiffs(value); + return this; + } + /** * The Locale to be used with any locale dependent logic if there is not a more specific locale available. More specific locales include e.g. {@link #getRenderLocale()}, {@link #getParseLocale()}, or {@link #getInterpreterLocale()}. * @@ -9891,6 +9926,7 @@ public class Settings builder.append("migrationAutoBaseline", migrationAutoBaseline); builder.append("migrationAutoVerification", migrationAutoVerification); builder.append("migrationIgnoreDefaultTimestampPrecisionDiffs", migrationIgnoreDefaultTimestampPrecisionDiffs); + builder.append("migrationIgnoreUnnamedConstraintDiffs", migrationIgnoreUnnamedConstraintDiffs); builder.append("locale", locale); builder.append("parseDialect", parseDialect); builder.append("parseLocale", parseLocale); @@ -11776,6 +11812,15 @@ public class Settings return false; } } + if (migrationIgnoreUnnamedConstraintDiffs == null) { + if (other.migrationIgnoreUnnamedConstraintDiffs!= null) { + return false; + } + } else { + if (!migrationIgnoreUnnamedConstraintDiffs.equals(other.migrationIgnoreUnnamedConstraintDiffs)) { + return false; + } + } if (locale == null) { if (other.locale!= null) { return false; @@ -12239,6 +12284,7 @@ public class Settings result = ((prime*result)+((migrationAutoBaseline == null)? 0 :migrationAutoBaseline.hashCode())); result = ((prime*result)+((migrationAutoVerification == null)? 0 :migrationAutoVerification.hashCode())); result = ((prime*result)+((migrationIgnoreDefaultTimestampPrecisionDiffs == null)? 0 :migrationIgnoreDefaultTimestampPrecisionDiffs.hashCode())); + result = ((prime*result)+((migrationIgnoreUnnamedConstraintDiffs == null)? 0 :migrationIgnoreUnnamedConstraintDiffs.hashCode())); result = ((prime*result)+((locale == null)? 0 :locale.hashCode())); result = ((prime*result)+((parseDialect == null)? 0 :parseDialect.hashCode())); result = ((prime*result)+((parseLocale == null)? 0 :parseLocale.hashCode())); diff --git a/jOOQ/src/main/java/org/jooq/impl/Diff.java b/jOOQ/src/main/java/org/jooq/impl/Diff.java index 2087d01e08..e444cf9b97 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Diff.java +++ b/jOOQ/src/main/java/org/jooq/impl/Diff.java @@ -38,6 +38,7 @@ package org.jooq.impl; import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; import static java.util.Arrays.asList; // ... import static org.jooq.SQLDialect.IGNITE; @@ -533,15 +534,20 @@ final class Diff { return (r, k1, k2) -> { Name n1 = k1.getUnqualifiedName(); Name n2 = k2.getUnqualifiedName(); + boolean allowRenames = true; if (n1.empty() ^ n2.empty()) { - drop.drop(r, k1); - create.create(r, k2); + if (n1.empty() || !TRUE.equals(ctx.settings().isMigrationIgnoreUnnamedConstraintDiffs())) { + drop.drop(r, k1); + create.create(r, k2); - return; + return; + } + else + allowRenames = false; } - if (NAMED_COMP.compare(k1, k2) != 0) + if (allowRenames && NAMED_COMP.compare(k1, k2) != 0) // [#10813] Don't rename constraints in MySQL if (type != PRIMARY_KEY || !NO_SUPPORT_PK_NAMES.contains(ctx.dialect())) diff --git a/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java b/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java index b5ac99d7d7..bec7db1de9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java @@ -55,6 +55,7 @@ import static org.jooq.impl.HistoryStatus.STARTING; import static org.jooq.impl.HistoryStatus.SUCCESS; import static org.jooq.impl.SchemaImpl.DEFAULT_SCHEMA; import static org.jooq.impl.Tools.map; +import static org.jooq.tools.StringUtils.isEmpty; import java.io.PrintWriter; import java.io.StringWriter; @@ -181,7 +182,7 @@ final class MigrationImpl extends AbstractScope implements Migration { throw new DataMigrationVerificationException("Commit is not available from CommitProvider: " + commit.id()); for (Schema schema : history.lookup(commit.meta().getSchemas())) - if (!ctx.migratedSchemas().contains(schema)) + if (!isEmpty(schema.getName()) && !ctx.migratedSchemas().contains(schema)) throw new DataMigrationVerificationException( """ Schema is referenced from commit, but not configured for migration: {schema}. diff --git a/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.20.0.xsd b/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.20.0.xsd index 909fb7af3d..9b37e42e80 100644 --- a/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.20.0.xsd +++ b/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.20.0.xsd @@ -1563,6 +1563,10 @@ deployed on an RDBMS that does not.]]> migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the difference between TIMESTAMP and TIMESTAMP(6), if 6 is the default precision for timestamps on the configured dialect.]]> + + + migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the difference between (possibly synthetically) name constraints and unnamed constraints, if the structure of the constraint is the same.]]> +