summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorAnnamalai Gurusami <annamalai.gurusami@oracle.com>2015-06-19 10:17:36 +0530
committerAnnamalai Gurusami <annamalai.gurusami@oracle.com>2015-06-19 10:17:52 +0530
commitdb2ed27e0ebe13fa70972b9993ff9bbd2f29499f (patch)
tree0c40a1c820eaeb8313a61900a036427be984ad5e /storage
parentdbbe747e54a320d810fff1896ed9e553d43a0bae (diff)
downloadmariadb-git-db2ed27e0ebe13fa70972b9993ff9bbd2f29499f.tar.gz
Bug #20762798 FK DDL: CRASH IN DICT_FOREIGN_REMOVE_FROM_CACHE
Problem: If we add a referential integrity constraint with a duplicate name, an error occurs. The foreign key object would not have been added to the dictionary cache. In the error path, there is an attempt to remove this foreign key object. Since this object is not there, the search returns a NULL result. De-referencing the null object results in this crash. Solution: If the search to the foreign key object failed, then don't attempt to access it. rb#9309 approved by Marko.
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/dict/dict0dict.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 56baceb7a4b..5aca95aec0d 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -2533,10 +2533,14 @@ 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 != NULL) {
+ dict_foreign_t* val
+ = *(dict_foreign_t**) node->value;
+
+ if (val == foreign) {
+ rbt_delete(rbt, foreign->id);
+ }
}
}
}
@@ -2552,10 +2556,14 @@ 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 != NULL) {
+ dict_foreign_t* val
+ = *(dict_foreign_t**) node->value;
+
+ if (val == foreign) {
+ rbt_delete(rbt, foreign->id);
+ }
}
}
}