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.
This commit is contained in:
parent
9390ff53fc
commit
60f51af755
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user