diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index e53a77b7d4..ec18a421d7 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -493,6 +493,8 @@ public class Settings protected Boolean migrationIgnoreDefaultTimestampPrecisionDiffs = true; @XmlElement(defaultValue = "false") protected Boolean migrationIgnoreUnnamedConstraintDiffs = false; + @XmlElement(defaultValue = "true") + protected Boolean migrationIgnoreImplicitPrimaryKeyNotNullConstraints = true; @XmlElement(type = String.class) @XmlJavaTypeAdapter(LocaleAdapter.class) protected Locale locale; @@ -6338,6 +6340,30 @@ public class Settings this.migrationIgnoreUnnamedConstraintDiffs = value; } + /** + * Various migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the presence or absence of implicit NOT NULL constraints on PRIMARY KEY columns. This flag allows for overriding this behaviour. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public Boolean isMigrationIgnoreImplicitPrimaryKeyNotNullConstraints() { + return migrationIgnoreImplicitPrimaryKeyNotNullConstraints; + } + + /** + * Various migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the presence or absence of implicit NOT NULL constraints on PRIMARY KEY columns. This flag allows for overriding this behaviour. + * + * @param value + * allowed object is + * {@link Boolean } + * + */ + public void setMigrationIgnoreImplicitPrimaryKeyNotNullConstraints(Boolean value) { + this.migrationIgnoreImplicitPrimaryKeyNotNullConstraints = 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()}. * @@ -9411,6 +9437,15 @@ public class Settings return this; } + /** + * Various migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the presence or absence of implicit NOT NULL constraints on PRIMARY KEY columns. This flag allows for overriding this behaviour. + * + */ + public Settings withMigrationIgnoreImplicitPrimaryKeyNotNullConstraints(Boolean value) { + setMigrationIgnoreImplicitPrimaryKeyNotNullConstraints(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()}. * @@ -9927,6 +9962,7 @@ public class Settings builder.append("migrationAutoVerification", migrationAutoVerification); builder.append("migrationIgnoreDefaultTimestampPrecisionDiffs", migrationIgnoreDefaultTimestampPrecisionDiffs); builder.append("migrationIgnoreUnnamedConstraintDiffs", migrationIgnoreUnnamedConstraintDiffs); + builder.append("migrationIgnoreImplicitPrimaryKeyNotNullConstraints", migrationIgnoreImplicitPrimaryKeyNotNullConstraints); builder.append("locale", locale); builder.append("parseDialect", parseDialect); builder.append("parseLocale", parseLocale); @@ -11821,6 +11857,15 @@ public class Settings return false; } } + if (migrationIgnoreImplicitPrimaryKeyNotNullConstraints == null) { + if (other.migrationIgnoreImplicitPrimaryKeyNotNullConstraints!= null) { + return false; + } + } else { + if (!migrationIgnoreImplicitPrimaryKeyNotNullConstraints.equals(other.migrationIgnoreImplicitPrimaryKeyNotNullConstraints)) { + return false; + } + } if (locale == null) { if (other.locale!= null) { return false; @@ -12285,6 +12330,7 @@ public class Settings 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)+((migrationIgnoreImplicitPrimaryKeyNotNullConstraints == null)? 0 :migrationIgnoreImplicitPrimaryKeyNotNullConstraints.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 e444cf9b97..bc3ed22903 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Diff.java +++ b/jOOQ/src/main/java/org/jooq/impl/Diff.java @@ -299,7 +299,7 @@ final class Diff { // TODO: The order of dropping / adding these objects might be incorrect // as there could be inter-dependencies. - appendColumns(r, t1, asList(t1.fields()), asList(t2.fields())); + appendColumns(r, t1, t2, asList(t1.fields()), asList(t2.fields())); appendPrimaryKey(r, t1, asList(t1.getPrimaryKey()), asList(t2.getPrimaryKey())); appendUniqueKeys(r, t1, removePrimary(t1.getKeys()), removePrimary(t2.getKeys())); appendForeignKeys(r, t1, t1.getReferences(), t2.getReferences()); @@ -373,7 +373,13 @@ final class Diff { return false; } - private final DiffResult appendColumns(DiffResult result, Table t1, List> l1, List> l2) { + private final DiffResult appendColumns( + DiffResult result, + Table t1, + Table t2, + List> l1, + List> l2 + ) { final List> add = new ArrayList<>(); final List> drop = new ArrayList<>(); @@ -413,9 +419,9 @@ final class Diff { if (typeNameDifference(type1, type2)) r.queries.add(ctx.alterTable(t1).alter(f1).set(type2.nullability(Nullability.DEFAULT))); - if (type1.nullable() && !type2.nullable()) + if (type1.nullable() && !type2.nullable() && respectPkNullability(f1, f2)) r.queries.add(ctx.alterTable(t1).alter(f1).setNotNull()); - else if (!type1.nullable() && type2.nullable()) + else if (!type1.nullable() && type2.nullable() && respectPkNullability(f1, f2)) r.queries.add(ctx.alterTable(t1).alter(f1).dropNotNull()); Field d1 = type1.defaultValue(); @@ -435,6 +441,19 @@ final class Diff { // [#9656] TODO: Change character set } + private final boolean respectPkNullability(Field f1, Field f2) { + if (FALSE.equals(ctx.settings().isMigrationIgnoreImplicitPrimaryKeyNotNullConstraints())) + return true; + + UniqueKey pk1 = t1.getPrimaryKey(); + UniqueKey pk2 = t2.getPrimaryKey(); + + return pk1 == null + || pk2 == null + || !pk1.getFields().contains(f1) + || !pk2.getFields().contains(f2); + } + private final boolean typeNameDifference(DataType type1, DataType type2) { if (type1.getTypeName().equals(type2.getTypeName())) return false; 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 9b37e42e80..2da5409dea 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 @@ -1568,6 +1568,10 @@ deployed on an RDBMS that does not.]]>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.]]> + + migrateTo() methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the presence or absence of implicit NOT NULL constraints on PRIMARY KEY columns. This flag allows for overriding this behaviour.]]> + +