diff --git a/mysql-test/suite/innodb/r/innodb_bug12661768.result b/mysql-test/suite/innodb/r/innodb_bug12661768.result new file mode 100644 index 00000000000..1f2401ddd47 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug12661768.result @@ -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 diff --git a/mysql-test/suite/innodb/t/innodb_bug12661768.test b/mysql-test/suite/innodb/t/innodb_bug12661768.test new file mode 100644 index 00000000000..01549a7e9e9 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug12661768.test @@ -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`; diff --git a/sql/handler.cc b/sql/handler.cc index 82f5f2ee841..895e7cc4df0 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -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)