summaryrefslogtreecommitdiff
path: root/innobase/row/row0upd.c
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-04-25 01:16:42 +0300
committerunknown <monty@hundin.mysql.fi>2002-04-25 01:16:42 +0300
commit0a03601fab2174e2a7590ff36d4ce2aee08adc5f (patch)
tree539e3f41736108728458d901c552313e5f058e8f /innobase/row/row0upd.c
parenta56d1215f52b8d6ed9428b358034f439e03cbf5b (diff)
parent64cc56125791c5e3773399b6d3a40be81510b460 (diff)
downloadmariadb-git-0a03601fab2174e2a7590ff36d4ce2aee08adc5f.tar.gz
merge
BitKeeper/etc/logging_ok: auto-union configure.in: Auto merged BitKeeper/deleted/.del-identity.result~e41453a364242503: Auto merged BitKeeper/deleted/.del-identity.test~326f469b59105404: Auto merged include/my_pthread.h: Auto merged innobase/dict/dict0crea.c: Auto merged innobase/dict/dict0dict.c: Auto merged innobase/dict/dict0load.c: Auto merged innobase/include/univ.i: Auto merged innobase/lock/lock0lock.c: Auto merged innobase/pars/pars0opt.c: Auto merged innobase/que/que0que.c: Auto merged innobase/row/row0ins.c: Auto merged innobase/row/row0mysql.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/row/row0upd.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/sync/sync0sync.c: Auto merged innobase/trx/trx0trx.c: Auto merged libmysql/libmysql.c: Auto merged myisam/myisampack.c: Auto merged mysql-test/t/func_test.test: Auto merged mysql-test/t/show_check.test: Auto merged mysql-test/t/variables.test: Auto merged mysys/my_pthread.c: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_func.cc: Auto merged sql/mysql_priv.h: Auto merged sql/share/danish/errmsg.txt: Auto merged sql/share/english/errmsg.txt: Auto merged sql/share/french/errmsg.txt: Auto merged sql/share/german/errmsg.txt: Auto merged sql/share/greek/errmsg.txt: Auto merged sql/share/hungarian/errmsg.txt: Auto merged sql/sql_show.cc: Auto merged sql/share/italian/errmsg.txt: Auto merged sql/share/japanese/errmsg.txt: Auto merged sql/share/korean/errmsg.txt: Auto merged sql/share/norwegian-ny/errmsg.txt: Auto merged sql/share/norwegian/errmsg.txt: Auto merged sql/share/polish/errmsg.txt: Auto merged sql/share/portuguese/errmsg.txt: Auto merged sql/share/romanian/errmsg.txt: Auto merged sql/share/russian/errmsg.txt: Auto merged sql/share/slovak/errmsg.txt: Auto merged sql/share/spanish/errmsg.txt: Auto merged sql/share/swedish/errmsg.txt: Auto merged sql/share/ukrainian/errmsg.txt: Auto merged
Diffstat (limited to 'innobase/row/row0upd.c')
-rw-r--r--innobase/row/row0upd.c109
1 files changed, 75 insertions, 34 deletions
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 710f650c0bd..1d5319a182b 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -73,8 +73,7 @@ steps of query graph execution. */
/*************************************************************************
Checks if index currently is mentioned as a referenced index in a foreign
-key constraint. This function also loads into the dictionary cache the
-possible referencing table. */
+key constraint. */
static
ibool
row_upd_index_is_referenced(
@@ -85,44 +84,28 @@ row_upd_index_is_referenced(
the referencing table has been dropped when
we leave this function: this function is only
for heuristic use! */
- dict_index_t* index) /* in: index */
+ dict_index_t* index, /* in: index */
+ trx_t* trx) /* in: transaction */
{
- dict_table_t* table = index->table;
+ dict_table_t* table = index->table;
dict_foreign_t* foreign;
- ulint phase = 1;
-try_again:
if (!UT_LIST_GET_FIRST(table->referenced_list)) {
return(FALSE);
}
- if (phase == 2) {
- mutex_enter(&(dict_sys->mutex));
+ if (!trx->has_dict_foreign_key_check_lock) {
+ rw_lock_s_lock(&dict_foreign_key_check_lock);
}
- rw_lock_s_lock(&dict_foreign_key_check_lock);
-
foreign = UT_LIST_GET_FIRST(table->referenced_list);
while (foreign) {
if (foreign->referenced_index == index) {
- if (foreign->foreign_table == NULL) {
- if (phase == 2) {
- dict_table_get_low(foreign->
- foreign_table_name);
- } else {
- phase = 2;
- rw_lock_s_unlock(
- &dict_foreign_key_check_lock);
- goto try_again;
- }
- }
-
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
- if (phase == 2) {
- mutex_exit(&(dict_sys->mutex));
+ if (!trx->has_dict_foreign_key_check_lock) {
+ rw_lock_s_unlock(&dict_foreign_key_check_lock);
}
return(TRUE);
@@ -131,10 +114,8 @@ try_again:
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
-
- if (phase == 2) {
- mutex_exit(&(dict_sys->mutex));
+ if (!trx->has_dict_foreign_key_check_lock) {
+ rw_lock_s_unlock(&dict_foreign_key_check_lock);
}
return(FALSE);
@@ -160,8 +141,17 @@ row_upd_check_references_constraints(
dict_foreign_t* foreign;
mem_heap_t* heap;
dtuple_t* entry;
+ trx_t* trx;
rec_t* rec;
ulint err;
+ ibool got_s_lock = FALSE;
+
+ if (UT_LIST_GET_FIRST(table->referenced_list) == NULL) {
+
+ return(DB_SUCCESS);
+ }
+
+ trx = thr_get_trx(thr);
rec = btr_pcur_get_rec(pcur);
@@ -173,17 +163,61 @@ row_upd_check_references_constraints(
mtr_start(mtr);
- rw_lock_s_lock(&dict_foreign_key_check_lock);
+ if (!trx->has_dict_foreign_key_check_lock) {
+ got_s_lock = TRUE;
+ rw_lock_s_lock(&dict_foreign_key_check_lock);
+
+ trx->has_dict_foreign_key_check_lock = TRUE;
+ }
+
foreign = UT_LIST_GET_FIRST(table->referenced_list);
while (foreign) {
if (foreign->referenced_index == index) {
+ if (foreign->foreign_table == NULL) {
+ dict_table_get(foreign->foreign_table_name,
+ trx);
+ }
+ if (foreign->foreign_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ (foreign->foreign_table
+ ->n_foreign_key_checks_running)++;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
+ /* NOTE that if the thread ends up waiting for a lock
+ we will release dict_foreign_key_check_lock
+ temporarily! But the counter on the table
+ protects 'foreign' from being dropped while the check
+ is running. */
+
err = row_ins_check_foreign_constraint(FALSE, foreign,
table, index, entry, thr);
+
+ if (foreign->foreign_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ ut_a(foreign->foreign_table
+ ->n_foreign_key_checks_running > 0);
+
+ (foreign->foreign_table
+ ->n_foreign_key_checks_running)--;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
if (err != DB_SUCCESS) {
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
+ if (got_s_lock) {
+ rw_lock_s_unlock(
+ &dict_foreign_key_check_lock);
+ trx->has_dict_foreign_key_check_lock
+ = FALSE;
+ }
+
mem_heap_free(heap);
return(err);
@@ -193,7 +227,11 @@ row_upd_check_references_constraints(
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
+ if (got_s_lock) {
+ rw_lock_s_unlock(&dict_foreign_key_check_lock);
+ trx->has_dict_foreign_key_check_lock = FALSE;
+ }
+
mem_heap_free(heap);
return(DB_SUCCESS);
@@ -222,6 +260,9 @@ upd_node_create(
node->index = NULL;
node->update = NULL;
+ node->cascade_heap = NULL;
+ node->cascade_node = NULL;
+
node->select = NULL;
node->heap = mem_heap_create(128);
@@ -1027,7 +1068,7 @@ row_upd_sec_index_entry(
index = node->index;
- check_ref = row_upd_index_is_referenced(index);
+ check_ref = row_upd_index_is_referenced(index, thr_get_trx(thr));
heap = mem_heap_create(1024);
@@ -1391,7 +1432,7 @@ row_upd_clust_step(
index = dict_table_get_first_index(node->table);
- check_ref = row_upd_index_is_referenced(index);
+ check_ref = row_upd_index_is_referenced(index, thr_get_trx(thr));
pcur = node->pcur;