[jOOQ/jOOQ#18441] Diff cannot handle name swaps of constraints and other
objects
This commit is contained in:
parent
2efa77e6bc
commit
f1d983d40d
@ -58,10 +58,12 @@ import static org.jooq.impl.ConstraintType.FOREIGN_KEY;
|
||||
import static org.jooq.impl.ConstraintType.PRIMARY_KEY;
|
||||
import static org.jooq.impl.ConstraintType.UNIQUE;
|
||||
import static org.jooq.impl.CreateTableImpl.SUPPORT_NULLABLE_PRIMARY_KEY;
|
||||
import static org.jooq.impl.DSL.unquotedName;
|
||||
import static org.jooq.impl.Tools.NO_SUPPORT_TIMESTAMP_PRECISION;
|
||||
import static org.jooq.impl.Tools.NO_SUPPORT_TIME_PRECISION;
|
||||
import static org.jooq.impl.Tools.allMatch;
|
||||
import static org.jooq.impl.Tools.anyMatch;
|
||||
import static org.jooq.impl.Tools.autoAlias;
|
||||
import static org.jooq.impl.Tools.filter;
|
||||
import static org.jooq.impl.Tools.findAny;
|
||||
import static org.jooq.impl.Tools.flatMap;
|
||||
@ -93,6 +95,8 @@ import org.jooq.DataType;
|
||||
import org.jooq.Domain;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Function2;
|
||||
import org.jooq.Function3;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.Key;
|
||||
import org.jooq.Meta;
|
||||
@ -108,8 +112,6 @@ import org.jooq.Sequence;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableOptions.TableType;
|
||||
import org.jooq.UniqueKey;
|
||||
import org.jooq.impl.QOM.DropTable;
|
||||
import org.jooq.impl.QOM.PrimaryKey;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
/**
|
||||
@ -428,7 +430,7 @@ final class Diff {
|
||||
else {
|
||||
|
||||
// [#18044] [#18327] Ensure constraint / column drop / add order
|
||||
DiffResult temp = new DiffResult(new ArrayList<>(), r.addedFks, r.droppedFks);
|
||||
DiffResult temp = new DiffResult(new ArrayList<>(), new ArrayList<>(), r.addedFks, r.droppedFks);
|
||||
|
||||
appendColumns(temp, t1, t2, asList(t1.fields()), asList(t2.fields()));
|
||||
appendPrimaryKey(temp, t1, asList(t1.getPrimaryKey()), asList(t2.getPrimaryKey()));
|
||||
@ -723,11 +725,15 @@ final class Diff {
|
||||
allowRenames = false;
|
||||
}
|
||||
|
||||
if (allowRenames && UNQUALIFIED_COMP.compare(k1, k2) != 0)
|
||||
if (allowRenames && UNQUALIFIED_COMP.compare(k1, k2) != 0) {
|
||||
|
||||
// [#10813] Don't rename constraints in MySQL
|
||||
if (type != PRIMARY_KEY || !NO_SUPPORT_PK_NAMES.contains(ctx.dialect()))
|
||||
r.queries.add(ctx.alterTable(t1).renameConstraint(n1).to(n2));
|
||||
if (type != PRIMARY_KEY || !NO_SUPPORT_PK_NAMES.contains(ctx.dialect())) {
|
||||
rename(r, type == CHECK ? t1.getChecks() : t1.getKeys(), n1, n2,
|
||||
(_n1, _n2) -> ctx.alterTable(t1).renameConstraint(_n1).to(_n2)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -742,6 +748,28 @@ final class Diff {
|
||||
};
|
||||
}
|
||||
|
||||
private final void rename(
|
||||
DiffResult r,
|
||||
List<? extends Named> existing,
|
||||
Name n1,
|
||||
Name n2,
|
||||
Function2<? super Name, ? super Name, ? extends Query> renameQuery
|
||||
) {
|
||||
|
||||
// [#18441] Handle name swaps
|
||||
if (anyMatch(existing, k -> k.getName().equals(n2.last()))) {
|
||||
Name temp = unquotedName(autoAlias(ctx.configuration(), n1.append(n2)));
|
||||
|
||||
if (n1.qualified())
|
||||
temp = n1.qualifier().append(temp);
|
||||
|
||||
r.queries.add(renameQuery.apply(n1, temp));
|
||||
r.cleanup.add(renameQuery.apply(temp, n2));
|
||||
}
|
||||
else
|
||||
r.queries.add(renameQuery.apply(n1, n2));
|
||||
}
|
||||
|
||||
private final <K extends Named> Merge<K> keyMerge(Domain<?> d1, Create<K> create, Drop<K> drop) {
|
||||
return (r, k1, k2) -> {
|
||||
Name n1 = k1.getUnqualifiedName();
|
||||
@ -813,8 +841,11 @@ final class Diff {
|
||||
drop.drop(r, ix1);
|
||||
create.create(r, ix2);
|
||||
}
|
||||
else if (UNQUALIFIED_COMP.compare(ix1, ix2) != 0)
|
||||
r.queries.add(ctx.alterTable(t1).renameIndex(ix1).to(ix2));
|
||||
else if (UNQUALIFIED_COMP.compare(ix1, ix2) != 0) {
|
||||
rename(r, t1.getIndexes(), ix1.getUnqualifiedName(), ix2.getUnqualifiedName(),
|
||||
(_i1, _i2) -> ctx.alterTable(t1).renameIndex(_i1).to(_i2)
|
||||
);
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
@ -851,9 +882,9 @@ final class Diff {
|
||||
Iterator<? extends N> i1 = sorted(l1, comp);
|
||||
Iterator<? extends N> i2 = sorted(l2, comp);
|
||||
|
||||
DiffResult dropped = dropMergeCreate ? new DiffResult(new ArrayList<>(), result.addedFks, result.droppedFks) : result;
|
||||
DiffResult merged = dropMergeCreate ? new DiffResult(new ArrayList<>(), result.addedFks, result.droppedFks) : result;
|
||||
DiffResult created = dropMergeCreate ? new DiffResult(new ArrayList<>(), result.addedFks, result.droppedFks) : result;
|
||||
DiffResult dropped = dropMergeCreate ? new DiffResult(new ArrayList<>(), new ArrayList<>(), result.addedFks, result.droppedFks) : result;
|
||||
DiffResult merged = dropMergeCreate ? new DiffResult(new ArrayList<>(), new ArrayList<>(), result.addedFks, result.droppedFks) : result;
|
||||
DiffResult created = dropMergeCreate ? new DiffResult(new ArrayList<>(), new ArrayList<>(), result.addedFks, result.droppedFks) : result;
|
||||
|
||||
for (;;) {
|
||||
if (s1 == null && i1.hasNext())
|
||||
@ -921,22 +952,24 @@ final class Diff {
|
||||
|
||||
private static final record DiffResult(
|
||||
List<Query> queries,
|
||||
List<Query> cleanup,
|
||||
Set<ForeignKey<?, ?>> addedFks,
|
||||
Set<ForeignKey<?, ?>> droppedFks
|
||||
) {
|
||||
DiffResult() {
|
||||
this(new ArrayList<>(), new HashSet<>(), new HashSet<>());
|
||||
this(new ArrayList<>(), new ArrayList<>(), new HashSet<>(), new HashSet<>());
|
||||
}
|
||||
|
||||
void addAll(DiffResult other) {
|
||||
queries.addAll(other.queries);
|
||||
queries.addAll(other.cleanup);
|
||||
addedFks.addAll(other.addedFks);
|
||||
droppedFks.addAll(other.droppedFks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return queries.toString();
|
||||
return Tools.concat(queries, cleanup).toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4020,6 +4020,17 @@ final class Tools {
|
||||
|
||||
static final Lazy<DSLContext> CTX = Lazy.of(() -> DSL.using(CONFIG.get()));
|
||||
|
||||
/**
|
||||
* A possibly inefficient but stable way to generate an alias for any
|
||||
* {@link QueryPart}.
|
||||
* <p>
|
||||
* Stability is important to profit from execution plan caching. Equal query
|
||||
* parts must produce the same alias every time.
|
||||
*/
|
||||
static final String autoAlias(Configuration configuration, QueryPart part) {
|
||||
return normaliseNameCase(configuration, autoAlias(part), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* A possibly inefficient but stable way to generate an alias for any
|
||||
* {@link QueryPart}.
|
||||
@ -7159,6 +7170,14 @@ final class Tools {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise a name case depending on the dialect and the setting for
|
||||
* {@link ParseNameCase}.
|
||||
*/
|
||||
static final String normaliseNameCase(Configuration configuration, String name, boolean quoted) {
|
||||
return normaliseNameCase(configuration, name, quoted, SettingsTools.parseLocale(configuration.settings()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise a name case depending on the dialect and the setting for
|
||||
* {@link ParseNameCase}.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user