diff options
author | Marko Mäkelä <marko.makela@oracle.com> | 2011-10-25 17:33:38 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@oracle.com> | 2011-10-25 17:33:38 +0300 |
commit | 013ba71dfdd6f9d49730c1a918d1d089976faefd (patch) | |
tree | 730c3fbdaf5501f23b6ce997a3c31b77350d169a /mysql-test/suite | |
parent | dce337406ea07b4581bf724133d5262fddd365f3 (diff) | |
download | mariadb-git-013ba71dfdd6f9d49730c1a918d1d089976faefd.tar.gz |
Bug#13002783 PARTIALLY UNINITIALIZED CASCADE UPDATE VECTOR
In the ON UPDATE CASCADE clause of FOREIGN KEY constraints, the
calculated update vector was not fully initialized. This bug was
introduced in the InnoDB Plugin when implementing support for
ROW_FORMAT=DYNAMIC.
Additionally, the data type information was not initialized, but
apparently it has never been needed in this case. Nevertheless, it is
not good programming practice to pass uninitialized values around.
calc_row_difference(): Declare the update field uninitialized in
Valgrind. Copy the data type information as well, except when the
field is SQL NULL. In the built-in InnoDB, initialize
ufield->extern_storage = FALSE (an initialization bug that had gone
unnoticed this far). The InnoDB Plugin and later have this flag to
dfield_t and have always initialized it properly.
row_ins_cascade_calc_update_vec(): Reduce the scope of some
pointers. Initialize orig_len. (This caused the bug in InnoDB Plugin
and later.)
row_ins_foreign_check_on_constraint(): Simplify a condition. Declare
the update vector uninitialized.
rb:771 approved by Jimmy Yang
Diffstat (limited to 'mysql-test/suite')
-rw-r--r-- | mysql-test/suite/innodb/r/innodb.result | 16 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb.test | 18 | ||||
-rw-r--r-- | mysql-test/suite/innodb_plugin/r/innodb.result | 16 | ||||
-rw-r--r-- | mysql-test/suite/innodb_plugin/t/innodb.test | 18 |
4 files changed, 66 insertions, 2 deletions
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index c6f6f352743..edf3c7d2753 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -1293,6 +1293,20 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; ERROR 42S22: Unknown column 't1.id' in 'where clause' drop table t3,t2,t1; +CREATE TABLE t1 ( +c1 VARCHAR(8), c2 VARCHAR(8), +PRIMARY KEY (c1, c2) +) ENGINE=InnoDB; +CREATE TABLE t2 ( +c0 INT PRIMARY KEY, +c1 VARCHAR(8) UNIQUE, +FOREIGN KEY (c1) REFERENCES t1 (c1) ON UPDATE CASCADE +) ENGINE=InnoDB; +INSERT INTO t1 VALUES ('old', 'somevalu'), ('other', 'anyvalue'); +INSERT INTO t2 VALUES (10, 'old'), (20, 'other'); +UPDATE t1 SET c1 = 'other' WHERE c1 = 'old'; +ERROR 23000: Upholding foreign key constraints for table 't1', entry '', key 2 would lead to a duplicate entry +DROP TABLE t2,t1; create table t1( id int primary key, pid int, @@ -1671,7 +1685,7 @@ variable_value - @innodb_rows_deleted_orig 71 SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; variable_value - @innodb_rows_inserted_orig -1063 +1067 SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; variable_value - @innodb_rows_updated_orig 865 diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index 480183b9e2d..ef050390b48 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -1021,6 +1021,24 @@ update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; drop table t3,t2,t1; +# test ON UPDATE CASCADE +CREATE TABLE t1 ( + c1 VARCHAR(8), c2 VARCHAR(8), + PRIMARY KEY (c1, c2) +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + c0 INT PRIMARY KEY, + c1 VARCHAR(8) UNIQUE, + FOREIGN KEY (c1) REFERENCES t1 (c1) ON UPDATE CASCADE +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES ('old', 'somevalu'), ('other', 'anyvalue'); +INSERT INTO t2 VALUES (10, 'old'), (20, 'other'); +-- error ER_FOREIGN_DUPLICATE_KEY +UPDATE t1 SET c1 = 'other' WHERE c1 = 'old'; +DROP TABLE t2,t1; + # # test for recursion depth limit # diff --git a/mysql-test/suite/innodb_plugin/r/innodb.result b/mysql-test/suite/innodb_plugin/r/innodb.result index d3f7a0b9fff..a550b9702bb 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb.result +++ b/mysql-test/suite/innodb_plugin/r/innodb.result @@ -1301,6 +1301,20 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; ERROR 42S22: Unknown column 't1.id' in 'where clause' drop table t3,t2,t1; +CREATE TABLE t1 ( +c1 VARCHAR(8), c2 VARCHAR(8), +PRIMARY KEY (c1, c2) +) ENGINE=InnoDB; +CREATE TABLE t2 ( +c0 INT PRIMARY KEY, +c1 VARCHAR(8) UNIQUE, +FOREIGN KEY (c1) REFERENCES t1 (c1) ON UPDATE CASCADE +) ENGINE=InnoDB; +INSERT INTO t1 VALUES ('old', 'somevalu'), ('other', 'anyvalue'); +INSERT INTO t2 VALUES (10, 'old'), (20, 'other'); +UPDATE t1 SET c1 = 'other' WHERE c1 = 'old'; +ERROR 23000: Upholding foreign key constraints for table 't1', entry '', key 2 would lead to a duplicate entry +DROP TABLE t2,t1; create table t1( id int primary key, pid int, @@ -1679,7 +1693,7 @@ variable_value - @innodb_rows_deleted_orig 71 SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; variable_value - @innodb_rows_inserted_orig -1067 +1071 SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; variable_value - @innodb_rows_updated_orig 866 diff --git a/mysql-test/suite/innodb_plugin/t/innodb.test b/mysql-test/suite/innodb_plugin/t/innodb.test index cfc2277d501..1480492cf2a 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb.test +++ b/mysql-test/suite/innodb_plugin/t/innodb.test @@ -1040,6 +1040,24 @@ update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; drop table t3,t2,t1; +# test ON UPDATE CASCADE +CREATE TABLE t1 ( + c1 VARCHAR(8), c2 VARCHAR(8), + PRIMARY KEY (c1, c2) +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + c0 INT PRIMARY KEY, + c1 VARCHAR(8) UNIQUE, + FOREIGN KEY (c1) REFERENCES t1 (c1) ON UPDATE CASCADE +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES ('old', 'somevalu'), ('other', 'anyvalue'); +INSERT INTO t2 VALUES (10, 'old'), (20, 'other'); +-- error ER_FOREIGN_DUPLICATE_KEY +UPDATE t1 SET c1 = 'other' WHERE c1 = 'old'; +DROP TABLE t2,t1; + # # test for recursion depth limit # |