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
|
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);
|
|||||||
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(
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user