Commit 60f51af7 authored by Jan Lindström's avatar Jan Lindström

MDEV-15042: INSERT ON DUPLICATE KEY UPDATE produces error 1032 (Can't find record)

Problem was that wrong error message was returned when insert
returned FK-error and there was no duplicate key to process.

row_ins
	If error from insert was DB_NO_REFERENCED_ROW and there was
	no duplicate key we should ignore ON DUPLICATE KEY UPDATE
	and return original error message.
parent 9390ff53
......@@ -58,3 +58,20 @@ SELECT * FROM t2;
i vi m
1 1 3
DROP TABLE t2, t1;
CREATE TABLE parent (
id INT PRIMARY KEY AUTO_INCREMENT
) ENGINE=INNODB;
CREATE TABLE child (
parent_id INT NOT NULL PRIMARY KEY,
id INT NOT NULL,
CONSTRAINT fk_c_parent FOREIGN KEY (parent_id) REFERENCES parent (id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=INNODB;
INSERT INTO child (id, parent_id) VALUES (1, 1);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `fk_c_parent` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
INSERT INTO child (id, parent_id) VALUES (1, 1) ON DUPLICATE KEY UPDATE id = VALUES(id);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `fk_c_parent` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
select * from parent;
id
select * from child;
parent_id id
drop table child, parent;
......@@ -61,3 +61,26 @@ INSERT into t2 VALUES (1, 1, 100);
INSERT INTO t2 (i,m) VALUES (1, 2) ON DUPLICATE KEY UPDATE m=3;
SELECT * FROM t2;
DROP TABLE t2, t1;
#
# MDEV-15042: INSERT ON DUPLICATE KEY UPDATE produces error 1032 (Can't find record)
#
CREATE TABLE parent (
id INT PRIMARY KEY AUTO_INCREMENT
) ENGINE=INNODB;
CREATE TABLE child (
parent_id INT NOT NULL PRIMARY KEY,
id INT NOT NULL,
CONSTRAINT fk_c_parent FOREIGN KEY (parent_id) REFERENCES parent (id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=INNODB;
--error ER_NO_REFERENCED_ROW_2
INSERT INTO child (id, parent_id) VALUES (1, 1);
--error ER_NO_REFERENCED_ROW_2
INSERT INTO child (id, parent_id) VALUES (1, 1) ON DUPLICATE KEY UPDATE id = VALUES(id);
select * from parent;
select * from child;
drop table child, parent;
......@@ -3696,12 +3696,24 @@ row_ins(
placing all gaplocks. */
err = DB_DUPLICATE_KEY;
break;
} else if (!node->duplicate) {
} else if (err == DB_DUPLICATE_KEY &&
!node->duplicate) {
/* Save 1st dup error. Ignore
subsequent dup errors. */
node->duplicate = node->index;
thr_get_trx(thr)->error_state
= DB_DUPLICATE_KEY;
} else if (err == DB_NO_REFERENCED_ROW) {
/* As a example consider
case INSERT INTO child (id)
VALUES (1) ON DUPLICATE
KEY UPDATE id =
VALUES(id);
where (1) does not cause
duplicate key. Thus
we should return original
DB_NO_REFERENCED_ROW */
DBUG_RETURN(err);
}
break;
}
......
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