BUG#18819: DELETE IGNORE hangs on foreign key parent delete

If the error happens during DELETE IGNORE, nothing could be send to the
client, thus leaving it frozen expecting the reply.

The problem was that if some error occurred, it wouldn't be reported to
the client because of IGNORE, but neither success would be reported.

MySQL 4.1 would not freeze the client, but will report

  ERROR 1105 (HY000): Unknown error

instead, which is also a bug.

The solution is to report success if we are in DELETE IGNORE and some
non-fatal error has happened.
parent acaa584c
......@@ -104,3 +104,19 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` =
id1
2
DROP TABLE t1, t2;
DROP TABLE IF EXISTS t2, t1;
CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB;
CREATE TABLE t2 (
i INT NOT NULL,
FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION
) ENGINE= InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
DELETE IGNORE FROM t1 WHERE i = 1;
Warnings:
Error 1217 Cannot delete or update a parent row: a foreign key constraint fails
SELECT * FROM t1, t2;
i i
1 1
DROP TABLE t2, t1;
End of 4.1 tests.
......@@ -117,3 +117,32 @@ INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES
SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = 1 AND `id3` = 2);
DROP TABLE t1, t2;
#
# BUG#18819: DELETE IGNORE hangs on foreign key parent delete
#
# The bug itself does not relate to InnoDB, but we have to use foreign
# keys to reproduce it.
#
--disable_warnings
DROP TABLE IF EXISTS t2, t1;
--enable_warnings
CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB;
CREATE TABLE t2 (
i INT NOT NULL,
FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION
) ENGINE= InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
DELETE IGNORE FROM t1 WHERE i = 1;
SELECT * FROM t1, t2;
DROP TABLE t2, t1;
--echo End of 4.1 tests.
......@@ -253,7 +253,8 @@ cleanup:
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
if (error >= 0 || thd->net.report_error)
if ((error >= 0 || thd->net.report_error) &&
(!thd->lex->ignore || thd->is_fatal_error))
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0);
else
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment