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 extends Field>> l1, List extends Field>> l2) {
+ private final DiffResult appendColumns(
+ DiffResult result,
+ Table> t1,
+ Table> t2,
+ List extends Field>> l1,
+ List extends Field>> 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.]]>
+
+