Fix Bug#12661768 UPDATE IGNORE CRASHES SERVER IF TABLE IS INNODB AND IT IS

PARENT FOR OTHER ONE

Do not try to lookup key_nr'th key in 'table' because there may not be such
a key there. key_nr is the number of the key in the _child_ table name, not
in the parent table.

Instead just print the fields of the record that are covered by the first key
defined on the parent table.

This bug gets a better fix in MySQL 5.6, which is too risky for 5.1 and 5.5.

Approved by:	Jon Olav Hauglid (via IM)
This commit is contained in:
Vasil Dimov 2011-10-25 16:46:38 +03:00
parent 76b20ba14a
commit 7312f83cb9
3 changed files with 59 additions and 1 deletions

View File

@ -0,0 +1,2 @@
SET SESSION foreign_key_checks=0;
ERROR 23000: Upholding foreign key constraints for table 'bug12661768_1', entry '3-bbb', key 2 would lead to a duplicate entry

View File

@ -0,0 +1,50 @@
#
# Bug#12661768 UPDATE IGNORE CRASHES SERVER IF TABLE IS INNODB AND IT IS
# PARENT FOR OTHER ONE
#
-- source include/have_innodb.inc
SET SESSION foreign_key_checks=0;
# only interested that the "UPDATE IGNORE" at the end does not crash the server
-- disable_query_log
-- disable_result_log
SET NAMES utf8;
-- let $t1_name = bug12661768_1
-- let $t2_name = bug12661768_2
-- let $fk_name = ab_on_2
-- let $key_str = 'bbb'
eval DROP TABLE IF EXISTS `$t2_name`, `$t1_name`;
eval CREATE TABLE `$t1_name` (
a INT,
b VARCHAR(512),
PRIMARY KEY (a, b)
) ENGINE=INNODB;
eval CREATE TABLE `$t2_name` (
id INT,
a INT,
b VARCHAR(512),
PRIMARY KEY (id),
UNIQUE KEY `$fk_name` (a, b),
FOREIGN KEY (a, b) REFERENCES `$t1_name` (a, b)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB;
eval INSERT INTO `$t1_name` VALUES (1, $key_str);
eval INSERT INTO `$t2_name` VALUES (100, 1, $key_str), (101, 3, $key_str);
SET SESSION foreign_key_checks=1;
-- enable_result_log
-- error ER_FOREIGN_DUPLICATE_KEY
eval UPDATE IGNORE `$t1_name` SET a = 3;
eval DROP TABLE `$t2_name`, `$t1_name`;

View File

@ -2692,7 +2692,13 @@ void handler::print_error(int error, myf errflag)
char key[MAX_KEY_LENGTH];
String str(key,sizeof(key),system_charset_info);
/* Table is opened and defined at this point */
key_unpack(&str,table,(uint) key_nr);
key_unpack(&str,table,0 /* Use 0 instead of key_nr because key_nr
is a key number in the child FK table, not in our 'table'. See
Bug#12661768 UPDATE IGNORE CRASHES SERVER IF TABLE IS INNODB
AND IT IS PARENT FOR OTHER ONE
This bug gets a better fix in MySQL 5.6, but it is too risky
to get that in 5.1 and 5.5 (extending the handler interface
and adding new error message codes */);
max_length= (MYSQL_ERRMSG_SIZE-
(uint) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
if (str.length() >= max_length)