mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
MDEV-7672: Crash creating an InnoDB table with foreign keys
Analysis: after a red-black-tree lookup we use node withouth checking did lookup succeed or not. This lead to situation where NULL-pointer was used. Fix: Add additional check that found node from red-back-tree is valid.
This commit is contained in:
parent
e52a58a5cc
commit
6c19f51a5f
4 changed files with 96 additions and 12 deletions
|
@ -33,3 +33,35 @@ select * from fk_29;
|
|||
f1
|
||||
29
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
f1 int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk1 FOREIGN KEY (f1) REFERENCES t1 (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
f2 int(11) NOT NULL,
|
||||
f3 int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT fk2 FOREIGN KEY (f2) REFERENCES t1 (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1005 Can't create table 'test.t2' (errno: 150)
|
||||
CREATE TABLE t2 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
f2 int(11) NOT NULL,
|
||||
f3 int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT fk2 FOREIGN KEY (f2) REFERENCES t1 (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE;
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1005 Can't create table '#sql-temporary' (errno: 150)
|
||||
drop table t2;
|
||||
drop table t1;
|
||||
|
|
|
@ -84,3 +84,43 @@ while ($i)
|
|||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# MDEV-7672: Crash creating an InnoDB table with foreign keys
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
f1 int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk1 FOREIGN KEY (f1) REFERENCES t1 (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
--error 1005
|
||||
CREATE TABLE t2 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
f2 int(11) NOT NULL,
|
||||
f3 int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT fk2 FOREIGN KEY (f2) REFERENCES t1 (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
show warnings;
|
||||
|
||||
CREATE TABLE t2 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
f2 int(11) NOT NULL,
|
||||
f3 int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT fk2 FOREIGN KEY (f2) REFERENCES t1 (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
--replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE;
|
||||
|
||||
--replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
|
||||
drop table t2;
|
||||
drop table t1;
|
||||
|
|
|
@ -2533,10 +2533,13 @@ dict_foreign_remove_from_cache(
|
|||
if (rbt != NULL && foreign->id != NULL) {
|
||||
const ib_rbt_node_t* node
|
||||
= rbt_lookup(rbt, foreign->id);
|
||||
dict_foreign_t* val = *(dict_foreign_t**) node->value;
|
||||
|
||||
if (val == foreign) {
|
||||
rbt_delete(rbt, foreign->id);
|
||||
if (node) {
|
||||
dict_foreign_t* val = *(dict_foreign_t**) node->value;
|
||||
|
||||
if (val == foreign) {
|
||||
rbt_delete(rbt, foreign->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2552,10 +2555,13 @@ dict_foreign_remove_from_cache(
|
|||
if (rbt != NULL && foreign->id != NULL) {
|
||||
const ib_rbt_node_t* node
|
||||
= rbt_lookup(rbt, foreign->id);
|
||||
dict_foreign_t* val = *(dict_foreign_t**) node->value;
|
||||
if (node) {
|
||||
|
||||
if (val == foreign) {
|
||||
rbt_delete(rbt, foreign->id);
|
||||
dict_foreign_t* val = *(dict_foreign_t**) node->value;
|
||||
|
||||
if (val == foreign) {
|
||||
rbt_delete(rbt, foreign->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2666,10 +2666,13 @@ dict_foreign_remove_from_cache(
|
|||
if (rbt != NULL && foreign->id != NULL) {
|
||||
const ib_rbt_node_t* node
|
||||
= rbt_lookup(rbt, foreign->id);
|
||||
dict_foreign_t* val = *(dict_foreign_t**) node->value;
|
||||
|
||||
if (val == foreign) {
|
||||
rbt_delete(rbt, foreign->id);
|
||||
if (node) {
|
||||
dict_foreign_t* val = *(dict_foreign_t**) node->value;
|
||||
|
||||
if (val == foreign) {
|
||||
rbt_delete(rbt, foreign->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2685,10 +2688,13 @@ dict_foreign_remove_from_cache(
|
|||
if (rbt != NULL && foreign->id != NULL) {
|
||||
const ib_rbt_node_t* node
|
||||
= rbt_lookup(rbt, foreign->id);
|
||||
dict_foreign_t* val = *(dict_foreign_t**) node->value;
|
||||
|
||||
if (val == foreign) {
|
||||
rbt_delete(rbt, foreign->id);
|
||||
if (node) {
|
||||
dict_foreign_t* val = *(dict_foreign_t**) node->value;
|
||||
|
||||
if (val == foreign) {
|
||||
rbt_delete(rbt, foreign->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue