You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug#36345882 Fix column ordering in Dbdict::buildFK_prepare
Contributed by Axel Svensson.
If one have a table with data adding a multicolumn foreign key
constraint could fail even if the data satisifies the constraint. Namely
if the order columns are mentioned in the references clause do not match
the order the columns are defined for the table.
Example#1, alter table add constraint foreign key:
mysql> create table prnt (pk1 int, pk2 int, primary key(pk2,pk1)
-> ) engine=ndbcluster;
mysql> create table chld (pk int primary key, col1 int, col2 int
-> ) engine=ndbcluster;
mysql> insert into prnt values (1,2);
mysql> insert into chld values (0,1,2);
mysql> alter table chld add
-> constraint fk foreign key(col2,col1)
-> references prnt(pk2,pk1);
mysql> \W
Show warnings enabled.
mysql> alter table chld
-> add constraint fk foreign key(col2,col1)
-> references prnt(pk2,pk1);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (Unknown error code)
Warning (Code 1296): Got error 255 'Foreign key constraint violated: No parent row found' from NDB
Error (Code 1452): Cannot add or update a child row: a foreign key constraint fails (Unknown error code)
Example#2, ndb_restore --rebuild-indexes:
mysql> create table prnt (pk1 int, pk2 int, primary key(pk2,pk1)
-> ) engine=ndbcluster;
mysql> create table chld (pk int primary key, col1 int, col2 int,
-> constraint fk foreign key(col2,col1)
-> references prnt(pk2,pk1)
-> ) engine=ndbcluster;
mysql> insert into prnt values (1,2);
mysql> insert into chld values (0,1,2);
ndb_mgm> start backup
...
Node 1: Backup 1 started from node 3 completed
mysql> drop table chld, prnt;
$ ndb_restore -b 1 -n 1 -m --disable-indexes BACKUP/BACKUP-1
$ ndb_restore -b 1 -n 1 -r --disable-indexes BACKUP/BACKUP-1
$ ndb_restore -b 1 -n 2 -r --disable-indexes BACKUP/BACKUP-1
$ ndb_restore -b 1 -n 1 --rebuild-indexes BACKUP/BACKUP-1
...
Failed to create foreign key fk parent test.prnt.PK child test.chld.fk : 255: Foreign key constraint violated: No parent row found
Problem:
When checking the existing data for a pending foreign key constraint
with multi column key, columns from referencing table were matches with
the columns in the referenced table in wrong order.
In the examples above, the columns (col2,col1) from referencing table is
matches against columns (pk1,pk2) in referenced table resulting in col2
is matched against pk1 and col1 against pk2 instead of the intention to
match col2 against pk2 and col1 against pk1.
The checking code expected the index in parent table to use the same
column order as specified in the references clause of constraint
definition. But unique indexes in NDB always uses the column order as
they appear in table definition.
In example above:
- PRIMARY KEY(pk1,pk2)
- PRIMARY KEY(pk2,pk1)
- UNIQUE KEY(pk1,pk2)
- UNIQUE KEY(pk2,pk1)
all would use key with column order as (pk1,pk2) since that is the
order in table definition
create table prnt (pk1 int, pk2 int)
Also note that the ordered index in the child table must have the
columns in the order specified in the constraint.
Note that the code maintaining the foreign key constraint did handle
multicolumn keys correctly.
Fix:
When Dbdict sends GSN_BUILD_FK_IMPL_REQ to TRIX it now sends the child
columns to fetch matching the parent index order.
Change-Id: I3bd57d3d2c36628c1dc03e1f590a2d5bcb9b04de
0 commit comments