mirror of
https://github.com/MariaDB/server.git
synced 2025-07-02 14:22:51 +03:00
Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation
on 5.0 The server crashes on an assert in net_end_statement indicating that the Diagnostics area wasn't set properly during execution. This happened on a multi table DELETE operation using the IGNORE keyword. The keyword is suppose to allow for execution to continue on a best effort despite some non-fatal errors. Instead execution stopped and no client response was sent which would have led to a protocol error if it hadn't been for the assert. This patch corrects this issue by checking for the existence of an IGNORE option before setting an error state during row-by-row delete iteration.
This commit is contained in:
@ -1846,4 +1846,149 @@ id
|
||||
TRUNCATE TABLE t2;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
aid INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (aid) REFERENCES t1 (id)
|
||||
) ENGINE=InnoDB;
|
||||
CREATE TABLE t3 (
|
||||
bid INT UNSIGNED NOT NULL,
|
||||
FOREIGN KEY (bid) REFERENCES t2 (id)
|
||||
) ENGINE=InnoDB;
|
||||
CREATE TABLE t4 (
|
||||
a INT
|
||||
) ENGINE=InnoDB;
|
||||
CREATE TABLE t5 (
|
||||
a INT
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO t1 (id) VALUES (1);
|
||||
INSERT INTO t2 (id, aid) VALUES (1, 1),(2,1),(3,1),(4,1);
|
||||
INSERT INTO t3 (bid) VALUES (1);
|
||||
INSERT INTO t4 VALUES (1),(2),(3),(4),(5);
|
||||
INSERT INTO t5 VALUES (1);
|
||||
DELETE t5 FROM t4 LEFT JOIN t5 ON t4.a= t5.a;
|
||||
DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1;
|
||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `t2` (`id`))
|
||||
DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1;
|
||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `t2` (`id`))
|
||||
DELETE IGNORE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1;
|
||||
DROP TABLE t3;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
DROP TABLES t4,t5;
|
||||
# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0
|
||||
# Testing for any side effects of IGNORE on AFTER DELETE triggers used with
|
||||
# transactional tables.
|
||||
#
|
||||
CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (a VARCHAR(100)) ENGINE=InnoDB;
|
||||
CREATE TABLE t3 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TABLE t4 (i INT NOT NULL PRIMARY KEY, t1i INT,
|
||||
FOREIGN KEY (t1i) REFERENCES t1(i))
|
||||
ENGINE=InnoDB;
|
||||
CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW
|
||||
BEGIN
|
||||
SET @b:='EXECUTED TRIGGER';
|
||||
INSERT INTO t2 VALUES (@b);
|
||||
SET @a:= error_happens_here;
|
||||
END||
|
||||
SET @b:="";
|
||||
SET @a:="";
|
||||
INSERT INTO t1 VALUES (1),(2),(3),(4);
|
||||
INSERT INTO t3 SELECT * FROM t1;
|
||||
** An error in a trigger causes rollback of the statement.
|
||||
DELETE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i;
|
||||
ERROR 42S22: Unknown column 'error_happens_here' in 'field list'
|
||||
SELECT @a,@b;
|
||||
@a @b
|
||||
EXECUTED TRIGGER
|
||||
SELECT * FROM t2;
|
||||
a
|
||||
SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i;
|
||||
i i
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
** Same happens with the IGNORE option
|
||||
DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i;
|
||||
ERROR 42S22: Unknown column 'error_happens_here' in 'field list'
|
||||
SELECT * FROM t2;
|
||||
a
|
||||
SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i;
|
||||
i i
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
**
|
||||
** The following is an attempt to demonstrate
|
||||
** error handling inside a row iteration.
|
||||
**
|
||||
DROP TRIGGER trg;
|
||||
TRUNCATE TABLE t1;
|
||||
TRUNCATE TABLE t2;
|
||||
TRUNCATE TABLE t3;
|
||||
INSERT INTO t1 VALUES (1),(2),(3),(4);
|
||||
INSERT INTO t3 VALUES (1),(2),(3),(4);
|
||||
INSERT INTO t4 VALUES (3,3),(4,4);
|
||||
CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW
|
||||
BEGIN
|
||||
SET @b:= CONCAT('EXECUTED TRIGGER FOR ROW ',CAST(OLD.i AS CHAR));
|
||||
INSERT INTO t2 VALUES (@b);
|
||||
END||
|
||||
** DELETE is prevented by foreign key constrains but errors are silenced.
|
||||
** The AFTER trigger isn't fired.
|
||||
DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i;
|
||||
** Tables are modified by best effort:
|
||||
SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i;
|
||||
i i
|
||||
3 3
|
||||
4 4
|
||||
** The AFTER trigger was only executed on successful rows:
|
||||
SELECT * FROM t2;
|
||||
a
|
||||
EXECUTED TRIGGER FOR ROW 1
|
||||
EXECUTED TRIGGER FOR ROW 2
|
||||
DROP TRIGGER trg;
|
||||
**
|
||||
** Induce an error midway through an AFTER-trigger
|
||||
**
|
||||
TRUNCATE TABLE t4;
|
||||
TRUNCATE TABLE t1;
|
||||
TRUNCATE TABLE t3;
|
||||
INSERT INTO t1 VALUES (1),(2),(3),(4);
|
||||
INSERT INTO t3 VALUES (1),(2),(3),(4);
|
||||
CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW
|
||||
BEGIN
|
||||
SET @a:= @a+1;
|
||||
IF @a > 2 THEN
|
||||
INSERT INTO t4 VALUES (5,5);
|
||||
END IF;
|
||||
END||
|
||||
SET @a:=0;
|
||||
** Errors in the trigger causes the statement to abort.
|
||||
DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i;
|
||||
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`t1i`) REFERENCES `t1` (`i`))
|
||||
SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i;
|
||||
i i
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
SELECT * FROM t4;
|
||||
i t1i
|
||||
DROP TRIGGER trg;
|
||||
DROP TABLE t4;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t3;
|
||||
End of 5.1 tests
|
||||
|
Reference in New Issue
Block a user