[jOOQ/jOOQ#17647] Diff should ignore implicit NOT NULL constraints on

PRIMARY KEY columns
This commit is contained in:
Lukas Eder 2024-11-21 17:10:52 +01:00
parent b72e6382a8
commit 5fb18bfaf5
3 changed files with 73 additions and 4 deletions

View File

@ -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 <code>migrateTo()</code> methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the presence or absence of implicit <code>NOT NULL</code> constraints on <code>PRIMARY KEY</code> columns. This flag allows for overriding this behaviour.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isMigrationIgnoreImplicitPrimaryKeyNotNullConstraints() {
return migrationIgnoreImplicitPrimaryKeyNotNullConstraints;
}
/**
* Various <code>migrateTo()</code> methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the presence or absence of implicit <code>NOT NULL</code> constraints on <code>PRIMARY KEY</code> 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 <code>migrateTo()</code> methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the presence or absence of implicit <code>NOT NULL</code> constraints on <code>PRIMARY KEY</code> 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()));

View File

@ -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<Field<?>> add = new ArrayList<>();
final List<Field<?>> 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;

View File

@ -1568,6 +1568,10 @@ deployed on an RDBMS that does not.]]></jxb:javadoc></jxb:property></appinfo></a
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Various <code>migrateTo()</code> 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.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="migrationIgnoreImplicitPrimaryKeyNotNullConstraints" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Various <code>migrateTo()</code> methods (e.g. {@link org.jooq.Meta#migrateTo(org.jooq.Meta)}) ignore the presence or absence of implicit <code>NOT NULL</code> constraints on <code>PRIMARY KEY</code> columns. This flag allows for overriding this behaviour.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="locale" type="string" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[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()}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>