Bug #35312 | REF_CNSTRS.CONSTRAINT_NAME to STATISTIC.INDEX_NAME can be broken | ||
---|---|---|---|
Submitted: | 15 Mar 2008 17:53 | Modified: | 19 Mar 2008 0:20 |
Reporter: | Adrian Colomitchi | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Information schema | Severity: | S2 (Serious) |
Version: | 5.1.23-rc-community, 5.0, 5.1, 6.0 BK | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[15 Mar 2008 17:53]
Adrian Colomitchi
[17 Mar 2008 16:25]
Sveta Smirnova
Thank you for the report. Verified as described. Maybe better problem is showing if take in account next output: With KEY `to_a` (`a_serial_no`,`a_version`): select INDEX_NAME, INDEX_SCHEMA from information_schema.STATISTICS where TABLE_SCHEMA='test' and TABLE_NAME = 'b'; INDEX_NAME INDEX_SCHEMA PRIMARY test to_a test to_a test Without KEY `to_a` (`a_serial_no`,`a_version`): select INDEX_NAME, INDEX_SCHEMA from information_schema.STATISTICS where TABLE_SCHEMA='test' and TABLE_NAME = 'b'; INDEX_NAME INDEX_SCHEMA PRIMARY test fk_to_a test fk_to_a test
[17 Mar 2008 17:35]
Valeriy Kravchuk
I think this is not a bug. You explicitely set name for the INDEX, and explicitely set different name for the CONSTRAINT. Why do you expect them to bethe same eventually?
[18 Mar 2008 13:13]
Adrian Colomitchi
Hi Valeriy, I might be wrong in what I'll be saying below: if this is the case, I apologize in advance. > You explicitely set name for the INDEX, and > explicitely set different name for the CONSTRAINT. > Why do you expect them to bethe same eventually? By stating that I explicitly created the FK and INDEX with a different name, you state on a false track. The problem is *not* that the names mismatch. The problem is that if someone creates the index then the FK with different names, you have no ways of detecting *what columns in the detail table corresponds to which columns in the master table*!! Suppose that the database is not created by me, I am only requested to recover the metadata of the database (including the FK definition). Suppose that I need to get this metadata not for the purposes of being read by human eyes (or for the purposes of backup/restore the database) but further processing of this information (think database diagramming, or automatic code generation, or whatever purposes for which an SQL script is not enough). To understand better, try to do the following exercise: ------- exercise start ------- a. create the FK without any index. Wrote a set of SQL select statement (against the tables in the INFO_SCHEMA) to come with a structure of the result in the form (FK_name, MASTER_TABLE_NAME, MASTER_COLUMN_NAME, DETAIL_TABLE_NAME, DETAIL_COLUMN_NAME) - i.e. list all the FK-es together with the unique.column<->fk_column correspondence. b. now, before creating the FK, create an index on the detail table on the same columns that will be involved in the FK. Repeat the same procedure you derived at point a. in this case. ---- exercise end ---- I bet that, in the scenario b. you will fail. *This* failure is the bug. The scripts that I posted in the initial comment of the issue are only to diagnose and demonstrate the bug. My conclusion is that the problem arises from the underlaying assumption that "for a foreign key and its associated index, the TABLE_CONSTRAINT.CONSTRAINT_NAME is always the same as the STATISTICS.INDEX_NAME" that fails to be true when the index is created in advance under another name. The correct fix, in my opinion, would be to add another column to the TABLE_CONSTRAINTS (say CONSTRAINT_KEY_NAME) to say "the FK with the CONSTRAINT_NAME is using the CONSTRAINT_KEY_NAME index". Best regards, Adrian
[18 Mar 2008 20:18]
Valeriy Kravchuk
Read http://dev.mysql.com/doc/refman/5.0/en/key-column-usage-table.html. Then just try something like: mysql> select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where table_schema='tes t' and table_name='b'\G *************************** 1. row *************************** CONSTRAINT_CATALOG: NULL CONSTRAINT_SCHEMA: test CONSTRAINT_NAME: PRIMARY TABLE_CATALOG: NULL TABLE_SCHEMA: test TABLE_NAME: b COLUMN_NAME: id ORDINAL_POSITION: 1 POSITION_IN_UNIQUE_CONSTRAINT: NULL REFERENCED_TABLE_SCHEMA: NULL REFERENCED_TABLE_NAME: NULL REFERENCED_COLUMN_NAME: NULL *************************** 2. row *************************** CONSTRAINT_CATALOG: NULL CONSTRAINT_SCHEMA: test CONSTRAINT_NAME: fk_to_a TABLE_CATALOG: NULL TABLE_SCHEMA: test TABLE_NAME: b COLUMN_NAME: a_serial_no ORDINAL_POSITION: 1 POSITION_IN_UNIQUE_CONSTRAINT: 1 REFERENCED_TABLE_SCHEMA: test REFERENCED_TABLE_NAME: a REFERENCED_COLUMN_NAME: serial_no *************************** 3. row *************************** CONSTRAINT_CATALOG: NULL CONSTRAINT_SCHEMA: test CONSTRAINT_NAME: fk_to_a TABLE_CATALOG: NULL TABLE_SCHEMA: test TABLE_NAME: b COLUMN_NAME: a_version ORDINAL_POSITION: 2 POSITION_IN_UNIQUE_CONSTRAINT: 2 REFERENCED_TABLE_SCHEMA: test REFERENCED_TABLE_NAME: a REFERENCED_COLUMN_NAME: version 3 rows in set (0.01 sec) Look at rows 2 and 3 in the results, then figure out how to get the exacts results you need. All you need is already there, including the manual...
[19 Mar 2008 0:20]
Adrian Colomitchi
Thank, Valeriy My bad, I apologize. Thank you for the time spent in putting me on the right track. Adrian