Bug #95280 | DatabaseMetaData.getImportedKeys returns double the rows | ||
---|---|---|---|
Submitted: | 7 May 2019 13:34 | Modified: | 21 May 2021 16:21 |
Reporter: | Chitra Dandin | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / J | Severity: | S2 (Serious) |
Version: | 8.0.15, 8.0.16, 8.0.21 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | DatabaseMetaData, MySQL 8, regression, useInformationSchema |
[7 May 2019 13:34]
Chitra Dandin
[7 May 2019 13:41]
Chitra Dandin
Fixed version
[7 May 2019 13:52]
MySQL Verification Team
Thank you for the bug report. The mentioned query against 8.0.16 server version returns 0 rows.
[7 May 2019 13:56]
Chitra Dandin
Sorry for not being clear in the steps. I have used a dummy catalog name 'test' and a dummy table name 'xyz' in the query. You will have to change those to valid values in your schema. Look for this: A.TABLE_SCHEMA LIKE 'test' AND A.TABLE_NAME='xyz'
[8 May 2019 12:33]
MySQL Verification Team
Hello Chitra, Thank you for the details. I could not reproduce this issue with Conn/J version 8.0.16, MySQL Server 8.0.16 and dummy schema, java test case. Could you please provide logical dump of the schema(SQL format), java test case to reproduce this issue at our end? Thank you. thanks, Umesh ## public class Main { public static void main(String[] args) throws Exception { Connection conn = getMySqlConnection(); DatabaseMetaData meta = conn.getMetaData(); ResultSet rs = meta.getImportedKeys(conn.getCatalog(), null, "products"); while (rs.next()) { String fkTableName = rs.getString("FKTABLE_NAME"); String fkColumnName = rs.getString("FKCOLUMN_NAME"); int fkSequence = rs.getInt("KEY_SEQ"); System.out.println("getExportedKeys(): fkTableName=" + fkTableName); System.out.println("getExportedKeys(): fkColumnName=" + fkColumnName); System.out.println("getExportedKeys(): fkSequence=" + fkSequence); } conn.close(); } public static Connection getMySqlConnection() throws Exception { String driver = "com.mysql.cj.jdbc.Driver"; String url = "jdbc:mysql://localhost/dbdemo"; String username = "root"; String password = "Mysql123!"; Class.forName(driver); Connection conn = DriverManager.getConnection(url, username, password); return conn; } run: getExportedKeys(): fkTableName=products getExportedKeys(): fkColumnName=cat_id getExportedKeys(): fkSequence=1 BUILD SUCCESSFUL (total time: 3 seconds) - schema CREATE DATABASE IF NOT EXISTS dbdemo; USE dbdemo; CREATE TABLE categories( cat_id int not null auto_increment primary key, cat_name varchar(255) not null, cat_description text ) ENGINE=InnoDB; CREATE TABLE products( prd_id int not null auto_increment primary key, prd_name varchar(355) not null, prd_price decimal, cat_id int not null, FOREIGN KEY fk_cat(cat_id) REFERENCES categories1(cat_id) ON UPDATE CASCADE ON DELETE RESTRICT )ENGINE=InnoDB;
[8 May 2019 14:11]
Chitra Dandin
Hi, I tried with your schema and I could not reproduce it either. But then I realized we have 2 schema with same structure with one of them being empty. We have it like that for 2 reasons: 1. Much faster to update/sync DDL 2. to run DB-tests against Anyways, coming back to the issue. I created a dbdemo2 schema using your script and then I was able to reproduce my issue. I got 2 results for 'dbdemo' and 'products'.
[8 May 2019 14:50]
Chitra Dandin
The problem is in this JOIN with INFORMATION_SCHEMA.TABLE_CONSTRAINTS. It only uses CONSTRAINT_NAME and TABLE_NAME. If you add TABLE_SCHEMA also to it, that will solve the problem. Refer to com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema#getImportedKeys Line# 417: sqlBuf.append(" JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B USING (CONSTRAINT_NAME, TABLE_NAME) ");
[9 May 2019 6:01]
MySQL Verification Team
Thank you for the feedback. With Conn/J 8.0.16 and MySQL Server 8.0.16, below schema and java test case: CREATE DATABASE IF NOT EXISTS dbdemo; USE dbdemo; CREATE TABLE categories( cat_id int not null auto_increment primary key, cat_name varchar(255) not null, cat_description text ) ENGINE=InnoDB; CREATE TABLE products( prd_id int not null auto_increment primary key, prd_name varchar(355) not null, prd_price decimal, cat_id int not null, FOREIGN KEY fk_cat(cat_id) REFERENCES categories(cat_id) ON UPDATE CASCADE ON DELETE RESTRICT )ENGINE=InnoDB; CREATE DATABASE IF NOT EXISTS dbdemo2; USE dbdemo2; CREATE TABLE categories( cat_id int not null auto_increment primary key, cat_name varchar(255) not null, cat_description text ) ENGINE=InnoDB; CREATE TABLE products( prd_id int not null auto_increment primary key, prd_name varchar(355) not null, prd_price decimal, cat_id int not null, FOREIGN KEY fk_cat(cat_id) REFERENCES categories(cat_id) ON UPDATE CASCADE ON DELETE RESTRICT )ENGINE=InnoDB; run: getExportedKeys(): fkTableName=products getExportedKeys(): fkColumnName=cat_id getExportedKeys(): fkSequence=1 getExportedKeys(): fkTableName=products getExportedKeys(): fkColumnName=cat_id getExportedKeys(): fkSequence=1 BUILD SUCCESSFUL (total time: 4 seconds) - With Conn/J 8.0.16 and MySQL Server 5.7.26, below schema and java test case: CREATE DATABASE IF NOT EXISTS dbdemo; USE dbdemo; CREATE TABLE categories( cat_id int not null auto_increment primary key, cat_name varchar(255) not null, cat_description text ) ENGINE=InnoDB; CREATE TABLE products( prd_id int not null auto_increment primary key, prd_name varchar(355) not null, prd_price decimal, cat_id int not null, FOREIGN KEY fk_cat(cat_id) REFERENCES categories(cat_id) ON UPDATE CASCADE ON DELETE RESTRICT )ENGINE=InnoDB; CREATE DATABASE IF NOT EXISTS dbdemo2; USE dbdemo2; CREATE TABLE categories( cat_id int not null auto_increment primary key, cat_name varchar(255) not null, cat_description text ) ENGINE=InnoDB; CREATE TABLE products( prd_id int not null auto_increment primary key, prd_name varchar(355) not null, prd_price decimal, cat_id int not null, FOREIGN KEY fk_cat(cat_id) REFERENCES categories(cat_id) ON UPDATE CASCADE ON DELETE RESTRICT )ENGINE=InnoDB; run: getExportedKeys(): fkTableName=products getExportedKeys(): fkColumnName=cat_id getExportedKeys(): fkSequence=1 BUILD SUCCESSFUL (total time: 2 seconds)
[9 May 2019 6:05]
MySQL Verification Team
- Looks like regression to me - C/J 5.1.47, MySQL Server 8.0.16 and below schema - looks fine i.e no duplicates observed CREATE DATABASE IF NOT EXISTS dbdemo; USE dbdemo; CREATE TABLE categories( cat_id int not null auto_increment primary key, cat_name varchar(255) not null, cat_description text ) ENGINE=InnoDB; CREATE TABLE products( prd_id int not null auto_increment primary key, prd_name varchar(355) not null, prd_price decimal, cat_id int not null, FOREIGN KEY fk_cat(cat_id) REFERENCES categories(cat_id) ON UPDATE CASCADE ON DELETE RESTRICT )ENGINE=InnoDB; CREATE DATABASE IF NOT EXISTS dbdemo2; USE dbdemo2; CREATE TABLE categories( cat_id int not null auto_increment primary key, cat_name varchar(255) not null, cat_description text ) ENGINE=InnoDB; CREATE TABLE products( prd_id int not null auto_increment primary key, prd_name varchar(355) not null, prd_price decimal, cat_id int not null, FOREIGN KEY fk_cat(cat_id) REFERENCES categories(cat_id) ON UPDATE CASCADE ON DELETE RESTRICT )ENGINE=InnoDB; run: getExportedKeys(): fkTableName=products getExportedKeys(): fkColumnName=cat_id getExportedKeys(): fkSequence=1 BUILD SUCCESSFUL (total time: 1 second)
[8 Jan 2020 11:07]
Stephan Heinrich
Same problem with MySQL 8.0.18 and connector 8.0.18.
[28 Aug 2020 5:50]
MySQL Verification Team
Bug #100665 marked as duplicate of this one
[30 Sep 2020 14:47]
OCA Admin
Contribution submitted via Github - Bug #100665 - Suboptimal DatabaseMetaDataUsingInfoSchema#getImportedKeys() (*) Contribution by Miron Balcerzak (Github mironbalcerzak, mysql-connector-j/pull/55): Please see the bug report available at - https://bugs.mysql.com/bug.php?id=100665 The OCA has been completed and I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.
Contribution: git_patch_474983209.txt (text/plain), 3.19 KiB.
[21 May 2021 16:21]
Daniel So
Added the following entry to the Connector/J 8.0.26 changelog: "Row were duplicated in the ResultSet returned by the DatabaseMetaData.getImportedKeys() method. It was due to a faulty query in the method, which has been corrected by this patch. Thanks to Miron Balcerzak for contributing to the fix."
[17 Aug 2021 1:34]
Efim Pyshnograev
I was able to reproduce this problem on MySQL Connector 8.0.26. This issue is marked as fixed there, so I assume something has regressed. I've prepared a repo with the steps to reproduce the problem. Strangely, everything works fine for 8.0.25, but fails for 8.0.26. Can somebody please take a look? https://github.com/badgersow/mysql-duplicate-fk-bug
[17 Aug 2021 7:23]
Alexander Soklakov
Hi Efim, Could you open a new bug report for this issue?
[17 Aug 2021 7:39]
Efim Pyshnograev
Sure. I've just filed https://bugs.mysql.com/bug.php?id=104641