Commit 08af835d authored by osku's avatar osku

Apply InnoDB-specific parts of the fix for bug #9680, wrong error from

cascading update.
parent 3d98fd8b
...@@ -457,6 +457,10 @@ convert_error_code_to_mysql( ...@@ -457,6 +457,10 @@ convert_error_code_to_mysql(
return(HA_ERR_FOUND_DUPP_KEY); return(HA_ERR_FOUND_DUPP_KEY);
} else if (error == (int) DB_FOREIGN_DUPLICATE_KEY) {
return(HA_ERR_FOREIGN_DUPLICATE_KEY);
} else if (error == (int) DB_RECORD_NOT_FOUND) { } else if (error == (int) DB_RECORD_NOT_FOUND) {
return(HA_ERR_NO_ACTIVE_RECORD); return(HA_ERR_NO_ACTIVE_RECORD);
......
...@@ -57,6 +57,10 @@ Created 5/24/1996 Heikki Tuuri ...@@ -57,6 +57,10 @@ Created 5/24/1996 Heikki Tuuri
buffer pool (for big transactions, buffer pool (for big transactions,
InnoDB stores the lock structs in the InnoDB stores the lock structs in the
buffer pool) */ buffer pool) */
#define DB_FOREIGN_DUPLICATE_KEY 46 /* foreign key constraints
activated by the operation would
lead to a duplicate key in some
table */
/* The following are partial failure codes */ /* The following are partial failure codes */
#define DB_FAIL 1000 #define DB_FAIL 1000
......
...@@ -3213,3 +3213,21 @@ drop trigger t2t; ...@@ -3213,3 +3213,21 @@ drop trigger t2t;
drop trigger t3t; drop trigger t3t;
drop trigger t4t; drop trigger t4t;
drop table t1, t2, t3, t4, t5; drop table t1, t2, t3, t4, t5;
CREATE TABLE t1 (
field1 varchar(8) NOT NULL DEFAULT '',
field2 varchar(8) NOT NULL DEFAULT '',
PRIMARY KEY (field1, field2)
) ENGINE=InnoDB;
CREATE TABLE t2 (
field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
FOREIGN KEY (field1) REFERENCES t1 (field1)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('old', 'somevalu');
INSERT INTO t1 VALUES ('other', 'anyvalue');
INSERT INTO t2 VALUES ('old');
INSERT INTO t2 VALUES ('other');
UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 1 would lead to a duplicate entry
DROP TABLE t2;
DROP TABLE t1;
...@@ -2106,3 +2106,32 @@ drop trigger t4t; ...@@ -2106,3 +2106,32 @@ drop trigger t4t;
drop table t1, t2, t3, t4, t5; drop table t1, t2, t3, t4, t5;
disconnect a; disconnect a;
disconnect b; disconnect b;
#
# Test that cascading updates leading to duplicate keys give the correct
# error message (bug #9680)
#
CREATE TABLE t1 (
field1 varchar(8) NOT NULL DEFAULT '',
field2 varchar(8) NOT NULL DEFAULT '',
PRIMARY KEY (field1, field2)
) ENGINE=InnoDB;
CREATE TABLE t2 (
field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
FOREIGN KEY (field1) REFERENCES t1 (field1)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('old', 'somevalu');
INSERT INTO t1 VALUES ('other', 'anyvalue');
INSERT INTO t2 VALUES ('old');
INSERT INTO t2 VALUES ('other');
--error ER_FOREIGN_DUPLICATE_KEY
UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
DROP TABLE t2;
DROP TABLE t1;
...@@ -1386,6 +1386,21 @@ row_ins_check_foreign_constraint( ...@@ -1386,6 +1386,21 @@ row_ins_check_foreign_constraint(
thr, foreign, &pcur, entry, thr, foreign, &pcur, entry,
&mtr); &mtr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
/* Since reporting a plain
"duplicate key" error
message to the user in
cases where a long CASCADE
operation would lead to a
duplicate key in some
other table is very
confusing, map duplicate
key errors resulting from
FK constraints to a
separate error code. */
if (err == DB_DUPLICATE_KEY) {
err = DB_FOREIGN_DUPLICATE_KEY;
}
break; break;
} }
......
...@@ -474,7 +474,8 @@ row_mysql_handle_errors( ...@@ -474,7 +474,8 @@ row_mysql_handle_errors(
trx->error_state = DB_SUCCESS; trx->error_state = DB_SUCCESS;
if (err == DB_DUPLICATE_KEY) { if ((err == DB_DUPLICATE_KEY)
|| (err == DB_FOREIGN_DUPLICATE_KEY)) {
if (savept) { if (savept) {
/* Roll back the latest, possibly incomplete /* Roll back the latest, possibly incomplete
insertion or update */ insertion or update */
......
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