1
1
/*****************************************************************************
3
Copyright (C) 1996, 2010, Innobase Oy. All Rights Reserved.
3
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
429
426
byte* last_index_id;
430
427
const char* err_msg;
432
buf = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
429
buf = mem_heap_alloc(heap, 8);
434
last_index_id = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
431
last_index_id = mem_heap_alloc(heap, 8);
435
432
mach_write_to_8(last_index_id, last_id);
437
434
err_msg = dict_load_field_low(buf, NULL, sys_field,
1028
1025
tuple = dtuple_create(heap, 1);
1029
1026
dfield = dtuple_get_nth_field(tuple, 0);
1031
buf = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
1028
buf = mem_heap_alloc(heap, 8);
1032
1029
mach_write_to_8(buf, table->id);
1034
1031
dfield_set_data(dfield, buf, 8);
1212
1209
tuple = dtuple_create(heap, 1);
1213
1210
dfield = dtuple_get_nth_field(tuple, 0);
1215
buf = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
1212
buf = mem_heap_alloc(heap, 8);
1216
1213
mach_write_to_8(buf, index->id);
1218
1215
dfield_set_data(dfield, buf, 8);
1415
1412
tuple = dtuple_create(heap, 1);
1416
1413
dfield = dtuple_get_nth_field(tuple, 0);
1418
buf = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
1415
buf = mem_heap_alloc(heap, 8);
1419
1416
mach_write_to_8(buf, table->id);
1421
1418
dfield_set_data(dfield, buf, 8);
1803
1800
err = dict_load_indexes(table, heap);
1805
/* Initialize table foreign_child value. Its value could be
1806
changed when dict_load_foreigns() is called below */
1807
table->fk_max_recusive_level = 0;
1809
1802
/* If the force recovery flag is set, we open the table irrespective
1810
1803
of the error condition, since the user may want to dump data from the
1811
1804
clustered index. However we load the foreign key information only if
1812
1805
all indexes were loaded. */
1814
1807
} else if (err == DB_SUCCESS) {
1815
err = dict_load_foreigns(table->name, TRUE, TRUE);
1817
if (err != DB_SUCCESS) {
1818
dict_table_remove_from_cache(table);
1821
table->fk_max_recusive_level = 0;
1808
err = dict_load_foreigns(table->name, TRUE);
1823
1809
} else if (!srv_force_recovery) {
1824
1810
dict_table_remove_from_cache(table);
1905
1889
BTR_SEARCH_LEAF, &pcur, &mtr);
1906
1890
rec = btr_pcur_get_rec(&pcur);
1908
if (!btr_pcur_is_on_user_rec(&pcur)) {
1892
if (!btr_pcur_is_on_user_rec(&pcur)
1893
|| rec_get_deleted_flag(rec, 0)) {
1909
1894
/* Not found */
1913
/* Find the first record that is not delete marked */
1914
while (rec_get_deleted_flag(rec, 0)) {
1915
if (!btr_pcur_move_to_next_user_rec(&pcur, &mtr)) {
1918
rec = btr_pcur_get_rec(&pcur);
1896
btr_pcur_close(&pcur);
1898
mem_heap_free(heap);
1921
1903
/*---------------------------------------------------*/
1989
1976
ut_ad(mutex_own(&(dict_sys->mutex)));
1991
foreign->foreign_col_names = static_cast<const char **>(mem_heap_alloc(
1992
foreign->heap, foreign->n_fields * sizeof(void*)));
1978
foreign->foreign_col_names = mem_heap_alloc(
1979
foreign->heap, foreign->n_fields * sizeof(void*));
1994
foreign->referenced_col_names = static_cast<const char **>(mem_heap_alloc(
1995
foreign->heap, foreign->n_fields * sizeof(void*)));
1981
foreign->referenced_col_names = mem_heap_alloc(
1982
foreign->heap, foreign->n_fields * sizeof(void*));
1996
1983
mtr_start(&mtr);
1998
1985
sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS");
2046
2033
/*==============*/
2047
2034
const char* id, /*!< in: foreign constraint id as a
2048
2035
null-terminated string */
2049
ibool check_charsets,
2036
ibool check_charsets)
2050
2037
/*!< in: TRUE=check charset compatibility */
2051
ibool check_recursive)
2052
/*!< in: Whether to record the foreign table
2053
parent count to avoid unlimited recursive
2054
load of chained foreign tables */
2056
2039
dict_foreign_t* foreign;
2057
2040
dict_table_t* sys_foreign;
2152
2133
dict_load_foreign_cols(id, foreign);
2154
ref_table = dict_table_check_if_in_cache_low(
2155
foreign->referenced_table_name);
2157
/* We could possibly wind up in a deep recursive calls if
2158
we call dict_table_get_low() again here if there
2159
is a chain of tables concatenated together with
2160
foreign constraints. In such case, each table is
2161
both a parent and child of the other tables, and
2162
act as a "link" in such table chains.
2163
To avoid such scenario, we would need to check the
2164
number of ancesters the current table has. If that
2165
exceeds DICT_FK_MAX_CHAIN_LEN, we will stop loading
2167
Foreign constraints are loaded in a Breath First fashion,
2168
that is, the index on FOR_NAME is scanned first, and then
2169
index on REF_NAME. So foreign constrains in which
2170
current table is a child (foreign table) are loaded first,
2171
and then those constraints where current table is a
2172
parent (referenced) table.
2173
Thus we could check the parent (ref_table) table's
2174
reference count (fk_max_recusive_level) to know how deep the
2175
recursive call is. If the parent table (ref_table) is already
2176
loaded, and its fk_max_recusive_level is larger than
2177
DICT_FK_MAX_CHAIN_LEN, we will stop the recursive loading
2178
by skipping loading the child table. It will not affect foreign
2179
constraint check for DMLs since child table will be loaded
2180
at that time for the constraint check. */
2182
|| ref_table->fk_max_recusive_level < DICT_FK_MAX_RECURSIVE_LOAD) {
2184
/* If the foreign table is not yet in the dictionary cache, we
2185
have to load it so that we are able to make type comparisons
2186
in the next function call. */
2188
for_table = dict_table_get_low(foreign->foreign_table_name);
2190
if (for_table && ref_table && check_recursive) {
2191
/* This is to record the longest chain of ancesters
2192
this table has, if the parent has more ancesters
2193
than this table has, record it after add 1 (for this
2195
if (ref_table->fk_max_recusive_level
2196
>= for_table->fk_max_recusive_level) {
2197
for_table->fk_max_recusive_level =
2198
ref_table->fk_max_recusive_level + 1;
2135
/* If the foreign table is not yet in the dictionary cache, we
2136
have to load it so that we are able to make type comparisons
2137
in the next function call. */
2139
dict_table_get_low(foreign->foreign_table_name);
2203
2141
/* Note that there may already be a foreign constraint object in
2204
2142
the dictionary cache for this constraint: then the following