[#3520] Duplicate column information in foreign key references for foreign keys that share the same name in different tables

This commit is contained in:
Lukas Eder 2014-08-11 10:57:50 +02:00
parent 1087bafafb
commit 656a1174a8
3 changed files with 44 additions and 28 deletions

View File

@ -56,7 +56,6 @@ import static org.jooq.util.postgres.information_schema.Tables.ATTRIBUTES;
import static org.jooq.util.postgres.information_schema.Tables.CHECK_CONSTRAINTS;
import static org.jooq.util.postgres.information_schema.Tables.KEY_COLUMN_USAGE;
import static org.jooq.util.postgres.information_schema.Tables.PARAMETERS;
import static org.jooq.util.postgres.information_schema.Tables.REFERENTIAL_CONSTRAINTS;
import static org.jooq.util.postgres.information_schema.Tables.ROUTINES;
import static org.jooq.util.postgres.information_schema.Tables.SEQUENCES;
import static org.jooq.util.postgres.information_schema.Tables.TABLES;
@ -177,34 +176,26 @@ public class PostgresDatabase extends AbstractDatabase {
@Override
protected void loadForeignKeys(DefaultRelations relations) throws SQLException {
Result<?> result = create()
.select(
REFERENTIAL_CONSTRAINTS.UNIQUE_CONSTRAINT_NAME,
REFERENTIAL_CONSTRAINTS.UNIQUE_CONSTRAINT_SCHEMA,
KEY_COLUMN_USAGE.CONSTRAINT_NAME,
KEY_COLUMN_USAGE.TABLE_SCHEMA,
KEY_COLUMN_USAGE.TABLE_NAME,
KEY_COLUMN_USAGE.COLUMN_NAME)
.from(REFERENTIAL_CONSTRAINTS)
.join(KEY_COLUMN_USAGE)
.on(KEY_COLUMN_USAGE.CONSTRAINT_SCHEMA.equal(REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA))
.and(KEY_COLUMN_USAGE.CONSTRAINT_NAME.equal(REFERENTIAL_CONSTRAINTS.CONSTRAINT_NAME))
.where(KEY_COLUMN_USAGE.TABLE_SCHEMA.in(getInputSchemata()))
.orderBy(
KEY_COLUMN_USAGE.TABLE_SCHEMA.asc(),
KEY_COLUMN_USAGE.TABLE_NAME.asc(),
KEY_COLUMN_USAGE.CONSTRAINT_NAME.asc(),
KEY_COLUMN_USAGE.ORDINAL_POSITION.asc())
.fetch();
// [#3520] PostgreSQL INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS contains incomplete information about foreign keys
// The (CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME) tuple is non-unique, in case two tables share the
// same CONSTRAINT_NAME.
// The JDBC driver implements this correctly through the pg_catalog, although the sorting and column name casing is wrong, too.
Result<Record> result = create()
.fetch(getConnection().getMetaData().getExportedKeys(null, null, null))
.sortAsc("key_seq")
.sortAsc("fk_name")
.sortAsc("fktable_name")
.sortAsc("fktable_schem");
for (Record record : result) {
SchemaDefinition foreignKeySchema = getSchema(record.getValue(KEY_COLUMN_USAGE.TABLE_SCHEMA));
SchemaDefinition uniqueKeySchema = getSchema(record.getValue(REFERENTIAL_CONSTRAINTS.UNIQUE_CONSTRAINT_SCHEMA));
SchemaDefinition foreignKeySchema = getSchema(record.getValue("fktable_schem", String.class));
SchemaDefinition uniqueKeySchema = getSchema(record.getValue("pktable_schem", String.class));
String foreignKey = record.getValue(KEY_COLUMN_USAGE.CONSTRAINT_NAME);
String foreignKeyTable = record.getValue(KEY_COLUMN_USAGE.TABLE_NAME);
String foreignKeyColumn = record.getValue(KEY_COLUMN_USAGE.COLUMN_NAME);
String uniqueKey = record.getValue(REFERENTIAL_CONSTRAINTS.UNIQUE_CONSTRAINT_NAME);
String foreignKey = record.getValue("fk_name", String.class);
String foreignKeyTable = record.getValue("fktable_name", String.class);
String foreignKeyColumn = record.getValue("fkcolumn_name", String.class);
String uniqueKey = record.getValue("pk_name", String.class);
TableDefinition referencingTable = getTable(foreignKeySchema, foreignKeyTable);

View File

@ -59,6 +59,8 @@ import static org.jooq.test.postgres.generatedclasses.Tables.T_639_NUMBERS_TABLE
import static org.jooq.test.postgres.generatedclasses.Tables.T_725_LOB_TEST;
import static org.jooq.test.postgres.generatedclasses.Tables.T_785;
import static org.jooq.test.postgres.generatedclasses.Tables.T_959;
import static org.jooq.test.postgres.generatedclasses.Tables.T_986_1;
import static org.jooq.test.postgres.generatedclasses.Tables.T_986_2;
import static org.jooq.test.postgres.generatedclasses.Tables.T_ARRAYS;
import static org.jooq.test.postgres.generatedclasses.Tables.T_AUTHOR;
import static org.jooq.test.postgres.generatedclasses.Tables.T_BOOK;
@ -76,6 +78,7 @@ import static org.jooq.test.postgres.generatedclasses.Tables.T_UNSIGNED;
import static org.jooq.test.postgres.generatedclasses.Tables.V_AUTHOR;
import static org.jooq.test.postgres.generatedclasses.Tables.V_BOOK;
import static org.jooq.test.postgres.generatedclasses.Tables.V_LIBRARY;
import static org.jooq.test.postgres.generatedclasses.Tables.X_UNUSED;
import static org.jooq.util.postgres.PostgresDSL.arrayAppend;
import static org.jooq.util.postgres.PostgresDSL.arrayCat;
import static org.jooq.util.postgres.PostgresDSL.arrayPrepend;
@ -149,6 +152,8 @@ import org.jooq.test.postgres.generatedclasses.tables.records.T_3111Record;
import org.jooq.test.postgres.generatedclasses.tables.records.T_639NumbersTableRecord;
import org.jooq.test.postgres.generatedclasses.tables.records.T_725LobTestRecord;
import org.jooq.test.postgres.generatedclasses.tables.records.T_785Record;
import org.jooq.test.postgres.generatedclasses.tables.records.T_986_1Record;
import org.jooq.test.postgres.generatedclasses.tables.records.T_986_2Record;
import org.jooq.test.postgres.generatedclasses.tables.records.VLibraryRecord;
import org.jooq.test.postgres.generatedclasses.tables.records.XUnusedRecord;
import org.jooq.test.postgres.generatedclasses.udt.UAddressType;
@ -1334,4 +1339,24 @@ public class PostgresTest extends jOOQAbstractTest<
create().delete(T_3111).execute();
}
}
@Test
public void testPostgresMetaReferencesWithSameNameForeignKey() {
// [#986] [#3520] Be sure that shared foreign key names do not produce any irregular behaviour
List<ForeignKey<T_986_1Record, XUnusedRecord>> r1 = T_986_1.getReferencesTo(X_UNUSED);
List<ForeignKey<T_986_2Record, XUnusedRecord>> r2 = T_986_2.getReferencesTo(X_UNUSED);
assertEquals(1, r1.size());
assertEquals(1, r2.size());
assertEquals(T_986_1, r1.get(0).getTable());
assertEquals(T_986_2, r2.get(0).getTable());
assertEquals(asList(T_986_1.REF), r1.get(0).getFields());
assertEquals(asList(T_986_2.REF), r2.get(0).getFields());
assertEquals(0, (int) create().selectCount().from(T_986_1.join(X_UNUSED).onKey()).fetchOne(0, int.class));
assertEquals(0, (int) create().selectCount().from(T_986_2.join(X_UNUSED).onKey()).fetchOne(0, int.class));
}
}

View File

@ -101,8 +101,8 @@ public class Keys {
}
private static class ForeignKeys0 extends org.jooq.impl.AbstractKeys {
public static final org.jooq.ForeignKey<org.jooq.test.postgres.generatedclasses.tables.records.T_986_1Record, org.jooq.test.postgres.generatedclasses.tables.records.XUnusedRecord> T_986_1__FK_986 = createForeignKey(org.jooq.test.postgres.generatedclasses.Keys.UK_X_UNUSED_ID, org.jooq.test.postgres.generatedclasses.tables.T_986_1.T_986_1, org.jooq.test.postgres.generatedclasses.tables.T_986_1.T_986_1.REF, org.jooq.test.postgres.generatedclasses.tables.T_986_1.T_986_1.REF);
public static final org.jooq.ForeignKey<org.jooq.test.postgres.generatedclasses.tables.records.T_986_2Record, org.jooq.test.postgres.generatedclasses.tables.records.XUnusedRecord> T_986_2__FK_986 = createForeignKey(org.jooq.test.postgres.generatedclasses.Keys.UK_X_UNUSED_ID, org.jooq.test.postgres.generatedclasses.tables.T_986_2.T_986_2, org.jooq.test.postgres.generatedclasses.tables.T_986_2.T_986_2.REF, org.jooq.test.postgres.generatedclasses.tables.T_986_2.T_986_2.REF);
public static final org.jooq.ForeignKey<org.jooq.test.postgres.generatedclasses.tables.records.T_986_1Record, org.jooq.test.postgres.generatedclasses.tables.records.XUnusedRecord> T_986_1__FK_986 = createForeignKey(org.jooq.test.postgres.generatedclasses.Keys.UK_X_UNUSED_ID, org.jooq.test.postgres.generatedclasses.tables.T_986_1.T_986_1, org.jooq.test.postgres.generatedclasses.tables.T_986_1.T_986_1.REF);
public static final org.jooq.ForeignKey<org.jooq.test.postgres.generatedclasses.tables.records.T_986_2Record, org.jooq.test.postgres.generatedclasses.tables.records.XUnusedRecord> T_986_2__FK_986 = createForeignKey(org.jooq.test.postgres.generatedclasses.Keys.UK_X_UNUSED_ID, org.jooq.test.postgres.generatedclasses.tables.T_986_2.T_986_2, org.jooq.test.postgres.generatedclasses.tables.T_986_2.T_986_2.REF);
public static final org.jooq.ForeignKey<org.jooq.test.postgres.generatedclasses.tables.records.TBookRecord, org.jooq.test.postgres.generatedclasses.tables.records.TAuthorRecord> T_BOOK__FK_T_BOOK_AUTHOR_ID = createForeignKey(org.jooq.test.postgres.generatedclasses.Keys.PK_T_AUTHOR, org.jooq.test.postgres.generatedclasses.tables.TBook.T_BOOK, org.jooq.test.postgres.generatedclasses.tables.TBook.T_BOOK.AUTHOR_ID);
public static final org.jooq.ForeignKey<org.jooq.test.postgres.generatedclasses.tables.records.TBookRecord, org.jooq.test.postgres.generatedclasses.tables.records.TAuthorRecord> T_BOOK__FK_T_BOOK_CO_AUTHOR_ID = createForeignKey(org.jooq.test.postgres.generatedclasses.Keys.PK_T_AUTHOR, org.jooq.test.postgres.generatedclasses.tables.TBook.T_BOOK, org.jooq.test.postgres.generatedclasses.tables.TBook.T_BOOK.CO_AUTHOR_ID);
public static final org.jooq.ForeignKey<org.jooq.test.postgres.generatedclasses.tables.records.TBookRecord, org.jooq.test.postgres.generatedclasses.tables.records.TLanguageRecord> T_BOOK__FK_T_BOOK_LANGUAGE_ID = createForeignKey(org.jooq.test.postgres.generatedclasses.Keys.PK_T_LANGUAGE, org.jooq.test.postgres.generatedclasses.tables.TBook.T_BOOK, org.jooq.test.postgres.generatedclasses.tables.TBook.T_BOOK.LANGUAGE_ID);