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; ...@@ -58,3 +58,20 @@ SELECT * FROM t2;
i vi m i vi m
1 1 3 1 1 3
DROP TABLE t2, t1; 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); ...@@ -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; INSERT INTO t2 (i,m) VALUES (1, 2) ON DUPLICATE KEY UPDATE m=3;
SELECT * FROM t2; SELECT * FROM t2;
DROP TABLE t2, t1; 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( ...@@ -3696,12 +3696,24 @@ row_ins(
placing all gaplocks. */ placing all gaplocks. */
err = DB_DUPLICATE_KEY; err = DB_DUPLICATE_KEY;
break; break;
} else if (!node->duplicate) { } else if (err == DB_DUPLICATE_KEY &&
!node->duplicate) {
/* Save 1st dup error. Ignore /* Save 1st dup error. Ignore
subsequent dup errors. */ subsequent dup errors. */
node->duplicate = node->index; node->duplicate = node->index;
thr_get_trx(thr)->error_state thr_get_trx(thr)->error_state
= DB_DUPLICATE_KEY; = 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; 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