[MDEV-7627] Some symbols in table name can cause to Error Code: 1050 when created FK Created: 2015-02-25 Updated: 2015-03-09 Resolved: 2015-03-09 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Data Definition - Alter Table, Storage Engine - InnoDB, Storage Engine - XtraDB |
| Affects Version/s: | 10.0.16 |
| Fix Version/s: | 10.0.18 |
| Type: | Bug | Priority: | Minor |
| Reporter: | Mikhail Gavrilov | Assignee: | Jan Lindström (Inactive) |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | CONSTRAINT, alter | ||
| Environment: |
Linux |
||
| Description |
|
Reproduce code:
Workaround is manual define CONSTRAINT name
Yet another example:
Workaround is manual define CONSTRAINT name
|
| Comments |
| Comment by Jan Lindström (Inactive) [ 2015-02-26 ] | |||||||||||||||||||||||
|
Lets start from the facts, this is not a bug. InnoDB internally uses foreign keys named with <table_name>ibfk<n> if no other name is provided. I strongly suggest that you try to avoid names starting with `#` and names ending with ibfk. Now the error message is really meaningless but you should see on error log something like this:
In above examples you have named your foreign key constraint so that alter will fail because there would be two identical foreign key names in InnoDB data dictionary. I will try to add more clearer error message so that show warnings after failed alter table would return more information why alter really failed. | |||||||||||||||||||||||
| Comment by Mikhail Gavrilov [ 2015-02-26 ] | |||||||||||||||||||||||
|
> I strongly suggest that you try to avoid names starting with `#` and names ending with ibfk. | |||||||||||||||||||||||
| Comment by Jan Lindström (Inactive) [ 2015-02-26 ] | |||||||||||||||||||||||
|
If you have create table like:
Then alter table like
WIll fail because it will try to create foreign key constraint with name `#departaments_tree_ibfk_1` in system charset, but that fails because table already has foreign key constraint with name `#departaments_tree_ibfk_1` in system charset. I personally would use:
| |||||||||||||||||||||||
| Comment by Mikhail Gavrilov [ 2015-02-26 ] | |||||||||||||||||||||||
|
I am understand this. | |||||||||||||||||||||||
| Comment by Jan Lindström (Inactive) [ 2015-02-26 ] | |||||||||||||||||||||||
|
Because numbering always starts from 1 and names are generated only for unnamed foreign key constraints. User given names are used exactly as they are given (on system charset naturally). | |||||||||||||||||||||||
| Comment by Jan Lindström (Inactive) [ 2015-02-26 ] | |||||||||||||||||||||||
|
I will improve the show warnings to show;
| |||||||||||||||||||||||
| Comment by Mikhail Gavrilov [ 2015-02-26 ] | |||||||||||||||||||||||
|
> I will improve the show warnings to show;
innodb generate name `#departaments_tree_ibfk_1` why innodb don't see that `#departaments_tree_ibfk_1` already reserved by another constraint and not use next number, and this occurs only in cases which I described above. | |||||||||||||||||||||||
| Comment by Mikhail Gavrilov [ 2015-02-26 ] | |||||||||||||||||||||||
|
Why using '#' is broken resolving logic? | |||||||||||||||||||||||
| Comment by Mikhail Gavrilov [ 2015-02-26 ] | |||||||||||||||||||||||
|
I think even more interesting is another question why it is not considered a bug innodb?
| |||||||||||||||||||||||
| Comment by Jan Lindström (Inactive) [ 2015-02-26 ] | |||||||||||||||||||||||
|
Last one still same
It will rename also existing fk name to test/bor#oda_ibfk_1 | |||||||||||||||||||||||
| Comment by Jan Lindström (Inactive) [ 2015-03-09 ] | |||||||||||||||||||||||
|
Ok, found the actual problem, at dict_table_get_highest_foreign_id() we should convert dictionary memory cache foreign key identifiers to filename charset before comparing. This is because table name is on that charset. | |||||||||||||||||||||||
| Comment by Jan Lindström (Inactive) [ 2015-03-09 ] | |||||||||||||||||||||||
|
commit 040027c888f9b9e1a41c82fd793e0cde289e5eb1 Analysis: Table name is on filename charset but foreign key Fix: Convert foreign key identifier to filename charset before |