diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 1aa22349593..e840b95f1ba 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -724,3 +724,18 @@ ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (` UPDATE t1, t2 SET t1.fld1= t1.fld1 + 3; ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) DROP TABLE t2, t1; +# +# BUG#22037930: INSERT IGNORE FAILS TO IGNORE FOREIGN +# KEY CONSTRAINT +CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE= INNODB; +CREATE TABLE t2 (fld1 VARCHAR(10), fld2 INT NOT NULL, +CONSTRAINT fk FOREIGN KEY (fld2) REFERENCES t1(fld1)) ENGINE= INNODB; +# Without patch, reports incorrect error. +INSERT INTO t2 VALUES('abc', 2) ON DUPLICATE KEY UPDATE fld1= 'def'; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +REPLACE INTO t2 VALUES('abc', 2); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +INSERT IGNORE INTO t2 VALUES('abc', 2) ON DUPLICATE KEY UPDATE fld1= 'def'; +Warnings: +Warning 1452 `test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) +DROP TABLE t2, t1; diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index ea89872200c..94cf5d3b475 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -591,3 +591,25 @@ UPDATE t1, t2 SET t2.fld2= t2.fld2 + 3; UPDATE t1, t2 SET t1.fld1= t1.fld1 + 3; DROP TABLE t2, t1; + + +--echo # +--echo # BUG#22037930: INSERT IGNORE FAILS TO IGNORE FOREIGN +--echo # KEY CONSTRAINT + +CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE= INNODB; + +CREATE TABLE t2 (fld1 VARCHAR(10), fld2 INT NOT NULL, +CONSTRAINT fk FOREIGN KEY (fld2) REFERENCES t1(fld1)) ENGINE= INNODB; + +--echo # Without patch, reports incorrect error. +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES('abc', 2) ON DUPLICATE KEY UPDATE fld1= 'def'; +--error ER_NO_REFERENCED_ROW_2 +REPLACE INTO t2 VALUES('abc', 2); + +--enable_warnings +INSERT IGNORE INTO t2 VALUES('abc', 2) ON DUPLICATE KEY UPDATE fld1= 'def'; +--disable_warnings + +DROP TABLE t2, t1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a267108c847..dc7cb698476 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1521,16 +1521,25 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) insert_id_for_cur_row= table->file->insert_id_for_cur_row; else table->file->insert_id_for_cur_row= insert_id_for_cur_row; - bool is_duplicate_key_error; - if (table->file->is_fatal_error(error, HA_CHECK_DUP | HA_CHECK_FK_ERROR)) + + /* + If it is a FK constraint violation and 'ignore' flag is set, + report a warning instead of error. + */ + if (info->ignore && !table->file->is_fatal_error(error, + HA_CHECK_FK_ERROR)) + goto ok_or_after_trg_err; + + if (table->file->is_fatal_error(error, HA_CHECK_DUP)) goto err; - is_duplicate_key_error= table->file->is_fatal_error(error, 0); - if (!is_duplicate_key_error) + + if (!table->file->is_fatal_error(error, 0)) { /* - We come here when we had an ignorable error which is not a duplicate - key error. In this we ignore error if ignore flag is set, otherwise - report error as usual. We will not do any duplicate key processing. + We come here when we have an ignorable error which is not a duplicate + key error or FK error(Ex: Partition related errors). In this case we + ignore the error if ignore flag is set, otherwise report error as usual. + We will not do any duplicate key processing. */ if (info->ignore) goto ok_or_after_trg_err; /* Ignoring a not fatal error, return 0 */