[jOOQ/jOOQ#11258] NullPointerException in MetaImpl.snapshot() when foreign key column order doesn't match unique key column order

This commit is contained in:
Lukas Eder 2021-01-20 14:09:22 +01:00
parent 43cf60192e
commit a5f0733f06
2 changed files with 10 additions and 4 deletions

View File

@ -43,9 +43,11 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import org.jooq.Catalog;
@ -632,13 +634,16 @@ abstract class AbstractMeta extends AbstractScope implements Meta, Serializable
}
final <R extends Record> UniqueKey<R> lookupKey(Table<R> in, UniqueKey<?> uk) {
Set<?> ukFields = new HashSet<>(uk.getFields());
for (UniqueKey<R> k : in.getKeys())
// [#10279] [#10281] Cannot use Key::equals here, because that is
// name-based. 1) The name is irrelevant for this lookup, 2) some
// key implementations (e.g. MetaPrimaryKey for H2) don't produce
// the correct key name, but the index name.
if (k.getFields().equals(uk.getFields()))
// [#11258] Also, we need position agnostic comparison, using sets
if (ukFields.equals(new HashSet<>(k.getFields())))
return k;
return null;

View File

@ -49,6 +49,7 @@ import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.Index;
import org.jooq.Meta;
import org.jooq.Name;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.Schema;
@ -455,12 +456,12 @@ final class FilteredMeta extends AbstractMeta {
continue fkLoop;
TableField<R, ?>[] fields1 = fk.getFieldsArray();
TableField<R, ?>[] fields2 = new TableField[fields1.length];
TableField<?, ?>[] fields2 = new TableField[fields1.length];
for (int i = 0; i < fields2.length; i++)
fields2[i] = (TableField<R, ?>) field(fields1[i]);
fields2[i] = (TableField<?, ?>) uk.getTable().field(fields1[i]);
references.add(Internal.createForeignKey(uk, this, fk.getName(), fields2, fk.enforced()));
references.add(Internal.createForeignKey(this, fk.getQualifiedName(), fields1, uk, (TableField[]) fields2, fk.enforced()));
}
}