Skip to content

Commit

Permalink
Fix for Bug#104641 (33237255), DatabaseMetaData.getImportedKeys can
Browse files Browse the repository at this point in the history
return duplicated foreign keys.
  • Loading branch information
soklakov committed Sep 2, 2021
1 parent 5f142a6 commit 2905415
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

Version 8.0.27

- Fix for Bug#104641 (33237255), DatabaseMetaData.getImportedKeys can return duplicated foreign keys.

- Fix for Bug#33185116, Have method ResultSet.getBoolean() supporting conversion of 'T' and 'F' in a VARCHAR to True/False (boolean).

- Fix for Bug#31117686, PROTOCOL ALLOWLIST NOT COMPATIBLE WITH IBM JAVA.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,11 @@ public java.sql.ResultSet getImportedKeys(String catalog, String schema, String
sqlBuf.append(generateUpdateRuleClause());
sqlBuf.append(" AS UPDATE_RULE,");
sqlBuf.append(generateDeleteRuleClause());
sqlBuf.append(" AS DELETE_RULE, A.CONSTRAINT_NAME AS FK_NAME, TC.CONSTRAINT_NAME AS PK_NAME,");
sqlBuf.append(" AS DELETE_RULE, A.CONSTRAINT_NAME AS FK_NAME, R.UNIQUE_CONSTRAINT_NAME AS PK_NAME,");
sqlBuf.append(importedKeyNotDeferrable);
sqlBuf.append(" AS DEFERRABILITY FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE A");
sqlBuf.append(" JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B USING (CONSTRAINT_NAME, TABLE_NAME) ");
sqlBuf.append(generateOptionalRefContraintsJoin());
sqlBuf.append(" LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON (A.REFERENCED_TABLE_SCHEMA = TC.TABLE_SCHEMA");
sqlBuf.append(" AND A.REFERENCED_TABLE_NAME = TC.TABLE_NAME");
sqlBuf.append(" AND TC.CONSTRAINT_TYPE IN ('UNIQUE', 'PRIMARY KEY'))");
sqlBuf.append("WHERE B.CONSTRAINT_TYPE = 'FOREIGN KEY'");
if (db != null) {
sqlBuf.append(" AND A.TABLE_SCHEMA = ?");
Expand Down
77 changes: 77 additions & 0 deletions src/test/java/testsuite/regression/MetaDataRegressionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5314,4 +5314,81 @@ public void testBug95280() throws Exception {
}
}
}

/**
* Tests fix for Bug#104641 (33237255), DatabaseMetaData.getImportedKeys can return duplicated foreign keys.
*
* @throws Exception
*/
@Test
public void testBug104641() throws Exception {
String databaseName1 = "dbBug104641";
createDatabase(databaseName1);
createTable(databaseName1 + ".table1",
"(`CREATED` datetime DEFAULT NULL,`ID` bigint NOT NULL AUTO_INCREMENT,`LRN_ID` bigint DEFAULT '0',`USERNAME` varchar(50) NOT NULL,"
+ "PRIMARY KEY (`ID`),UNIQUE KEY `U_table1_LRN_ID` (`LRN_ID`),UNIQUE KEY `U_table1_USERNAME` (`USERNAME`) )");
createTable(databaseName1 + ".table2",
"(`AL_ID` varchar(50) DEFAULT NULL,`CREATED` datetime DEFAULT NULL,`ID` bigint NOT NULL AUTO_INCREMENT,`USER_ID` bigint DEFAULT NULL,"
+ "PRIMARY KEY (`ID`),KEY `fk_table2_user_id` (`USER_ID`),KEY `index_al_id1` (`AL_ID`),"
+ "CONSTRAINT `fk_table2_user_id` FOREIGN KEY (`USER_ID`) REFERENCES `table1` (`ID`) )");
createTable(databaseName1 + ".table3",
"(`AL_ID` varchar(50) DEFAULT NULL,`ID` bigint NOT NULL AUTO_INCREMENT,`USER_ID` bigint DEFAULT NULL,`LRN_ID` bigint DEFAULT '0',"
+ "PRIMARY KEY (`ID`),KEY `fk_table3_LRN_ID` (`LRN_ID`),KEY `index_al_id2` (`AL_ID`),"
+ "CONSTRAINT `fk_table3_LRN_ID` FOREIGN KEY `U_table1_LRN_ID` (`LRN_ID`) REFERENCES `table1` (`LRN_ID`) )");

Properties props = new Properties();
props.setProperty(PropertyKey.useSSL.getKeyName(), "false");
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
for (boolean useIS : new boolean[] { false, true }) {
for (String databaseTerm : new String[] { "CATALOG", "SCHEMA" }) {
props.setProperty(PropertyKey.useInformationSchema.getKeyName(), "" + useIS);
props.setProperty(PropertyKey.databaseTerm.getKeyName(), databaseTerm);

boolean dbTermIsSchema = databaseTerm.contentEquals("SCHEMA");

String err = "useInformationSchema=" + useIS + ", databaseTerm=" + databaseTerm;
Connection con = getConnectionWithProps(props);
DatabaseMetaData meta = con.getMetaData();

this.rs = dbTermIsSchema ? meta.getImportedKeys(null, databaseName1, "table2") : meta.getImportedKeys(databaseName1, null, "table2");
assertTrue(this.rs.next(), err);
assertEquals(dbTermIsSchema ? "def" : databaseName1, this.rs.getString("PKTABLE_CAT"), err);
assertEquals(dbTermIsSchema ? databaseName1 : null, this.rs.getString("PKTABLE_SCHEM"), err);
assertEquals(dbTermIsSchema ? "def" : databaseName1, this.rs.getString("FKTABLE_CAT"), err);
assertEquals(dbTermIsSchema ? databaseName1 : null, this.rs.getString("FKTABLE_SCHEM"), err);
assertEquals("table1", this.rs.getString("PKTABLE_NAME"), err);
assertEquals("ID", this.rs.getString("PKCOLUMN_NAME"), err);
assertEquals("table2", this.rs.getString("FKTABLE_NAME"), err);
assertEquals("USER_ID", this.rs.getString("FKCOLUMN_NAME"), err);
assertEquals(1, this.rs.getInt("KEY_SEQ"), err);
assertEquals(1, this.rs.getInt("UPDATE_RULE"), err);
assertEquals(1, this.rs.getInt("DELETE_RULE"), err);
assertEquals("fk_table2_user_id", this.rs.getString("FK_NAME"), err);
assertEquals(useIS ? "PRIMARY" : null, this.rs.getString("PK_NAME"), err);
assertEquals(7, this.rs.getInt("DEFERRABILITY"), err);
assertFalse(this.rs.next(), err);

this.rs = dbTermIsSchema ? meta.getImportedKeys(null, databaseName1, "table3") : meta.getImportedKeys(databaseName1, null, "table3");
assertTrue(this.rs.next(), err);
assertEquals(dbTermIsSchema ? "def" : databaseName1, this.rs.getString("PKTABLE_CAT"), err);
assertEquals(dbTermIsSchema ? databaseName1 : null, this.rs.getString("PKTABLE_SCHEM"), err);
assertEquals(dbTermIsSchema ? "def" : databaseName1, this.rs.getString("FKTABLE_CAT"), err);
assertEquals(dbTermIsSchema ? databaseName1 : null, this.rs.getString("FKTABLE_SCHEM"), err);
assertEquals("table1", this.rs.getString("PKTABLE_NAME"), err);
assertEquals("LRN_ID", this.rs.getString("PKCOLUMN_NAME"), err);
assertEquals("table3", this.rs.getString("FKTABLE_NAME"), err);
assertEquals("LRN_ID", this.rs.getString("FKCOLUMN_NAME"), err);
assertEquals(1, this.rs.getInt("KEY_SEQ"), err);
assertEquals(1, this.rs.getInt("UPDATE_RULE"), err);
assertEquals(1, this.rs.getInt("DELETE_RULE"), err);
assertEquals("fk_table3_LRN_ID", this.rs.getString("FK_NAME"), err);
assertEquals(useIS ? "U_table1_LRN_ID" : null, this.rs.getString("PK_NAME"), err);
assertEquals(7, this.rs.getInt("DEFERRABILITY"), err);
assertFalse(this.rs.next(), err);

con.close();
}
}

}
}

0 comments on commit 2905415

Please sign in to comment.