summaryrefslogtreecommitdiff
path: root/storage/xtradb/row
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/row')
-rw-r--r--storage/xtradb/row/row0ins.cc26
-rw-r--r--storage/xtradb/row/row0mysql.cc152
-rw-r--r--storage/xtradb/row/row0upd.cc71
3 files changed, 128 insertions, 121 deletions
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index ecbf9425f43..c0396a96cfc 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1745,12 +1745,11 @@ do_possible_lock_wait:
table case (check_ref == 0), since MDL lock will prevent
concurrent DDL and DML on the same table */
if (!check_ref) {
- for (const dict_foreign_t* check_foreign
- = UT_LIST_GET_FIRST( table->referenced_list);
- check_foreign;
- check_foreign = UT_LIST_GET_NEXT(
- referenced_list, check_foreign)) {
- if (check_foreign == foreign) {
+ for (dict_foreign_set::iterator it
+ = table->referenced_set.begin();
+ it != table->referenced_set.end();
+ ++it) {
+ if (*it == foreign) {
verified = true;
break;
}
@@ -1803,12 +1802,15 @@ row_ins_check_foreign_constraints(
trx = thr_get_trx(thr);
- foreign = UT_LIST_GET_FIRST(table->foreign_list);
-
DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
"foreign_constraint_check_for_ins");
- while (foreign) {
+ for (dict_foreign_set::iterator it = table->foreign_set.begin();
+ it != table->foreign_set.end();
+ ++it) {
+
+ foreign = *it;
+
if (foreign->foreign_index == index) {
dict_table_t* ref_table = NULL;
dict_table_t* foreign_table = foreign->foreign_table;
@@ -1864,8 +1866,6 @@ row_ins_check_foreign_constraints(
return(err);
}
}
-
- foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
return(DB_SUCCESS);
@@ -2915,7 +2915,7 @@ row_ins_clust_index_entry(
dberr_t err;
ulint n_uniq;
- if (UT_LIST_GET_FIRST(index->table->foreign_list)) {
+ if (!index->table->foreign_set.empty()) {
err = row_ins_check_foreign_constraints(
index->table, index, entry, thr);
if (err != DB_SUCCESS) {
@@ -2973,7 +2973,7 @@ row_ins_sec_index_entry(
mem_heap_t* offsets_heap;
mem_heap_t* heap;
- if (UT_LIST_GET_FIRST(index->table->foreign_list)) {
+ if (!index->table->foreign_set.empty()) {
err = row_ins_check_foreign_constraints(index->table, index,
entry, thr);
if (err != DB_SUCCESS) {
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 671714c5b3d..ebf991e6ff8 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2014, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -62,6 +62,7 @@ Created 9/17/2000 Heikki Tuuri
#include "m_string.h"
#include "my_sys.h"
#include "ha_prototypes.h"
+#include <algorithm>
/** Provide optional 4.x backwards compatibility for 5.0 and above */
UNIV_INTERN ibool row_rollback_on_timeout = FALSE;
@@ -1576,8 +1577,6 @@ init_fts_doc_id_for_ref(
{
dict_foreign_t* foreign;
- foreign = UT_LIST_GET_FIRST(table->referenced_list);
-
table->fk_max_recusive_level = 0;
(*depth)++;
@@ -1589,17 +1588,25 @@ init_fts_doc_id_for_ref(
/* Loop through this table's referenced list and also
recursively traverse each table's foreign table list */
- while (foreign && foreign->foreign_table) {
- if (foreign->foreign_table->fts) {
- fts_init_doc_id(foreign->foreign_table);
+ for (dict_foreign_set::iterator it = table->referenced_set.begin();
+ it != table->referenced_set.end();
+ ++it) {
+
+ foreign = *it;
+
+ if (foreign->foreign_table == NULL) {
+ break;
}
- if (UT_LIST_GET_LEN(foreign->foreign_table->referenced_list)
- > 0 && foreign->foreign_table != table) {
- init_fts_doc_id_for_ref(foreign->foreign_table, depth);
+ if (foreign->foreign_table->fts != NULL) {
+ fts_init_doc_id(foreign->foreign_table);
}
- foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
+ if (!foreign->foreign_table->referenced_set.empty()
+ && foreign->foreign_table != table) {
+ init_fts_doc_id_for_ref(
+ foreign->foreign_table, depth);
+ }
}
}
@@ -2839,43 +2846,47 @@ row_discard_tablespace_foreign_key_checks(
const trx_t* trx, /*!< in: transaction handle */
const dict_table_t* table) /*!< in: table to be discarded */
{
- const dict_foreign_t* foreign;
+
+ if (srv_read_only_mode || !trx->check_foreigns) {
+ return(DB_SUCCESS);
+ }
/* Check if the table is referenced by foreign key constraints from
some other table (not the table itself) */
+ dict_foreign_set::iterator it
+ = std::find_if(table->referenced_set.begin(),
+ table->referenced_set.end(),
+ dict_foreign_different_tables());
- for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
- foreign && foreign->foreign_table == table;
- foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
-
+ if (it == table->referenced_set.end()) {
+ return(DB_SUCCESS);
}
- if (!srv_read_only_mode && foreign && trx->check_foreigns) {
+ const dict_foreign_t* foreign = *it;
+ FILE* ef = dict_foreign_err_file;
- FILE* ef = dict_foreign_err_file;
+ ut_ad(foreign->foreign_table != table);
+ ut_ad(foreign->referenced_table == table);
- /* We only allow discarding a referenced table if
- FOREIGN_KEY_CHECKS is set to 0 */
+ /* We only allow discarding a referenced table if
+ FOREIGN_KEY_CHECKS is set to 0 */
- mutex_enter(&dict_foreign_err_mutex);
+ mutex_enter(&dict_foreign_err_mutex);
- rewind(ef);
+ rewind(ef);
- ut_print_timestamp(ef);
+ ut_print_timestamp(ef);
- fputs(" Cannot DISCARD table ", ef);
- ut_print_name(stderr, trx, TRUE, table->name);
- fputs("\n"
- "because it is referenced by ", ef);
- ut_print_name(stderr, trx, TRUE, foreign->foreign_table_name);
- putc('\n', ef);
+ fputs(" Cannot DISCARD table ", ef);
+ ut_print_name(stderr, trx, TRUE, table->name);
+ fputs("\n"
+ "because it is referenced by ", ef);
+ ut_print_name(stderr, trx, TRUE, foreign->foreign_table_name);
+ putc('\n', ef);
- mutex_exit(&dict_foreign_err_mutex);
-
- return(DB_CANNOT_DROP_CONSTRAINT);
- }
+ mutex_exit(&dict_foreign_err_mutex);
- return(DB_SUCCESS);
+ return(DB_CANNOT_DROP_CONSTRAINT);
}
/*********************************************************************//**
@@ -3178,7 +3189,6 @@ row_truncate_table_for_mysql(
dict_table_t* table, /*!< in: table handle */
trx_t* trx) /*!< in: transaction handle */
{
- dict_foreign_t* foreign;
dberr_t err;
mem_heap_t* heap;
byte* buf;
@@ -3270,18 +3280,17 @@ row_truncate_table_for_mysql(
/* Check if the table is referenced by foreign key constraints from
some other table (not the table itself) */
- for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
- foreign != 0 && foreign->foreign_table == table;
- foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
-
- /* Do nothing. */
- }
+ dict_foreign_set::iterator it
+ = std::find_if(table->referenced_set.begin(),
+ table->referenced_set.end(),
+ dict_foreign_different_tables());
if (!srv_read_only_mode
- && foreign
+ && it != table->referenced_set.end()
&& trx->check_foreigns) {
- FILE* ef = dict_foreign_err_file;
+ FILE* ef = dict_foreign_err_file;
+ dict_foreign_t* foreign = *it;
/* We only allow truncating a referenced table if
FOREIGN_KEY_CHECKS is set to 0 */
@@ -3882,42 +3891,45 @@ row_drop_table_for_mysql(
/* Check if the table is referenced by foreign key constraints from
some other table (not the table itself) */
- foreign = UT_LIST_GET_FIRST(table->referenced_list);
+ if (!srv_read_only_mode && trx->check_foreigns) {
- while (foreign && foreign->foreign_table == table) {
-check_next_foreign:
- foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
- }
+ for (dict_foreign_set::iterator it
+ = table->referenced_set.begin();
+ it != table->referenced_set.end();
+ ++it) {
- if (!srv_read_only_mode
- && foreign
- && trx->check_foreigns
- && !(drop_db && dict_tables_have_same_db(
- name, foreign->foreign_table_name_lookup))) {
- FILE* ef = dict_foreign_err_file;
+ foreign = *it;
- /* We only allow dropping a referenced table if
- FOREIGN_KEY_CHECKS is set to 0 */
+ const bool ref_ok = drop_db
+ && dict_tables_have_same_db(
+ name,
+ foreign->foreign_table_name_lookup);
- err = DB_CANNOT_DROP_CONSTRAINT;
+ if (foreign->foreign_table != table && !ref_ok) {
- mutex_enter(&dict_foreign_err_mutex);
- rewind(ef);
- ut_print_timestamp(ef);
+ FILE* ef = dict_foreign_err_file;
- fputs(" Cannot drop table ", ef);
- ut_print_name(ef, trx, TRUE, name);
- fputs("\n"
- "because it is referenced by ", ef);
- ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
- putc('\n', ef);
- mutex_exit(&dict_foreign_err_mutex);
+ /* We only allow dropping a referenced table
+ if FOREIGN_KEY_CHECKS is set to 0 */
- goto funct_exit;
- }
+ err = DB_CANNOT_DROP_CONSTRAINT;
+
+ mutex_enter(&dict_foreign_err_mutex);
+ rewind(ef);
+ ut_print_timestamp(ef);
- if (foreign && trx->check_foreigns) {
- goto check_next_foreign;
+ fputs(" Cannot drop table ", ef);
+ ut_print_name(ef, trx, TRUE, name);
+ fputs("\n"
+ "because it is referenced by ", ef);
+ ut_print_name(ef, trx, TRUE,
+ foreign->foreign_table_name);
+ putc('\n', ef);
+ mutex_exit(&dict_foreign_err_mutex);
+
+ goto funct_exit;
+ }
+ }
}
/* TODO: could we replace the counter n_foreign_key_checks_running
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index bdd2a691368..53da8fea77e 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -53,11 +53,12 @@ Created 12/27/1996 Heikki Tuuri
#include "pars0sym.h"
#include "eval0eval.h"
#include "buf0lru.h"
+#include <algorithm>
+
#ifdef WITH_WSREP
extern my_bool wsrep_debug;
#endif
-
/* What kind of latch and lock can we assume when the control comes to
-------------------------------------------------------------------
an update node?
@@ -141,12 +142,10 @@ row_upd_index_is_referenced(
trx_t* trx) /*!< in: transaction */
{
dict_table_t* table = index->table;
- dict_foreign_t* foreign;
ibool froze_data_dict = FALSE;
ibool is_referenced = FALSE;
- if (!UT_LIST_GET_FIRST(table->referenced_list)) {
-
+ if (table->referenced_set.empty()) {
return(FALSE);
}
@@ -155,19 +154,13 @@ row_upd_index_is_referenced(
froze_data_dict = TRUE;
}
- foreign = UT_LIST_GET_FIRST(table->referenced_list);
+ dict_foreign_set::iterator it
+ = std::find_if(table->referenced_set.begin(),
+ table->referenced_set.end(),
+ dict_foreign_with_index(index));
- while (foreign) {
- if (foreign->referenced_index == index) {
+ is_referenced = (it != table->referenced_set.end());
- is_referenced = TRUE;
- goto func_exit;
- }
-
- foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
- }
-
-func_exit:
if (froze_data_dict) {
row_mysql_unfreeze_data_dictionary(trx);
}
@@ -188,8 +181,7 @@ wsrep_row_upd_index_is_foreign(
ibool froze_data_dict = FALSE;
ibool is_referenced = FALSE;
- if (!UT_LIST_GET_FIRST(table->foreign_list)) {
-
+ if (table->foreign_set.empty()) {
return(FALSE);
}
@@ -198,17 +190,18 @@ wsrep_row_upd_index_is_foreign(
froze_data_dict = TRUE;
}
- foreign = UT_LIST_GET_FIRST(table->foreign_list);
+ for (dict_foreign_set::iterator it= table->foreign_set.begin();
+ it != table->foreign_set.end();
+ ++ it)
+ {
+ foreign= *it;
- while (foreign) {
- if (foreign->foreign_index == index) {
-
- is_referenced = TRUE;
- goto func_exit;
- }
-
- foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
- }
+ if (foreign->foreign_index == index)
+ {
+ is_referenced= TRUE;
+ goto func_exit;
+ }
+ }
func_exit:
if (froze_data_dict) {
@@ -249,7 +242,7 @@ row_upd_check_references_constraints(
dberr_t err;
ibool got_s_lock = FALSE;
- if (UT_LIST_GET_FIRST(table->referenced_list) == NULL) {
+ if (table->referenced_set.empty()) {
return(DB_SUCCESS);
}
@@ -276,9 +269,13 @@ row_upd_check_references_constraints(
}
run_again:
- foreign = UT_LIST_GET_FIRST(table->referenced_list);
- while (foreign) {
+ for (dict_foreign_set::iterator it = table->referenced_set.begin();
+ it != table->referenced_set.end();
+ ++it) {
+
+ foreign = *it;
+
/* Note that we may have an update which updates the index
record, but does NOT update the first fields which are
referenced in a foreign key constraint. Then the update does
@@ -331,8 +328,6 @@ run_again:
goto func_exit;
}
}
-
- foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
err = DB_SUCCESS;
@@ -369,8 +364,7 @@ wsrep_row_upd_check_foreign_constraints(
ibool got_s_lock = FALSE;
ibool opened = FALSE;
- if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) {
-
+ if (table->foreign_set.empty()) {
return(DB_SUCCESS);
}
@@ -396,9 +390,12 @@ wsrep_row_upd_check_foreign_constraints(
row_mysql_freeze_data_dictionary(trx);
}
- foreign = UT_LIST_GET_FIRST(table->foreign_list);
+ for (dict_foreign_set::iterator it= table->foreign_set.begin();
+ it != table->foreign_set.end();
+ ++ it)
+ {
+ foreign= *it;
- while (foreign) {
/* Note that we may have an update which updates the index
record, but does NOT update the first fields which are
referenced in a foreign key constraint. Then the update does
@@ -448,8 +445,6 @@ wsrep_row_upd_check_foreign_constraints(
goto func_exit;
}
}
-
- foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
err = DB_SUCCESS;