diff options
author | unknown <serg@serg.mylan> | 2004-07-20 00:53:24 +0200 |
---|---|---|
committer | unknown <serg@serg.mylan> | 2004-07-20 00:53:24 +0200 |
commit | eee5f15b92f71c74ce315932770a603e4deef477 (patch) | |
tree | b39cfbb54d66b05cd075839aa58dc3215c8d4146 /innobase/row/row0ins.c | |
parent | d57d78ac10980e28344f285bdbc986fa3ee3496e (diff) | |
parent | b940ae1012b00e74e2155c4e35ca7872bed278e3 (diff) | |
download | mariadb-git-eee5f15b92f71c74ce315932770a603e4deef477.tar.gz |
manual merged (blame me!)
Build-tools/Do-compile:
Auto merged
Docs/Makefile.am:
Auto merged
innobase/btr/btr0cur.c:
Auto merged
innobase/include/lock0lock.h:
Auto merged
innobase/include/row0mysql.h:
Auto merged
innobase/include/srv0srv.h:
Auto merged
innobase/include/sync0arr.h:
Auto merged
innobase/include/trx0trx.h:
Auto merged
innobase/lock/lock0lock.c:
Auto merged
innobase/srv/srv0srv.c:
Auto merged
innobase/srv/srv0start.c:
Auto merged
innobase/sync/sync0arr.c:
Auto merged
innobase/trx/trx0trx.c:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
mysql-test/r/innodb.result:
to be fixed after the merge
Diffstat (limited to 'innobase/row/row0ins.c')
-rw-r--r-- | innobase/row/row0ins.c | 81 |
1 files changed, 67 insertions, 14 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 7f1852c70f2..0da749212d2 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -370,6 +370,32 @@ row_ins_cascade_ancestor_updates_table( return(FALSE); } +/************************************************************************* +Returns the number of ancestor UPDATE or DELETE nodes of a +cascaded update/delete node. */ +static +ulint +row_ins_cascade_n_ancestors( +/*========================*/ + /* out: number of ancestors */ + que_node_t* node) /* in: node in a query graph */ +{ + que_node_t* parent; + ulint n_ancestors = 0; + + parent = que_node_get_parent(node); + + while (que_node_get_type(parent) == QUE_NODE_UPDATE) { + n_ancestors++; + + parent = que_node_get_parent(parent); + + ut_a(parent); + } + + return(n_ancestors); +} + /********************************************************************** Calculates the update vector node->cascade->update for a child table in a cascaded update. */ @@ -616,6 +642,34 @@ row_ins_foreign_report_add_err( } /************************************************************************* +Invalidate the query cache for the given table. */ +static +void +row_ins_invalidate_query_cache( +/*===========================*/ + que_thr_t* thr, /* in: query thread whose run_node + is an update node */ + const char* name) /* in: table name prefixed with + database name and a '/' character */ +{ + char* buf; + char* ptr; + ulint len = strlen(name) + 1; + + buf = mem_strdupl(name, len); + + ptr = strchr(buf, '/'); + ut_a(ptr); + *ptr = '\0'; + + /* We call a function in ha_innodb.cc */ +#ifndef UNIV_HOTBACKUP + innobase_invalidate_query_cache(thr_get_trx(thr), buf, len); +#endif + mem_free(buf); +} + +/************************************************************************* Perform referential actions or checks when a parent row is deleted or updated and the constraint had an ON DELETE or ON UPDATE condition which was not RESTRICT. */ @@ -650,26 +704,15 @@ row_ins_foreign_check_on_constraint( ulint n_to_update; ulint err; ulint i; - char* ptr; - char* table_name_buf; + + ut_a(thr && foreign && pcur && mtr); /* Since we are going to delete or update a row, we have to invalidate the MySQL query cache for table */ - table_name_buf = mem_strdup(table->name); - - ptr = strchr(table_name_buf, '/'); - ut_a(ptr); - *ptr = '\0'; - -#ifndef UNIV_HOTBACKUP - /* We call a function in ha_innodb.cc */ - innobase_invalidate_query_cache(thr_get_trx(thr), table_name_buf, - strlen(table->name) + 1); -#endif - mem_free(table_name_buf); + row_ins_invalidate_query_cache(thr, table->name); node = thr->run_node; @@ -757,6 +800,16 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } + if (row_ins_cascade_n_ancestors(cascade) >= 15) { + err = DB_ROW_IS_REFERENCED; + + row_ins_foreign_report_err( +(char*)"Trying a too deep cascaded delete or update\n", + thr, foreign, btr_pcur_get_rec(pcur), entry); + + goto nonstandard_exit_func; + } + index = btr_pcur_get_btr_cur(pcur)->index; ut_a(index == foreign->foreign_index); |