summaryrefslogtreecommitdiff
path: root/storage/innobase/row
diff options
context:
space:
mode:
authorGeorgi Kodinov <gkodinov@mysql.com>2010-10-27 09:32:26 +0200
committerGeorgi Kodinov <gkodinov@mysql.com>2010-10-27 09:32:26 +0200
commit50d18aa2d567854264c10e56eff6304075ef5cd4 (patch)
tree6bc185b8a2bbd71d9513f8fbd402ae0bda8a74f8 /storage/innobase/row
parente86b6c0db40116cb0dc223999e45712e1b1908ef (diff)
parent8a30cc4a79908452c5dabe50f93900c2eb873f66 (diff)
downloadmariadb-git-50d18aa2d567854264c10e56eff6304075ef5cd4.tar.gz
merge
Diffstat (limited to 'storage/innobase/row')
-rw-r--r--storage/innobase/row/row0merge.c2
-rw-r--r--storage/innobase/row/row0mysql.c30
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);