diff options
author | Georgi Kodinov <gkodinov@mysql.com> | 2010-10-27 09:32:26 +0200 |
---|---|---|
committer | Georgi Kodinov <gkodinov@mysql.com> | 2010-10-27 09:32:26 +0200 |
commit | 50d18aa2d567854264c10e56eff6304075ef5cd4 (patch) | |
tree | 6bc185b8a2bbd71d9513f8fbd402ae0bda8a74f8 /storage/innobase/row | |
parent | e86b6c0db40116cb0dc223999e45712e1b1908ef (diff) | |
parent | 8a30cc4a79908452c5dabe50f93900c2eb873f66 (diff) | |
download | mariadb-git-50d18aa2d567854264c10e56eff6304075ef5cd4.tar.gz |
merge
Diffstat (limited to 'storage/innobase/row')
-rw-r--r-- | storage/innobase/row/row0merge.c | 2 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.c | 30 |
2 files changed, 29 insertions, 3 deletions
diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c index 38ec4bff08f..1b96ff50e66 100644 --- a/storage/innobase/row/row0merge.c +++ b/storage/innobase/row/row0merge.c @@ -2418,7 +2418,7 @@ row_merge_rename_tables( goto err_exit; } - err = dict_load_foreigns(old_name, TRUE); + err = dict_load_foreigns(old_name, FALSE, TRUE); if (err != DB_SUCCESS) { err_exit: diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 71ef587b141..f298b3224e0 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -635,6 +635,13 @@ handle_new_error: "InnoDB: " REFMAN "forcing-recovery.html" " for help.\n", stderr); break; + case DB_FOREIGN_EXCEED_MAX_CASCADE: + fprintf(stderr, "InnoDB: Cannot delete/update rows with" + " cascading foreign key constraints that exceed max" + " depth of %lu\n" + "Please drop excessive foreign constraints" + " and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD); + break; default: fprintf(stderr, "InnoDB: unknown error code %lu\n", (ulong) err); @@ -1440,11 +1447,15 @@ row_update_for_mysql( run_again: thr->run_node = node; thr->prev_node = node; + thr->fk_cascade_depth = 0; row_upd_step(thr); err = trx->error_state; + /* Reset fk_cascade_depth back to 0 */ + thr->fk_cascade_depth = 0; + if (err != DB_SUCCESS) { que_thr_stop_for_mysql(thr); @@ -1640,12 +1651,27 @@ row_update_cascade_for_mysql( trx_t* trx; trx = thr_get_trx(thr); + + /* Increment fk_cascade_depth to record the recursive call depth on + a single update/delete that affects multiple tables chained + together with foreign key relations. */ + thr->fk_cascade_depth++; + + if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) { + return (DB_FOREIGN_EXCEED_MAX_CASCADE); + } run_again: thr->run_node = node; thr->prev_node = node; row_upd_step(thr); + /* The recursive call for cascading update/delete happens + in above row_upd_step(), reset the counter once we come + out of the recursive call, so it does not accumulate for + different row deletes */ + thr->fk_cascade_depth = 0; + err = trx->error_state; /* Note that the cascade node is a subnode of another InnoDB @@ -2120,7 +2146,7 @@ row_table_add_foreign_constraints( name, reject_fks); if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ - err = dict_load_foreigns(name, TRUE); + err = dict_load_foreigns(name, FALSE, TRUE); } if (err != DB_SUCCESS) { @@ -3992,7 +4018,7 @@ end: an ALTER, not in a RENAME. */ err = dict_load_foreigns( - new_name, !old_is_tmp || trx->check_foreigns); + new_name, FALSE, !old_is_tmp || trx->check_foreigns); if (err != DB_SUCCESS) { ut_print_timestamp(stderr); |