#include "dict0dict.h"#include "buf0buf.h"#include "data0type.h"#include "mach0data.h"#include "dict0boot.h"#include "dict0mem.h"#include "dict0crea.h"#include "trx0undo.h"#include "btr0btr.h"#include "btr0cur.h"#include "btr0sea.h"#include "pars0pars.h"#include "pars0sym.h"#include "que0que.h"#include "rem0cmp.h"#include "m_ctype.h"Include dependency graph for dict0dict.c:

Go to the source code of this file.
| #define DICT_HEAP_SIZE 100 |
Definition at line 47 of file dict0dict.c.
Referenced by dict_mem_index_create(), and dict_mem_table_create().
| #define DICT_POOL_PER_COL_HASH 128 |
| #define DICT_POOL_PER_TABLE_HASH 512 |
| #define DICT_POOL_PER_VARYING 4 |
Definition at line 53 of file dict0dict.c.
| static const char* dict_accept | ( | struct charset_info_st * | cs, | |
| const char * | ptr, | |||
| const char * | string, | |||
| ibool * | success | |||
| ) | [static] |
Definition at line 2382 of file dict0dict.c.
References dict_scan_to(), FALSE, my_isspace, TRUE, and ut_strlen().
Referenced by dict_create_foreign_constraints_low(), dict_foreign_parse_drop_constraints(), and dict_str_starts_with_keyword().
02384 : if string was accepted, the pointer 02385 is moved after that, else ptr is returned */ 02386 struct charset_info_st* cs,/* in: the character set of ptr */ 02387 const char* ptr, /* in: scan from this */ 02388 const char* string, /* in: accept only this string as the next 02389 non-whitespace string */ 02390 ibool* success)/* out: TRUE if accepted */ 02391 { 02392 const char* old_ptr = ptr; 02393 const char* old_ptr2; 02394 02395 *success = FALSE; 02396 02397 while (my_isspace(cs, *ptr)) { 02398 ptr++; 02399 } 02400 02401 old_ptr2 = ptr; 02402 02403 ptr = dict_scan_to(ptr, string); 02404 02405 if (*ptr == '\0' || old_ptr2 != ptr) { 02406 return(old_ptr); 02407 } 02408 02409 *success = TRUE; 02410 02411 return(ptr + ut_strlen(string)); 02412 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_casedn_str | ( | char * | a | ) |
Definition at line 257 of file dict0dict.c.
References innobase_casedn_str().
Referenced by fil_load_single_table_tablespace().
00259 : string to put in lower case */ 00260 { 00261 innobase_casedn_str(a); 00262 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_col_add_to_cache | ( | dict_table_t * | table, | |
| dict_col_t * | col | |||
| ) | [static] |
Definition at line 1330 of file dict0dict.c.
References dict_sys_struct::col_hash, dict_sys, DICT_TABLE_MAGIC_N, hash(), HASH_INSERT, HASH_SEARCH, dict_table_struct::magic_n, dict_sys_struct::mutex, dict_col_struct::name, dict_table_struct::name, NULL, dict_col_struct::table, ut_a, ut_ad, ut_fold_string(), ut_fold_ulint_pair(), and ut_strcmp().
Referenced by dict_table_add_to_cache().
01332 : table */ 01333 dict_col_t* col) /* in: column */ 01334 { 01335 ulint fold; 01336 01337 ut_ad(table && col); 01338 #ifdef UNIV_SYNC_DEBUG 01339 ut_ad(mutex_own(&(dict_sys->mutex))); 01340 #endif /* UNIV_SYNC_DEBUG */ 01341 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01342 01343 fold = ut_fold_ulint_pair(ut_fold_string(table->name), 01344 ut_fold_string(col->name)); 01345 01346 /* Look for a column with same table name and column name: error */ 01347 { 01348 dict_col_t* col2; 01349 HASH_SEARCH(hash, dict_sys->col_hash, fold, col2, 01350 (ut_strcmp(col->name, col2->name) == 0) 01351 && (ut_strcmp((col2->table)->name, table->name) 01352 == 0)); 01353 ut_a(col2 == NULL); 01354 } 01355 01356 HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col); 01357 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool dict_col_name_is_reserved | ( | const char * | name | ) |
Definition at line 1417 of file dict0dict.c.
References FALSE, reserved_names, strcmp(), and TRUE.
Referenced by row_create_table_for_mysql().
01419 : TRUE if name is reserved */ 01420 const char* name) /* in: column name */ 01421 { 01422 /* This check reminds that if a new system column is added to 01423 the program, it should be dealt with here. */ 01424 #if DATA_N_SYS_COLS != 4 01425 #error "DATA_N_SYS_COLS != 4" 01426 #endif 01427 01428 static const char* reserved_names[] = { 01429 "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID" 01430 }; 01431 01432 ulint i; 01433 01434 for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) { 01435 if (strcmp(name, reserved_names[i]) == 0) { 01436 01437 return(TRUE); 01438 } 01439 } 01440 01441 return(FALSE); 01442 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_col_print_low | ( | dict_col_t * | col | ) | [static] |
Definition at line 4157 of file dict0dict.c.
References dict_col_get_type(), dict_sys, dtype_print(), dict_sys_struct::mutex, dict_col_struct::name, and ut_ad.
Referenced by dict_table_print_low().
04159 : column */ 04160 { 04161 dtype_t* type; 04162 04163 #ifdef UNIV_SYNC_DEBUG 04164 ut_ad(mutex_own(&(dict_sys->mutex))); 04165 #endif /* UNIV_SYNC_DEBUG */ 04166 04167 type = dict_col_get_type(col); 04168 fprintf(stderr, "%s: ", col->name); 04169 04170 dtype_print(type); 04171 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_col_remove_from_cache | ( | dict_table_t * | table, | |
| dict_col_t * | col | |||
| ) | [static] |
Definition at line 1363 of file dict0dict.c.
References dict_sys_struct::col_hash, dict_sys, DICT_TABLE_MAGIC_N, hash(), HASH_DELETE, dict_table_struct::magic_n, dict_sys_struct::mutex, dict_col_struct::name, dict_table_struct::name, ut_ad, ut_fold_string(), and ut_fold_ulint_pair().
Referenced by dict_table_remove_from_cache().
01365 : table */ 01366 dict_col_t* col) /* in: column */ 01367 { 01368 ulint fold; 01369 01370 ut_ad(table && col); 01371 #ifdef UNIV_SYNC_DEBUG 01372 ut_ad(mutex_own(&(dict_sys->mutex))); 01373 #endif /* UNIV_SYNC_DEBUG */ 01374 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01375 01376 fold = ut_fold_ulint_pair(ut_fold_string(table->name), 01377 ut_fold_string(col->name)); 01378 01379 HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col); 01380 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_col_reposition_in_cache | ( | dict_table_t * | table, | |
| dict_col_t * | col, | |||
| const char * | new_name | |||
| ) | [static] |
Definition at line 1387 of file dict0dict.c.
References dict_sys_struct::col_hash, dict_sys, DICT_TABLE_MAGIC_N, hash(), HASH_DELETE, HASH_INSERT, dict_table_struct::magic_n, dict_sys_struct::mutex, dict_col_struct::name, dict_table_struct::name, ut_ad, ut_fold_string(), and ut_fold_ulint_pair().
Referenced by dict_table_rename_in_cache().
01389 : table */ 01390 dict_col_t* col, /* in: column */ 01391 const char* new_name) /* in: new table name */ 01392 { 01393 ulint fold; 01394 01395 ut_ad(table && col); 01396 #ifdef UNIV_SYNC_DEBUG 01397 ut_ad(mutex_own(&(dict_sys->mutex))); 01398 #endif /* UNIV_SYNC_DEBUG */ 01399 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01400 01401 fold = ut_fold_ulint_pair(ut_fold_string(table->name), 01402 ut_fold_string(col->name)); 01403 01404 HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col); 01405 01406 fold = ut_fold_ulint_pair(ut_fold_string(new_name), 01407 ut_fold_string(col->name)); 01408 01409 HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col); 01410 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_create_foreign_constraints | ( | trx_t * | trx, | |
| const char * | sql_string, | |||
| const char * | name, | |||
| ibool | reject_fks | |||
| ) |
Definition at line 3455 of file dict0dict.c.
References dict_create_foreign_constraints_low(), dict_strip_comments(), err, innobase_get_charset(), mem_free, mem_heap_create, mem_heap_free, trx_struct::mysql_thd, and ut_a.
Referenced by row_table_add_foreign_constraints().
03457 : error code or DB_SUCCESS */ 03458 trx_t* trx, /* in: transaction */ 03459 const char* sql_string, /* in: table create statement where 03460 foreign keys are declared like: 03461 FOREIGN KEY (a, b) REFERENCES 03462 table2(c, d), table2 can be written 03463 also with the database 03464 name before it: test.table2; the 03465 default database id the database of 03466 parameter name */ 03467 const char* name, /* in: table full name in the 03468 normalized form 03469 database_name/table_name */ 03470 ibool reject_fks) /* in: if TRUE, fail with error 03471 code DB_CANNOT_ADD_CONSTRAINT if 03472 any foreign keys are found. */ 03473 { 03474 char* str; 03475 ulint err; 03476 mem_heap_t* heap; 03477 03478 ut_a(trx && trx->mysql_thd); 03479 03480 str = dict_strip_comments(sql_string); 03481 heap = mem_heap_create(10000); 03482 03483 err = dict_create_foreign_constraints_low(trx, heap, 03484 innobase_get_charset(trx->mysql_thd), 03485 str, name, reject_fks); 03486 03487 mem_heap_free(heap); 03488 mem_free(str); 03489 03490 return(err); 03491 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ulint dict_create_foreign_constraints_low | ( | trx_t * | trx, | |
| mem_heap_t * | heap, | |||
| struct charset_info_st * | cs, | |||
| const char * | sql_string, | |||
| const char * | name, | |||
| ibool | reject_fks | |||
| ) | [static] |
Definition at line 2873 of file dict0dict.c.
References trx_struct::check_foreigns, column_names, DATA_NOT_NULL, DB_CANNOT_ADD_CONSTRAINT, DB_ERROR, dict_accept(), dict_create_add_foreigns_to_dictionary(), dict_foreign_err_file, dict_foreign_err_mutex, dict_foreign_error_report_low(), dict_foreign_find_index(), dict_foreign_free(), DICT_FOREIGN_ON_DELETE_CASCADE, DICT_FOREIGN_ON_DELETE_NO_ACTION, DICT_FOREIGN_ON_UPDATE_CASCADE, DICT_FOREIGN_ON_UPDATE_NO_ACTION, dict_foreign_report_syntax_err(), dict_get_db_name_len(), dict_index_get_nth_type(), dict_mem_foreign_create(), dict_scan_col(), dict_scan_id(), dict_scan_table_name(), dict_scan_to(), dict_skip_word(), dict_sys, dict_table_get_highest_foreign_id(), dict_table_get_low(), error, FALSE, dict_foreign_struct::foreign_col_names, dict_foreign_struct::foreign_index, dict_table_struct::foreign_list, dict_foreign_struct::foreign_table, dict_foreign_struct::foreign_table_name, dict_foreign_struct::heap, dict_foreign_struct::id, index(), mem_heap_alloc(), mem_heap_strdup(), dict_sys_struct::mutex, mutex_enter, mutex_exit(), my_isspace, dict_foreign_struct::n_fields, dict_col_struct::name, dict_table_struct::name, NULL, dtype_struct::prtype, strlen(), TRUE, dict_foreign_struct::type, ut_a, ut_ad, UT_LIST_GET_LEN, ut_memcpy(), and ut_print_name().
Referenced by dict_create_foreign_constraints().
02875 : error code or DB_SUCCESS */ 02876 trx_t* trx, /* in: transaction */ 02877 mem_heap_t* heap, /* in: memory heap */ 02878 struct charset_info_st* cs,/* in: the character set of sql_string */ 02879 const char* sql_string, 02880 /* in: CREATE TABLE or ALTER TABLE statement 02881 where foreign keys are declared like: 02882 FOREIGN KEY (a, b) REFERENCES table2(c, d), 02883 table2 can be written also with the database 02884 name before it: test.table2; the default 02885 database is the database of parameter name */ 02886 const char* name, /* in: table full name in the normalized form 02887 database_name/table_name */ 02888 ibool reject_fks) 02889 /* in: if TRUE, fail with error code 02890 DB_CANNOT_ADD_CONSTRAINT if any foreign 02891 keys are found. */ 02892 { 02893 dict_table_t* table; 02894 dict_table_t* referenced_table; 02895 dict_table_t* table_to_alter; 02896 ulint highest_id_so_far = 0; 02897 dict_index_t* index; 02898 dict_foreign_t* foreign; 02899 const char* ptr = sql_string; 02900 const char* start_of_latest_foreign = sql_string; 02901 FILE* ef = dict_foreign_err_file; 02902 const char* constraint_name; 02903 ibool success; 02904 ulint error; 02905 const char* ptr1; 02906 const char* ptr2; 02907 ulint i; 02908 ulint j; 02909 ibool is_on_delete; 02910 ulint n_on_deletes; 02911 ulint n_on_updates; 02912 dict_col_t* columns[500]; 02913 const char* column_names[500]; 02914 const char* referenced_table_name; 02915 02916 #ifdef UNIV_SYNC_DEBUG 02917 ut_ad(mutex_own(&(dict_sys->mutex))); 02918 #endif /* UNIV_SYNC_DEBUG */ 02919 02920 table = dict_table_get_low(name); 02921 02922 if (table == NULL) { 02923 mutex_enter(&dict_foreign_err_mutex); 02924 dict_foreign_error_report_low(ef, name); 02925 fprintf(ef, 02926 "Cannot find the table in the internal data dictionary of InnoDB.\n" 02927 "Create table statement:\n%s\n", sql_string); 02928 mutex_exit(&dict_foreign_err_mutex); 02929 02930 return(DB_ERROR); 02931 } 02932 02933 /* First check if we are actually doing an ALTER TABLE, and in that 02934 case look for the table being altered */ 02935 02936 ptr = dict_accept(cs, ptr, "ALTER", &success); 02937 02938 if (!success) { 02939 02940 goto loop; 02941 } 02942 02943 ptr = dict_accept(cs, ptr, "TABLE", &success); 02944 02945 if (!success) { 02946 02947 goto loop; 02948 } 02949 02950 /* We are doing an ALTER TABLE: scan the table name we are altering */ 02951 02952 ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name, 02953 &success, heap, &referenced_table_name); 02954 if (!success) { 02955 fprintf(stderr, 02956 "InnoDB: Error: could not find the table being ALTERED in:\n%s\n", sql_string); 02957 02958 return(DB_ERROR); 02959 } 02960 02961 /* Starting from 4.0.18 and 4.1.2, we generate foreign key id's in the 02962 format databasename/tablename_ibfk_<number>, where <number> is local 02963 to the table; look for the highest <number> for table_to_alter, so 02964 that we can assign to new constraints higher numbers. */ 02965 02966 /* If we are altering a temporary table, the table name after ALTER 02967 TABLE does not correspond to the internal table name, and 02968 table_to_alter is NULL. TODO: should we fix this somehow? */ 02969 02970 if (table_to_alter == NULL) { 02971 highest_id_so_far = 0; 02972 } else { 02973 highest_id_so_far = dict_table_get_highest_foreign_id( 02974 table_to_alter); 02975 } 02976 02977 /* Scan for foreign key declarations in a loop */ 02978 loop: 02979 /* Scan either to "CONSTRAINT" or "FOREIGN", whichever is closer */ 02980 02981 ptr1 = dict_scan_to(ptr, "CONSTRAINT"); 02982 ptr2 = dict_scan_to(ptr, "FOREIGN"); 02983 02984 constraint_name = NULL; 02985 02986 if (ptr1 < ptr2) { 02987 /* The user may have specified a constraint name. Pick it so 02988 that we can store 'databasename/constraintname' as the id of 02989 of the constraint to system tables. */ 02990 ptr = ptr1; 02991 02992 ptr = dict_accept(cs, ptr, "CONSTRAINT", &success); 02993 02994 ut_a(success); 02995 02996 if (!my_isspace(cs, *ptr) && *ptr != '"' && *ptr != '`') { 02997 goto loop; 02998 } 02999 03000 while (my_isspace(cs, *ptr)) { 03001 ptr++; 03002 } 03003 03004 /* read constraint name unless got "CONSTRAINT FOREIGN" */ 03005 if (ptr != ptr2) { 03006 ptr = dict_scan_id(cs, ptr, heap, 03007 &constraint_name, FALSE, FALSE); 03008 } 03009 } else { 03010 ptr = ptr2; 03011 } 03012 03013 if (*ptr == '\0') { 03014 /* The proper way to reject foreign keys for temporary 03015 tables would be to split the lexing and syntactical 03016 analysis of foreign key clauses from the actual adding 03017 of them, so that ha_innodb.cc could first parse the SQL 03018 command, determine if there are any foreign keys, and 03019 if so, immediately reject the command if the table is a 03020 temporary one. For now, this kludge will work. */ 03021 if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0)) { 03022 03023 return(DB_CANNOT_ADD_CONSTRAINT); 03024 } 03025 03026 /**********************************************************/ 03027 /* The following call adds the foreign key constraints 03028 to the data dictionary system tables on disk */ 03029 03030 error = dict_create_add_foreigns_to_dictionary( 03031 highest_id_so_far, table, trx); 03032 return(error); 03033 } 03034 03035 start_of_latest_foreign = ptr; 03036 03037 ptr = dict_accept(cs, ptr, "FOREIGN", &success); 03038 03039 if (!success) { 03040 goto loop; 03041 } 03042 03043 if (!my_isspace(cs, *ptr)) { 03044 goto loop; 03045 } 03046 03047 ptr = dict_accept(cs, ptr, "KEY", &success); 03048 03049 if (!success) { 03050 goto loop; 03051 } 03052 03053 ptr = dict_accept(cs, ptr, "(", &success); 03054 03055 if (!success) { 03056 /* MySQL allows also an index id before the '('; we 03057 skip it */ 03058 ptr = dict_skip_word(cs, ptr, &success); 03059 03060 if (!success) { 03061 dict_foreign_report_syntax_err(name, 03062 start_of_latest_foreign, ptr); 03063 03064 return(DB_CANNOT_ADD_CONSTRAINT); 03065 } 03066 03067 ptr = dict_accept(cs, ptr, "(", &success); 03068 03069 if (!success) { 03070 /* We do not flag a syntax error here because in an 03071 ALTER TABLE we may also have DROP FOREIGN KEY abc */ 03072 03073 goto loop; 03074 } 03075 } 03076 03077 i = 0; 03078 03079 /* Scan the columns in the first list */ 03080 col_loop1: 03081 ut_a(i < (sizeof column_names) / sizeof *column_names); 03082 ptr = dict_scan_col(cs, ptr, &success, table, columns + i, 03083 heap, column_names + i); 03084 if (!success) { 03085 mutex_enter(&dict_foreign_err_mutex); 03086 dict_foreign_error_report_low(ef, name); 03087 fprintf(ef, "%s:\nCannot resolve column name close to:\n%s\n", 03088 start_of_latest_foreign, ptr); 03089 mutex_exit(&dict_foreign_err_mutex); 03090 03091 return(DB_CANNOT_ADD_CONSTRAINT); 03092 } 03093 03094 i++; 03095 03096 ptr = dict_accept(cs, ptr, ",", &success); 03097 03098 if (success) { 03099 goto col_loop1; 03100 } 03101 03102 ptr = dict_accept(cs, ptr, ")", &success); 03103 03104 if (!success) { 03105 dict_foreign_report_syntax_err(name, start_of_latest_foreign, 03106 ptr); 03107 return(DB_CANNOT_ADD_CONSTRAINT); 03108 } 03109 03110 /* Try to find an index which contains the columns 03111 as the first fields and in the right order */ 03112 03113 index = dict_foreign_find_index(table, column_names, i, NULL, TRUE); 03114 03115 if (!index) { 03116 mutex_enter(&dict_foreign_err_mutex); 03117 dict_foreign_error_report_low(ef, name); 03118 fputs("There is no index in table ", ef); 03119 ut_print_name(ef, NULL, TRUE, name); 03120 fprintf(ef, " where the columns appear\n" 03121 "as the first columns. Constraint:\n%s\n" 03122 "See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" 03123 "for correct foreign key definition.\n", 03124 start_of_latest_foreign); 03125 mutex_exit(&dict_foreign_err_mutex); 03126 03127 return(DB_CANNOT_ADD_CONSTRAINT); 03128 } 03129 ptr = dict_accept(cs, ptr, "REFERENCES", &success); 03130 03131 if (!success || !my_isspace(cs, *ptr)) { 03132 dict_foreign_report_syntax_err(name, start_of_latest_foreign, 03133 ptr); 03134 return(DB_CANNOT_ADD_CONSTRAINT); 03135 } 03136 03137 /* Let us create a constraint struct */ 03138 03139 foreign = dict_mem_foreign_create(); 03140 03141 if (constraint_name) { 03142 ulint db_len; 03143 03144 /* Catenate 'databasename/' to the constraint name specified 03145 by the user: we conceive the constraint as belonging to the 03146 same MySQL 'database' as the table itself. We store the name 03147 to foreign->id. */ 03148 03149 db_len = dict_get_db_name_len(table->name); 03150 03151 foreign->id = mem_heap_alloc(foreign->heap, 03152 db_len + strlen(constraint_name) + 2); 03153 03154 ut_memcpy(foreign->id, table->name, db_len); 03155 foreign->id[db_len] = '/'; 03156 strcpy(foreign->id + db_len + 1, constraint_name); 03157 } 03158 03159 foreign->foreign_table = table; 03160 foreign->foreign_table_name = mem_heap_strdup(foreign->heap, 03161 table->name); 03162 foreign->foreign_index = index; 03163 foreign->n_fields = i; 03164 foreign->foreign_col_names = mem_heap_alloc(foreign->heap, 03165 i * sizeof(void*)); 03166 for (i = 0; i < foreign->n_fields; i++) { 03167 foreign->foreign_col_names[i] = 03168 mem_heap_strdup(foreign->heap, columns[i]->name); 03169 } 03170 03171 ptr = dict_scan_table_name(cs, ptr, &referenced_table, name, 03172 &success, heap, &referenced_table_name); 03173 03174 /* Note that referenced_table can be NULL if the user has suppressed 03175 checking of foreign key constraints! */ 03176 03177 if (!success || (!referenced_table && trx->check_foreigns)) { 03178 dict_foreign_free(foreign); 03179 03180 mutex_enter(&dict_foreign_err_mutex); 03181 dict_foreign_error_report_low(ef, name); 03182 fprintf(ef, "%s:\nCannot resolve table name close to:\n" 03183 "%s\n", 03184 start_of_latest_foreign, ptr); 03185 mutex_exit(&dict_foreign_err_mutex); 03186 03187 return(DB_CANNOT_ADD_CONSTRAINT); 03188 } 03189 03190 ptr = dict_accept(cs, ptr, "(", &success); 03191 03192 if (!success) { 03193 dict_foreign_free(foreign); 03194 dict_foreign_report_syntax_err(name, start_of_latest_foreign, 03195 ptr); 03196 return(DB_CANNOT_ADD_CONSTRAINT); 03197 } 03198 03199 /* Scan the columns in the second list */ 03200 i = 0; 03201 03202 col_loop2: 03203 ptr = dict_scan_col(cs, ptr, &success, referenced_table, columns + i, 03204 heap, column_names + i); 03205 i++; 03206 03207 if (!success) { 03208 dict_foreign_free(foreign); 03209 03210 mutex_enter(&dict_foreign_err_mutex); 03211 dict_foreign_error_report_low(ef, name); 03212 fprintf(ef, "%s:\nCannot resolve column name close to:\n" 03213 "%s\n", 03214 start_of_latest_foreign, ptr); 03215 mutex_exit(&dict_foreign_err_mutex); 03216 03217 return(DB_CANNOT_ADD_CONSTRAINT); 03218 } 03219 03220 ptr = dict_accept(cs, ptr, ",", &success); 03221 03222 if (success) { 03223 goto col_loop2; 03224 } 03225 03226 ptr = dict_accept(cs, ptr, ")", &success); 03227 03228 if (!success || foreign->n_fields != i) { 03229 dict_foreign_free(foreign); 03230 03231 dict_foreign_report_syntax_err(name, start_of_latest_foreign, 03232 ptr); 03233 return(DB_CANNOT_ADD_CONSTRAINT); 03234 } 03235 03236 n_on_deletes = 0; 03237 n_on_updates = 0; 03238 03239 scan_on_conditions: 03240 /* Loop here as long as we can find ON ... conditions */ 03241 03242 ptr = dict_accept(cs, ptr, "ON", &success); 03243 03244 if (!success) { 03245 03246 goto try_find_index; 03247 } 03248 03249 ptr = dict_accept(cs, ptr, "DELETE", &success); 03250 03251 if (!success) { 03252 ptr = dict_accept(cs, ptr, "UPDATE", &success); 03253 03254 if (!success) { 03255 dict_foreign_free(foreign); 03256 03257 dict_foreign_report_syntax_err(name, 03258 start_of_latest_foreign, ptr); 03259 return(DB_CANNOT_ADD_CONSTRAINT); 03260 } 03261 03262 is_on_delete = FALSE; 03263 n_on_updates++; 03264 } else { 03265 is_on_delete = TRUE; 03266 n_on_deletes++; 03267 } 03268 03269 ptr = dict_accept(cs, ptr, "RESTRICT", &success); 03270 03271 if (success) { 03272 goto scan_on_conditions; 03273 } 03274 03275 ptr = dict_accept(cs, ptr, "CASCADE", &success); 03276 03277 if (success) { 03278 if (is_on_delete) { 03279 foreign->type |= DICT_FOREIGN_ON_DELETE_CASCADE; 03280 } else { 03281 foreign->type |= DICT_FOREIGN_ON_UPDATE_CASCADE; 03282 } 03283 03284 goto scan_on_conditions; 03285 } 03286 03287 ptr = dict_accept(cs, ptr, "NO", &success); 03288 03289 if (success) { 03290 ptr = dict_accept(cs, ptr, "ACTION", &success); 03291 03292 if (!success) { 03293 dict_foreign_free(foreign); 03294 dict_foreign_report_syntax_err(name, 03295 start_of_latest_foreign, ptr); 03296 03297 return(DB_CANNOT_ADD_CONSTRAINT); 03298 } 03299 03300 if (is_on_delete) { 03301 foreign->type |= DICT_FOREIGN_ON_DELETE_NO_ACTION; 03302 } else { 03303 foreign->type |= DICT_FOREIGN_ON_UPDATE_NO_ACTION; 03304 } 03305 03306 goto scan_on_conditions; 03307 } 03308 03309 ptr = dict_accept(cs, ptr, "SET", &success); 03310 03311 if (!success) { 03312 dict_foreign_free(foreign); 03313 dict_foreign_report_syntax_err(name, start_of_latest_foreign, 03314 ptr); 03315 return(DB_CANNOT_ADD_CONSTRAINT); 03316 } 03317 03318 ptr = dict_accept(cs, ptr, "NULL", &success); 03319 03320 if (!success) { 03321 dict_foreign_free(foreign); 03322 dict_foreign_report_syntax_err(name, start_of_latest_foreign, 03323 ptr); 03324 return(DB_CANNOT_ADD_CONSTRAINT); 03325 } 03326 03327 for (j = 0; j < foreign->n_fields; j++) { 03328 if ((dict_index_get_nth_type( 03329 foreign->foreign_index, j)->prtype) 03330 & DATA_NOT_NULL) { 03331 03332 /* It is not sensible to define SET NULL 03333 if the column is not allowed to be NULL! */ 03334 03335 dict_foreign_free(foreign); 03336 03337 mutex_enter(&dict_foreign_err_mutex); 03338 dict_foreign_error_report_low(ef, name); 03339 fprintf(ef, "%s:\n" 03340 "You have defined a SET NULL condition though some of the\n" 03341 "columns are defined as NOT NULL.\n", start_of_latest_foreign); 03342 mutex_exit(&dict_foreign_err_mutex); 03343 03344 return(DB_CANNOT_ADD_CONSTRAINT); 03345 } 03346 } 03347 03348 if (is_on_delete) { 03349 foreign->type |= DICT_FOREIGN_ON_DELETE_SET_NULL; 03350 } else { 03351 foreign->type |= DICT_FOREIGN_ON_UPDATE_SET_NULL; 03352 } 03353 03354 goto scan_on_conditions; 03355 03356 try_find_index: 03357 if (n_on_deletes > 1 || n_on_updates > 1) { 03358 /* It is an error to define more than 1 action */ 03359 03360 dict_foreign_free(foreign); 03361 03362 mutex_enter(&dict_foreign_err_mutex); 03363 dict_foreign_error_report_low(ef, name); 03364 fprintf(ef, "%s:\n" 03365 "You have twice an ON DELETE clause or twice an ON UPDATE clause.\n", 03366 start_of_latest_foreign); 03367 mutex_exit(&dict_foreign_err_mutex); 03368 03369 return(DB_CANNOT_ADD_CONSTRAINT); 03370 } 03371 03372 /* Try to find an index which contains the columns as the first fields 03373 and in the right order, and the types are the same as in 03374 foreign->foreign_index */ 03375 03376 if (referenced_table) { 03377 index = dict_foreign_find_index(referenced_table, 03378 column_names, i, foreign->foreign_index, TRUE); 03379 if (!index) { 03380 dict_foreign_free(foreign); 03381 mutex_enter(&dict_foreign_err_mutex); 03382 dict_foreign_error_report_low(ef, name); 03383 fprintf(ef, "%s:\n" 03384 "Cannot find an index in the referenced table where the\n" 03385 "referenced columns appear as the first columns, or column types\n" 03386 "in the table and the referenced table do not match for constraint.\n" 03387 "Note that the internal storage type of ENUM and SET changed in\n" 03388 "tables created with >= InnoDB-4.1.12, and such columns in old tables\n" 03389 "cannot be referenced by such columns in new tables.\n" 03390 "See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" 03391 "for correct foreign key definition.\n", 03392 start_of_latest_foreign); 03393 mutex_exit(&dict_foreign_err_mutex); 03394 03395 return(DB_CANNOT_ADD_CONSTRAINT); 03396 } 03397 } else { 03398 ut_a(trx->check_foreigns == FALSE); 03399 index = NULL; 03400 } 03401 03402 foreign->referenced_index = index; 03403 foreign->referenced_table = referenced_table; 03404 03405 foreign->referenced_table_name = mem_heap_strdup(foreign->heap, 03406 referenced_table_name); 03407 03408 foreign->referenced_col_names = mem_heap_alloc(foreign->heap, 03409 i * sizeof(void*)); 03410 for (i = 0; i < foreign->n_fields; i++) { 03411 foreign->referenced_col_names[i] 03412 = mem_heap_strdup(foreign->heap, column_names[i]); 03413 } 03414 03415 /* We found an ok constraint definition: add to the lists */ 03416 03417 UT_LIST_ADD_LAST(foreign_list, table->foreign_list, foreign); 03418 03419 if (referenced_table) { 03420 UT_LIST_ADD_LAST(referenced_list, 03421 referenced_table->referenced_list, 03422 foreign); 03423 } 03424 03425 goto loop; 03426 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_field_print_low | ( | dict_field_t * | field | ) | [static] |
Definition at line 4232 of file dict0dict.c.
References dict_sys, dict_sys_struct::mutex, dict_field_struct::name, dict_field_struct::prefix_len, and ut_ad.
Referenced by dict_index_print_low().
04234 : field */ 04235 { 04236 #ifdef UNIV_SYNC_DEBUG 04237 ut_ad(mutex_own(&(dict_sys->mutex))); 04238 #endif /* UNIV_SYNC_DEBUG */ 04239 fprintf(stderr, " %s", field->name); 04240 04241 if (field->prefix_len != 0) { 04242 fprintf(stderr, "(%lu)", (ulong) field->prefix_len); 04243 } 04244 }
Here is the caller graph for this function:

| ulint dict_foreign_add_to_cache | ( | dict_foreign_t * | foreign, | |
| ibool | check_charsets | |||
| ) |
Definition at line 2233 of file dict0dict.c.
References DB_CANNOT_ADD_CONSTRAINT, DB_SUCCESS, dict_foreign_err_file, dict_foreign_error_report(), dict_foreign_find(), dict_foreign_find_index(), dict_sys, dict_table_check_if_in_cache_low(), FALSE, dict_foreign_struct::foreign_col_names, dict_foreign_struct::foreign_index, dict_table_struct::foreign_list, dict_foreign_struct::foreign_table, dict_foreign_struct::foreign_table_name, dict_foreign_struct::heap, dict_foreign_struct::id, index(), mem_heap_free, dict_sys_struct::mutex, dict_foreign_struct::n_fields, NULL, dict_foreign_struct::referenced_col_names, dict_foreign_struct::referenced_index, dict_table_struct::referenced_list, dict_foreign_struct::referenced_table, dict_foreign_struct::referenced_table_name, TRUE, ut_a, ut_ad, UT_LIST_ADD_LAST, and UT_LIST_REMOVE.
Referenced by dict_load_foreign().
02235 : DB_SUCCESS or error code */ 02236 dict_foreign_t* foreign, /* in, own: foreign key constraint */ 02237 ibool check_charsets) /* in: TRUE=check charset 02238 compatibility */ 02239 { 02240 dict_table_t* for_table; 02241 dict_table_t* ref_table; 02242 dict_foreign_t* for_in_cache = NULL; 02243 dict_index_t* index; 02244 ibool added_to_referenced_list= FALSE; 02245 FILE* ef = dict_foreign_err_file; 02246 02247 #ifdef UNIV_SYNC_DEBUG 02248 ut_ad(mutex_own(&(dict_sys->mutex))); 02249 #endif /* UNIV_SYNC_DEBUG */ 02250 02251 for_table = dict_table_check_if_in_cache_low( 02252 foreign->foreign_table_name); 02253 02254 ref_table = dict_table_check_if_in_cache_low( 02255 foreign->referenced_table_name); 02256 ut_a(for_table || ref_table); 02257 02258 if (for_table) { 02259 for_in_cache = dict_foreign_find(for_table, foreign->id); 02260 } 02261 02262 if (!for_in_cache && ref_table) { 02263 for_in_cache = dict_foreign_find(ref_table, foreign->id); 02264 } 02265 02266 if (for_in_cache) { 02267 /* Free the foreign object */ 02268 mem_heap_free(foreign->heap); 02269 } else { 02270 for_in_cache = foreign; 02271 } 02272 02273 if (for_in_cache->referenced_table == NULL && ref_table) { 02274 index = dict_foreign_find_index(ref_table, 02275 (const char**) for_in_cache->referenced_col_names, 02276 for_in_cache->n_fields, 02277 for_in_cache->foreign_index, check_charsets); 02278 02279 if (index == NULL) { 02280 dict_foreign_error_report(ef, for_in_cache, 02281 "there is no index in referenced table which would contain\n" 02282 "the columns as the first columns, or the data types in the\n" 02283 "referenced table do not match to the ones in table."); 02284 02285 if (for_in_cache == foreign) { 02286 mem_heap_free(foreign->heap); 02287 } 02288 02289 return(DB_CANNOT_ADD_CONSTRAINT); 02290 } 02291 02292 for_in_cache->referenced_table = ref_table; 02293 for_in_cache->referenced_index = index; 02294 UT_LIST_ADD_LAST(referenced_list, 02295 ref_table->referenced_list, 02296 for_in_cache); 02297 added_to_referenced_list = TRUE; 02298 } 02299 02300 if (for_in_cache->foreign_table == NULL && for_table) { 02301 index = dict_foreign_find_index(for_table, 02302 (const char**) for_in_cache->foreign_col_names, 02303 for_in_cache->n_fields, 02304 for_in_cache->referenced_index, check_charsets); 02305 02306 if (index == NULL) { 02307 dict_foreign_error_report(ef, for_in_cache, 02308 "there is no index in the table which would contain\n" 02309 "the columns as the first columns, or the data types in the\n" 02310 "table do not match to the ones in the referenced table."); 02311 02312 if (for_in_cache == foreign) { 02313 if (added_to_referenced_list) { 02314 UT_LIST_REMOVE(referenced_list, 02315 ref_table->referenced_list, 02316 for_in_cache); 02317 } 02318 02319 mem_heap_free(foreign->heap); 02320 } 02321 02322 return(DB_CANNOT_ADD_CONSTRAINT); 02323 } 02324 02325 for_in_cache->foreign_table = for_table; 02326 for_in_cache->foreign_index = index; 02327 UT_LIST_ADD_LAST(foreign_list, 02328 for_table->foreign_list, 02329 for_in_cache); 02330 } 02331 02332 return(DB_SUCCESS); 02333 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_foreign_error_report | ( | FILE * | file, | |
| dict_foreign_t * | fk, | |||
| const char * | msg | |||
| ) | [static] |
Definition at line 2203 of file dict0dict.c.
References dict_foreign_err_mutex, dict_foreign_error_report_low(), dict_print_info_on_foreign_key_in_create_format(), FALSE, dict_foreign_struct::foreign_index, dict_foreign_struct::foreign_table_name, mutex_enter, mutex_exit(), dict_index_struct::name, NULL, TRUE, and ut_print_name().
Referenced by dict_foreign_add_to_cache().
02205 : output stream */ 02206 dict_foreign_t* fk, /* in: foreign key constraint */ 02207 const char* msg) /* in: the error message */ 02208 { 02209 mutex_enter(&dict_foreign_err_mutex); 02210 dict_foreign_error_report_low(file, fk->foreign_table_name); 02211 fputs(msg, file); 02212 fputs(" Constraint:\n", file); 02213 dict_print_info_on_foreign_key_in_create_format(file, NULL, fk, TRUE); 02214 putc('\n', file); 02215 if (fk->foreign_index) { 02216 fputs("The index in the foreign key in table is ", file); 02217 ut_print_name(file, NULL, FALSE, fk->foreign_index->name); 02218 fputs( 02219 "\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" 02220 "for correct foreign key definition.\n", 02221 file); 02222 } 02223 mutex_exit(&dict_foreign_err_mutex); 02224 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_foreign_error_report_low | ( | FILE * | file, | |
| const char * | name | |||
| ) | [static] |
Definition at line 2188 of file dict0dict.c.
References ut_print_timestamp().
Referenced by dict_create_foreign_constraints_low(), dict_foreign_error_report(), and dict_foreign_report_syntax_err().
02190 : output stream */ 02191 const char* name) /* in: table name */ 02192 { 02193 rewind(file); 02194 ut_print_timestamp(file); 02195 fprintf(file, " Error in foreign key constraint of table %s:\n", 02196 name); 02197 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dict_foreign_t* dict_foreign_find | ( | dict_table_t * | table, | |
| const char * | id | |||
| ) | [static] |
Definition at line 2082 of file dict0dict.c.
References dict_sys, dict_table_struct::foreign_list, dict_foreign_struct::id, dict_sys_struct::mutex, NULL, dict_table_struct::referenced_list, ut_ad, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, and ut_strcmp().
Referenced by dict_foreign_add_to_cache().
02084 : foreign constraint */ 02085 dict_table_t* table, /* in: table object */ 02086 const char* id) /* in: foreign constraint id */ 02087 { 02088 dict_foreign_t* foreign; 02089 02090 #ifdef UNIV_SYNC_DEBUG 02091 ut_ad(mutex_own(&(dict_sys->mutex))); 02092 #endif /* UNIV_SYNC_DEBUG */ 02093 02094 foreign = UT_LIST_GET_FIRST(table->foreign_list); 02095 02096 while (foreign) { 02097 if (ut_strcmp(id, foreign->id) == 0) { 02098 02099 return(foreign); 02100 } 02101 02102 foreign = UT_LIST_GET_NEXT(foreign_list, foreign); 02103 } 02104 02105 foreign = UT_LIST_GET_FIRST(table->referenced_list); 02106 02107 while (foreign) { 02108 if (ut_strcmp(id, foreign->id) == 0) { 02109 02110 return(foreign); 02111 } 02112 02113 foreign = UT_LIST_GET_NEXT(referenced_list, foreign); 02114 } 02115 02116 return(NULL); 02117 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dict_index_t* dict_foreign_find_index | ( | dict_table_t * | table, | |
| const char ** | columns, | |||
| ulint | n_cols, | |||
| dict_index_t * | types_idx, | |||
| ibool | check_charsets | |||
| ) | [static] |
Definition at line 2125 of file dict0dict.c.
References cmp_types_are_equal(), dict_index_get_n_fields(), dict_index_get_nth_field(), dict_index_get_nth_type(), dict_table_get_first_index(), dict_table_get_next_index(), index(), innobase_strcasecmp(), dict_field_struct::name, and NULL.
Referenced by dict_create_foreign_constraints_low(), and dict_foreign_add_to_cache().
02127 : matching index, NULL if not found */ 02128 dict_table_t* table, /* in: table */ 02129 const char** columns,/* in: array of column names */ 02130 ulint n_cols, /* in: number of columns */ 02131 dict_index_t* types_idx, /* in: NULL or an index to whose types the 02132 column types must match */ 02133 ibool check_charsets) /* in: whether to check charsets. 02134 only has an effect if types_idx != 02135 NULL. */ 02136 { 02137 dict_index_t* index; 02138 const char* col_name; 02139 ulint i; 02140 02141 index = dict_table_get_first_index(table); 02142 02143 while (index != NULL) { 02144 if (dict_index_get_n_fields(index) >= n_cols) { 02145 02146 for (i = 0; i < n_cols; i++) { 02147 col_name = dict_index_get_nth_field(index, i) 02148 ->col->name; 02149 if (dict_index_get_nth_field(index, i) 02150 ->prefix_len != 0) { 02151 /* We do not accept column prefix 02152 indexes here */ 02153 02154 break; 02155 } 02156 02157 if (0 != innobase_strcasecmp(columns[i], 02158 col_name)) { 02159 break; 02160 } 02161 02162 if (types_idx && !cmp_types_are_equal( 02163 dict_index_get_nth_type(index, i), 02164 dict_index_get_nth_type(types_idx, i), 02165 check_charsets)) { 02166 02167 break; 02168 } 02169 } 02170 02171 if (i == n_cols) { 02172 /* We found a matching index */ 02173 02174 return(index); 02175 } 02176 } 02177 02178 index = dict_table_get_next_index(index); 02179 } 02180 02181 return(NULL); 02182 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_foreign_free | ( | dict_foreign_t * | foreign | ) | [static] |
Definition at line 2044 of file dict0dict.c.
References dict_foreign_struct::heap, and mem_heap_free.
Referenced by dict_create_foreign_constraints_low(), and dict_foreign_remove_from_cache().
02046 : foreign key struct */ 02047 { 02048 mem_heap_free(foreign->heap); 02049 }
Here is the caller graph for this function:

| ulint dict_foreign_parse_drop_constraints | ( | mem_heap_t * | heap, | |
| trx_t * | trx, | |||
| dict_table_t * | table, | |||
| ulint * | n, | |||
| const char *** | constraints_to_drop | |||
| ) |
Definition at line 3497 of file dict0dict.c.
References DB_CANNOT_DROP_CONSTRAINT, DB_SUCCESS, dict_accept(), dict_foreign_err_file, dict_foreign_err_mutex, dict_remove_db_name(), dict_scan_id(), dict_scan_to(), dict_strip_comments(), dict_sys, FALSE, dict_table_struct::foreign_list, id, dict_foreign_struct::id, innobase_get_charset(), mem_free, mem_heap_alloc(), dict_sys_struct::mutex, mutex_enter, mutex_exit(), my_isspace, trx_struct::mysql_query_str, trx_struct::mysql_thd, dict_table_struct::name, NULL, strchr(), strcmp(), TRUE, ut_a, ut_ad, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, ut_print_name(), and ut_print_timestamp().
Referenced by row_rename_table_for_mysql().
03499 : DB_SUCCESS or 03500 DB_CANNOT_DROP_CONSTRAINT if 03501 syntax error or the constraint 03502 id does not match */ 03503 mem_heap_t* heap, /* in: heap from which we can 03504 allocate memory */ 03505 trx_t* trx, /* in: transaction */ 03506 dict_table_t* table, /* in: table */ 03507 ulint* n, /* out: number of constraints 03508 to drop */ 03509 const char*** constraints_to_drop) /* out: id's of the 03510 constraints to drop */ 03511 { 03512 dict_foreign_t* foreign; 03513 ibool success; 03514 char* str; 03515 const char* ptr; 03516 const char* id; 03517 FILE* ef = dict_foreign_err_file; 03518 struct charset_info_st* cs; 03519 03520 ut_a(trx && trx->mysql_thd); 03521 03522 cs = innobase_get_charset(trx->mysql_thd); 03523 03524 *n = 0; 03525 03526 *constraints_to_drop = mem_heap_alloc(heap, 1000 * sizeof(char*)); 03527 03528 str = dict_strip_comments(*(trx->mysql_query_str)); 03529 ptr = str; 03530 03531 #ifdef UNIV_SYNC_DEBUG 03532 ut_ad(mutex_own(&(dict_sys->mutex))); 03533 #endif /* UNIV_SYNC_DEBUG */ 03534 loop: 03535 ptr = dict_scan_to(ptr, "DROP"); 03536 03537 if (*ptr == '\0') { 03538 mem_free(str); 03539 03540 return(DB_SUCCESS); 03541 } 03542 03543 ptr = dict_accept(cs, ptr, "DROP", &success); 03544 03545 if (!my_isspace(cs, *ptr)) { 03546 03547 goto loop; 03548 } 03549 03550 ptr = dict_accept(cs, ptr, "FOREIGN", &success); 03551 03552 if (!success) { 03553 03554 goto loop; 03555 } 03556 03557 ptr = dict_accept(cs, ptr, "KEY", &success); 03558 03559 if (!success) { 03560 03561 goto syntax_error; 03562 } 03563 03564 ptr = dict_scan_id(cs, ptr, heap, &id, FALSE, TRUE); 03565 03566 if (id == NULL) { 03567 03568 goto syntax_error; 03569 } 03570 03571 ut_a(*n < 1000); 03572 (*constraints_to_drop)[*n] = id; 03573 (*n)++; 03574 03575 /* Look for the given constraint id */ 03576 03577 foreign = UT_LIST_GET_FIRST(table->foreign_list); 03578 03579 while (foreign != NULL) { 03580 if (0 == strcmp(foreign->id, id) 03581 || (strchr(foreign->id, '/') 03582 && 0 == strcmp(id, 03583 dict_remove_db_name(foreign->id)))) { 03584 /* Found */ 03585 break; 03586 } 03587 03588 foreign = UT_LIST_GET_NEXT(foreign_list, foreign); 03589 } 03590 03591 if (foreign == NULL) { 03592 mutex_enter(&dict_foreign_err_mutex); 03593 rewind(ef); 03594 ut_print_timestamp(ef); 03595 fputs( 03596 " Error in dropping of a foreign key constraint of table ", ef); 03597 ut_print_name(ef, NULL, TRUE, table->name); 03598 fputs(",\n" 03599 "in SQL command\n", ef); 03600 fputs(str, ef); 03601 fputs("\nCannot find a constraint with the given id ", ef); 03602 ut_print_name(ef, NULL, FALSE, id); 03603 fputs(".\n", ef); 03604 mutex_exit(&dict_foreign_err_mutex); 03605 03606 mem_free(str); 03607 03608 return(DB_CANNOT_DROP_CONSTRAINT); 03609 } 03610 03611 goto loop; 03612 03613 syntax_error: 03614 mutex_enter(&dict_foreign_err_mutex); 03615 rewind(ef); 03616 ut_print_timestamp(ef); 03617 fputs( 03618 " Syntax error in dropping of a foreign key constraint of table ", ef); 03619 ut_print_name(ef, NULL, TRUE, table->name); 03620 fprintf(ef, ",\n" 03621 "close to:\n%s\n in SQL command\n%s\n", ptr, str); 03622 mutex_exit(&dict_foreign_err_mutex); 03623 03624 mem_free(str); 03625 03626 return(DB_CANNOT_DROP_CONSTRAINT); 03627 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_foreign_print_low | ( | dict_foreign_t * | foreign | ) | [static] |
Definition at line 4034 of file dict0dict.c.
References dict_sys, dict_foreign_struct::foreign_col_names, dict_foreign_struct::foreign_table_name, dict_foreign_struct::id, dict_sys_struct::mutex, dict_foreign_struct::n_fields, dict_foreign_struct::referenced_col_names, dict_foreign_struct::referenced_table_name, and ut_ad.
Referenced by dict_table_print_low().
04036 : foreign key constraint */ 04037 { 04038 ulint i; 04039 04040 #ifdef UNIV_SYNC_DEBUG 04041 ut_ad(mutex_own(&(dict_sys->mutex))); 04042 #endif /* UNIV_SYNC_DEBUG */ 04043 04044 fprintf(stderr, " FOREIGN KEY CONSTRAINT %s: %s (", 04045 foreign->id, foreign->foreign_table_name); 04046 04047 for (i = 0; i < foreign->n_fields; i++) { 04048 fprintf(stderr, " %s", foreign->foreign_col_names[i]); 04049 } 04050 04051 fprintf(stderr, " )\n" 04052 " REFERENCES %s (", 04053 foreign->referenced_table_name); 04054 04055 for (i = 0; i < foreign->n_fields; i++) { 04056 fprintf(stderr, " %s", foreign->referenced_col_names[i]); 04057 } 04058 04059 fputs(" )\n", stderr); 04060 }
Here is the caller graph for this function:

| static void dict_foreign_remove_from_cache | ( | dict_foreign_t * | foreign | ) | [static] |
Definition at line 2055 of file dict0dict.c.
References dict_foreign_free(), dict_sys, dict_table_struct::foreign_list, dict_foreign_struct::foreign_table, dict_sys_struct::mutex, dict_table_struct::referenced_list, dict_foreign_struct::referenced_table, ut_a, ut_ad, and UT_LIST_REMOVE.
Referenced by dict_table_remove_from_cache(), and dict_table_rename_in_cache().
02057 : foreign constraint */ 02058 { 02059 #ifdef UNIV_SYNC_DEBUG 02060 ut_ad(mutex_own(&(dict_sys->mutex))); 02061 #endif /* UNIV_SYNC_DEBUG */ 02062 ut_a(foreign); 02063 02064 if (foreign->referenced_table) { 02065 UT_LIST_REMOVE(referenced_list, 02066 foreign->referenced_table->referenced_list, foreign); 02067 } 02068 02069 if (foreign->foreign_table) { 02070 UT_LIST_REMOVE(foreign_list, 02071 foreign->foreign_table->foreign_list, foreign); 02072 } 02073 02074 dict_foreign_free(foreign); 02075 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_foreign_report_syntax_err | ( | const char * | name, | |
| const char * | start_of_latest_foreign, | |||
| const char * | ptr | |||
| ) | [static] |
Definition at line 2848 of file dict0dict.c.
References dict_foreign_err_file, dict_foreign_err_mutex, dict_foreign_error_report_low(), mutex_enter, and mutex_exit().
Referenced by dict_create_foreign_constraints_low().
02850 : table name */ 02851 const char* start_of_latest_foreign, 02852 /* in: start of the foreign key clause 02853 in the SQL string */ 02854 const char* ptr) /* in: place of the syntax error */ 02855 { 02856 FILE* ef = dict_foreign_err_file; 02857 02858 mutex_enter(&dict_foreign_err_mutex); 02859 dict_foreign_error_report_low(ef, name); 02860 fprintf(ef, "%s:\nSyntax error close to:\n%s\n", 02861 start_of_latest_foreign, ptr); 02862 mutex_exit(&dict_foreign_err_mutex); 02863 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_get_db_name_len | ( | const char * | name | ) |
Definition at line 306 of file dict0dict.c.
References strchr(), and ut_a.
Referenced by dict_create_foreign_constraints_low(), dict_print_info_on_foreign_key_in_create_format(), dict_scan_table_name(), dict_table_rename_in_cache(), and row_rename_table_for_mysql().
00308 : database name length */ 00309 const char* name) /* in: table name in the form 00310 dbname '/' tablename */ 00311 { 00312 const char* s; 00313 s = strchr(name, '/'); 00314 ut_a(s); 00315 return(s - name); 00316 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_index_add_col | ( | dict_index_t * | index, | |
| dict_col_t * | col, | |||
| ulint | prefix_len | |||
| ) |
Definition at line 1655 of file dict0dict.c.
References dict_field_struct::col, DATA_NOT_NULL, dict_index_get_nth_field(), DICT_MAX_INDEX_COL_LEN, dict_mem_index_add_field(), dtype_get_fixed_size(), dtype_get_prtype(), dict_field_struct::fixed_len, index(), dict_col_struct::name, and dict_col_struct::type.
Referenced by dict_index_build_internal_clust(), dict_index_copy(), ibuf_dummy_index_add_col(), mlog_parse_index(), and srv_init().
01657 : index */ 01658 dict_col_t* col, /* in: column */ 01659 ulint prefix_len) /* in: column prefix length */ 01660 { 01661 dict_field_t* field; 01662 01663 dict_mem_index_add_field(index, col->name, prefix_len); 01664 01665 field = dict_index_get_nth_field(index, index->n_def - 1); 01666 01667 field->col = col; 01668 field->fixed_len = dtype_get_fixed_size(&col->type); 01669 01670 if (prefix_len && field->fixed_len > prefix_len) { 01671 field->fixed_len = prefix_len; 01672 } 01673 01674 /* Long fixed-length fields that need external storage are treated as 01675 variable-length fields, so that the extern flag can be embedded in 01676 the length word. */ 01677 01678 if (field->fixed_len > DICT_MAX_INDEX_COL_LEN) { 01679 field->fixed_len = 0; 01680 } 01681 01682 if (!(dtype_get_prtype(&col->type) & DATA_NOT_NULL)) { 01683 index->n_nullable++; 01684 } 01685 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool dict_index_add_to_cache | ( | dict_table_t * | table, | |
| dict_index_t * | index, | |||
| ulint | page_no | |||
| ) |
Definition at line 1448 of file dict0dict.c.
References btr_search_info_create(), DICT_CLUSTERED, dict_field_get_col(), dict_index_build_internal_clust(), dict_index_build_internal_non_clust(), dict_index_find_cols(), dict_index_get_n_unique(), dict_index_get_nth_field(), DICT_INDEX_MAGIC_N, dict_mem_index_free(), dict_sys, dict_tree_create(), DICT_UNIVERSAL, FALSE, dict_index_struct::heap, index(), dict_table_struct::indexes, mem_heap_alloc(), mem_heap_get_size(), mem_heap_validate(), dict_sys_struct::mutex, dict_index_struct::n_def, dict_index_struct::n_fields, dict_index_struct::name, dict_table_struct::name, NULL, dict_col_struct::ord_part, dict_index_struct::search_info, dict_sys_struct::size, dict_index_struct::stat_n_diff_key_vals, dict_index_struct::table, dict_index_struct::table_name, dict_index_struct::tree, dict_tree_struct::tree_index, TRUE, dict_index_struct::type, ut_a, ut_ad, UT_LIST_ADD_LAST, UT_LIST_GET_FIRST, UT_LIST_GET_LEN, UT_LIST_GET_NEXT, and ut_strcmp().
Referenced by dict_boot(), dict_create_index_step(), dict_load_indexes(), and ibuf_data_init_for_space().
01450 : TRUE if success */ 01451 dict_table_t* table, /* in: table on which the index is */ 01452 dict_index_t* index, /* in, own: index; NOTE! The index memory 01453 object is freed in this function! */ 01454 ulint page_no)/* in: root page number of the index */ 01455 { 01456 dict_index_t* new_index; 01457 dict_tree_t* tree; 01458 dict_field_t* field; 01459 ulint n_ord; 01460 ibool success; 01461 ulint i; 01462 01463 ut_ad(index); 01464 #ifdef UNIV_SYNC_DEBUG 01465 ut_ad(mutex_own(&(dict_sys->mutex))); 01466 #endif /* UNIV_SYNC_DEBUG */ 01467 ut_ad(index->n_def == index->n_fields); 01468 ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); 01469 01470 ut_ad(mem_heap_validate(index->heap)); 01471 01472 #ifdef UNIV_DEBUG 01473 { 01474 dict_index_t* index2; 01475 index2 = UT_LIST_GET_FIRST(table->indexes); 01476 01477 while (index2 != NULL) { 01478 ut_ad(ut_strcmp(index->name, index2->name) != 0); 01479 01480 index2 = UT_LIST_GET_NEXT(indexes, index2); 01481 } 01482 } 01483 #endif /* UNIV_DEBUG */ 01484 01485 ut_a(!(index->type & DICT_CLUSTERED) 01486 || UT_LIST_GET_LEN(table->indexes) == 0); 01487 01488 success = dict_index_find_cols(table, index); 01489 01490 if (!success) { 01491 dict_mem_index_free(index); 01492 01493 return(FALSE); 01494 } 01495 01496 /* Build the cache internal representation of the index, 01497 containing also the added system fields */ 01498 01499 if (index->type & DICT_CLUSTERED) { 01500 new_index = dict_index_build_internal_clust(table, index); 01501 } else { 01502 new_index = dict_index_build_internal_non_clust(table, index); 01503 } 01504 01505 new_index->search_info = btr_search_info_create(new_index->heap); 01506 01507 /* Set the n_fields value in new_index to the actual defined 01508 number of fields in the cache internal representation */ 01509 01510 new_index->n_fields = new_index->n_def; 01511 01512 /* Add the new index as the last index for the table */ 01513 01514 UT_LIST_ADD_LAST(indexes, table->indexes, new_index); 01515 new_index->table = table; 01516 new_index->table_name = table->name; 01517 01518 /* Increment the ord_part counts in columns which are ordering */ 01519 01520 if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) { 01521 n_ord = new_index->n_fields; 01522 } else { 01523 n_ord = dict_index_get_n_unique(new_index); 01524 } 01525 01526 for (i = 0; i < n_ord; i++) { 01527 01528 field = dict_index_get_nth_field(new_index, i); 01529 01530 dict_field_get_col(field)->ord_part++; 01531 } 01532 01533 /* Create an index tree memory object for the index */ 01534 tree = dict_tree_create(new_index, page_no); 01535 ut_ad(tree); 01536 01537 new_index->tree = tree; 01538 01539 if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) { 01540 01541 new_index->stat_n_diff_key_vals = 01542 mem_heap_alloc(new_index->heap, 01543 (1 + dict_index_get_n_unique(new_index)) 01544 * sizeof(ib_longlong)); 01545 /* Give some sensible values to stat_n_... in case we do 01546 not calculate statistics quickly enough */ 01547 01548 for (i = 0; i <= dict_index_get_n_unique(new_index); i++) { 01549 01550 new_index->stat_n_diff_key_vals[i] = 100; 01551 } 01552 } 01553 01554 /* Add the index to the list of indexes stored in the tree */ 01555 tree->tree_index = new_index; 01556 01557 dict_sys->size += mem_heap_get_size(new_index->heap); 01558 01559 dict_mem_index_free(index); 01560 01561 return(TRUE); 01562 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dict_index_t * dict_index_build_internal_clust | ( | dict_table_t * | table, | |
| dict_index_t * | index | |||
| ) | [static] |
Definition at line 1765 of file dict0dict.c.
References dict_col_struct::aux, dict_field_struct::col, DATA_ROLL_PTR, DATA_ROW_ID, DATA_TRX_ID, DICT_CLUSTERED, DICT_IBUF, dict_index_add_col(), dict_index_copy(), dict_index_get_nth_field(), dict_index_get_nth_type(), dict_mem_index_create(), dict_sys, dict_table_get_nth_col(), dict_table_get_sys_col(), DICT_TABLE_MAGIC_N, DICT_UNIQUE, DICT_UNIVERSAL, dtype_get_fixed_size(), dict_index_struct::id, index(), dict_table_struct::magic_n, dict_sys_struct::mutex, dict_table_struct::n_cols, dict_index_struct::n_def, dict_index_struct::n_uniq, dict_index_struct::n_user_defined_cols, dict_table_struct::name, dict_field_struct::prefix_len, dict_table_struct::space, dict_index_struct::trx_id_offset, and ut_ad.
Referenced by dict_index_add_to_cache().
01767 : the internal representation 01768 of the clustered index */ 01769 dict_table_t* table, /* in: table */ 01770 dict_index_t* index) /* in: user representation of a clustered 01771 index */ 01772 { 01773 dict_index_t* new_index; 01774 dict_field_t* field; 01775 dict_col_t* col; 01776 ulint fixed_size; 01777 ulint trx_id_pos; 01778 ulint i; 01779 01780 ut_ad(table && index); 01781 ut_ad(index->type & DICT_CLUSTERED); 01782 #ifdef UNIV_SYNC_DEBUG 01783 ut_ad(mutex_own(&(dict_sys->mutex))); 01784 #endif /* UNIV_SYNC_DEBUG */ 01785 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01786 01787 /* Create a new index object with certainly enough fields */ 01788 new_index = dict_mem_index_create(table->name, 01789 index->name, table->space, index->type, 01790 index->n_fields + table->n_cols); 01791 01792 /* Copy other relevant data from the old index struct to the new 01793 struct: it inherits the values */ 01794 01795 new_index->n_user_defined_cols = index->n_fields; 01796 01797 new_index->id = index->id; 01798 01799 /* Copy the fields of index */ 01800 dict_index_copy(new_index, index, 0, index->n_fields); 01801 01802 if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) { 01803 /* No fixed number of fields determines an entry uniquely */ 01804 01805 new_index->n_uniq = ULINT_MAX; 01806 01807 } else if (index->type & DICT_UNIQUE) { 01808 /* Only the fields defined so far are needed to identify 01809 the index entry uniquely */ 01810 01811 new_index->n_uniq = new_index->n_def; 01812 } else { 01813 /* Also the row id is needed to identify the entry */ 01814 new_index->n_uniq = 1 + new_index->n_def; 01815 } 01816 01817 new_index->trx_id_offset = 0; 01818 01819 if (!(index->type & DICT_IBUF)) { 01820 /* Add system columns, trx id first */ 01821 01822 trx_id_pos = new_index->n_def; 01823 01824 #if DATA_ROW_ID != 0 01825 # error "DATA_ROW_ID != 0" 01826 #endif 01827 #if DATA_TRX_ID != 1 01828 # error "DATA_TRX_ID != 1" 01829 #endif 01830 #if DATA_ROLL_PTR != 2 01831 # error "DATA_ROLL_PTR != 2" 01832 #endif 01833 01834 if (!(index->type & DICT_UNIQUE)) { 01835 dict_index_add_col(new_index, 01836 dict_table_get_sys_col(table, DATA_ROW_ID), 0); 01837 trx_id_pos++; 01838 } 01839 01840 dict_index_add_col(new_index, 01841 dict_table_get_sys_col(table, DATA_TRX_ID), 0); 01842 01843 dict_index_add_col(new_index, 01844 dict_table_get_sys_col(table, DATA_ROLL_PTR), 0); 01845 01846 for (i = 0; i < trx_id_pos; i++) { 01847 01848 fixed_size = dtype_get_fixed_size( 01849 dict_index_get_nth_type(new_index, i)); 01850 01851 if (fixed_size == 0) { 01852 new_index->trx_id_offset = 0; 01853 01854 break; 01855 } 01856 01857 if (dict_index_get_nth_field(new_index, i)->prefix_len 01858 > 0) { 01859 new_index->trx_id_offset = 0; 01860 01861 break; 01862 } 01863 01864 new_index->trx_id_offset += fixed_size; 01865 } 01866 01867 } 01868 01869 /* Set auxiliary variables in table columns as undefined */ 01870 for (i = 0; i < table->n_cols; i++) { 01871 01872 col = dict_table_get_nth_col(table, i); 01873 col->aux = ULINT_UNDEFINED; 01874 } 01875 01876 /* Mark with 0 the table columns already contained in new_index */ 01877 for (i = 0; i < new_index->n_def; i++) { 01878 01879 field = dict_index_get_nth_field(new_index, i); 01880 01881 /* If there is only a prefix of the column in the index 01882 field, do not mark the column as contained in the index */ 01883 01884 if (field->prefix_len == 0) { 01885 01886 field->col->aux = 0; 01887 } 01888 } 01889 01890 /* Add to new_index non-system columns of table not yet included 01891 there */ 01892 for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) { 01893 01894 col = dict_table_get_nth_col(table, i); 01895 ut_ad(col->type.mtype != DATA_SYS); 01896 01897 if (col->aux == ULINT_UNDEFINED) { 01898 dict_index_add_col(new_index, col, 0); 01899 } 01900 } 01901 01902 ut_ad((index->type & DICT_IBUF) 01903 || (UT_LIST_GET_LEN(table->indexes) == 0)); 01904 01905 /* Store to the column structs the position of the table columns 01906 in the clustered index */ 01907 01908 for (i = 0; i < new_index->n_def; i++) { 01909 field = dict_index_get_nth_field(new_index, i); 01910 01911 if (field->prefix_len == 0) { 01912 01913 field->col->clust_pos = i; 01914 } 01915 } 01916 01917 new_index->cached = TRUE; 01918 01919 return(new_index); 01920 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dict_index_t * dict_index_build_internal_non_clust | ( | dict_table_t * | table, | |
| dict_index_t * | index | |||
| ) | [static] |
Definition at line 1927 of file dict0dict.c.
References dict_col_struct::aux, dict_field_struct::col, DICT_CLUSTERED, dict_index_copy(), dict_index_get_nth_field(), dict_mem_index_create(), dict_sys, DICT_TABLE_MAGIC_N, DICT_UNIVERSAL, dict_index_struct::id, index(), dict_table_struct::indexes, dict_table_struct::magic_n, dict_sys_struct::mutex, dict_index_struct::n_def, dict_index_struct::n_uniq, dict_index_struct::n_user_defined_cols, dict_table_struct::name, dict_field_struct::prefix_len, dict_index_struct::type, ut_ad, and UT_LIST_GET_FIRST.
Referenced by dict_index_add_to_cache().
01929 : the internal representation 01930 of the non-clustered index */ 01931 dict_table_t* table, /* in: table */ 01932 dict_index_t* index) /* in: user representation of a non-clustered 01933 index */ 01934 { 01935 dict_field_t* field; 01936 dict_index_t* new_index; 01937 dict_index_t* clust_index; 01938 ulint i; 01939 01940 ut_ad(table && index); 01941 ut_ad(0 == (index->type & DICT_CLUSTERED)); 01942 #ifdef UNIV_SYNC_DEBUG 01943 ut_ad(mutex_own(&(dict_sys->mutex))); 01944 #endif /* UNIV_SYNC_DEBUG */ 01945 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01946 01947 /* The clustered index should be the first in the list of indexes */ 01948 clust_index = UT_LIST_GET_FIRST(table->indexes); 01949 01950 ut_ad(clust_index); 01951 ut_ad(clust_index->type & DICT_CLUSTERED); 01952 ut_ad(!(clust_index->type & DICT_UNIVERSAL)); 01953 01954 /* Create a new index */ 01955 new_index = dict_mem_index_create(table->name, 01956 index->name, index->space, index->type, 01957 index->n_fields + 1 + clust_index->n_uniq); 01958 01959 /* Copy other relevant data from the old index 01960 struct to the new struct: it inherits the values */ 01961 01962 new_index->n_user_defined_cols = index->n_fields; 01963 01964 new_index->id = index->id; 01965 01966 /* Copy fields from index to new_index */ 01967 dict_index_copy(new_index, index, 0, index->n_fields); 01968 01969 /* Set the auxiliary variables in the clust_index unique columns 01970 as undefined */ 01971 for (i = 0; i < clust_index->n_uniq; i++) { 01972 01973 field = dict_index_get_nth_field(clust_index, i); 01974 field->col->aux = ULINT_UNDEFINED; 01975 } 01976 01977 /* Mark with 0 table columns already contained in new_index */ 01978 for (i = 0; i < new_index->n_def; i++) { 01979 01980 field = dict_index_get_nth_field(new_index, i); 01981 01982 /* If there is only a prefix of the column in the index 01983 field, do not mark the column as contained in the index */ 01984 01985 if (field->prefix_len == 0) { 01986 01987 field->col->aux = 0; 01988 } 01989 } 01990 01991 /* Add to new_index the columns necessary to determine the clustered 01992 index entry uniquely */ 01993 01994 for (i = 0; i < clust_index->n_uniq; i++) { 01995 01996 field = dict_index_get_nth_field(clust_index, i); 01997 01998 if (field->col->aux == ULINT_UNDEFINED) { 01999 dict_index_add_col(new_index, field->col, 02000 field->prefix_len); 02001 } 02002 } 02003 02004 if ((index->type) & DICT_UNIQUE) { 02005 new_index->n_uniq = index->n_fields; 02006 } else { 02007 new_index->n_uniq = new_index->n_def; 02008 } 02009 02010 /* Set the n_fields value in new_index to the actual defined 02011 number of fields */ 02012 02013 new_index->n_fields = new_index->n_def; 02014 02015 new_index->cached = TRUE; 02016 02017 return(new_index); 02018 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_index_calc_min_rec_len | ( | dict_index_t * | index | ) |
Definition at line 3880 of file dict0dict.c.
References DATA_NOT_NULL, dict_index_get_n_fields(), dict_index_get_nth_type(), dict_table_is_comp(), dtype_get_fixed_size(), dtype_get_len(), dtype_get_prtype(), index(), REC_N_NEW_EXTRA_BYTES, and REC_N_OLD_EXTRA_BYTES.
03882 : index */ 03883 { 03884 ulint sum = 0; 03885 ulint i; 03886 03887 if (dict_table_is_comp(index->table)) { 03888 ulint nullable = 0; 03889 sum = REC_N_NEW_EXTRA_BYTES; 03890 for (i = 0; i < dict_index_get_n_fields(index); i++) { 03891 dtype_t*t = dict_index_get_nth_type(index, i); 03892 ulint size = dtype_get_fixed_size(t); 03893 sum += size; 03894 if (!size) { 03895 size = dtype_get_len(t); 03896 sum += size < 128 ? 1 : 2; 03897 } 03898 if (!(dtype_get_prtype(t) & DATA_NOT_NULL)) 03899 nullable++; 03900 } 03901 03902 /* round the NULL flags up to full bytes */ 03903 sum += (nullable + 7) / 8; 03904 03905 return(sum); 03906 } 03907 03908 for (i = 0; i < dict_index_get_n_fields(index); i++) { 03909 sum += dtype_get_fixed_size(dict_index_get_nth_type(index, i)); 03910 } 03911 03912 if (sum > 127) { 03913 sum += 2 * dict_index_get_n_fields(index); 03914 } else { 03915 sum += dict_index_get_n_fields(index); 03916 } 03917 03918 sum += REC_N_OLD_EXTRA_BYTES; 03919 03920 return(sum); 03921 }
Here is the call graph for this function:

| ibool dict_index_contains_col_or_prefix | ( | dict_index_t * | index, | |
| ulint | n | |||
| ) |
Definition at line 580 of file dict0dict.c.
References dict_field_struct::col, DICT_CLUSTERED, dict_index_get_n_fields(), dict_index_get_nth_field(), DICT_INDEX_MAGIC_N, dict_table_get_nth_col(), index(), pos(), TRUE, and ut_ad.
00582 : TRUE if contains the column or its 00583 prefix */ 00584 dict_index_t* index, /* in: index */ 00585 ulint n) /* in: column number */ 00586 { 00587 dict_field_t* field; 00588 dict_col_t* col; 00589 ulint pos; 00590 ulint n_fields; 00591 00592 ut_ad(index); 00593 ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); 00594 00595 if (index->type & DICT_CLUSTERED) { 00596 00597 return(TRUE); 00598 } 00599 00600 col = dict_table_get_nth_col(index->table, n); 00601 00602 n_fields = dict_index_get_n_fields(index); 00603 00604 for (pos = 0; pos < n_fields; pos++) { 00605 field = dict_index_get_nth_field(index, pos); 00606 00607 if (col == field->col) { 00608 00609 return(TRUE); 00610 } 00611 } 00612 00613 return(FALSE); 00614 }
Here is the call graph for this function:

| static void dict_index_copy | ( | dict_index_t * | index1, | |
| dict_index_t * | index2, | |||
| ulint | start, | |||
| ulint | end | |||
| ) | [static] |
Definition at line 1691 of file dict0dict.c.
References dict_field_struct::col, dict_index_add_col(), dict_index_get_nth_field(), and dict_field_struct::prefix_len.
Referenced by dict_index_build_internal_clust(), and dict_index_build_internal_non_clust().
01693 : index to copy to */ 01694 dict_index_t* index2, /* in: index to copy from */ 01695 ulint start, /* in: first position to copy */ 01696 ulint end) /* in: last position to copy */ 01697 { 01698 dict_field_t* field; 01699 ulint i; 01700 01701 /* Copy fields contained in index2 */ 01702 01703 for (i = start; i < end; i++) { 01704 01705 field = dict_index_get_nth_field(index2, i); 01706 dict_index_add_col(index1, field->col, field->prefix_len); 01707 } 01708 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_index_copy_types | ( | dtuple_t * | tuple, | |
| dict_index_t * | index, | |||
| ulint | n_fields | |||
| ) |
Definition at line 1714 of file dict0dict.c.
References dfield_get_type(), dict_col_get_type(), dict_field_get_col(), dict_index_get_nth_field(), DICT_UNIVERSAL, dtuple_get_nth_field(), dtuple_set_types_binary(), and index().
Referenced by dict_get_first_table_name_in_db(), dict_load_columns(), dict_load_fields(), dict_load_foreign(), dict_load_foreign_cols(), dict_load_foreigns(), dict_load_indexes(), dict_load_table(), dict_load_table_on_id(), dict_tree_build_data_tuple(), dict_tree_build_node_ptr(), opt_clust_access(), opt_search_plan_for_table(), row_build_row_ref(), row_build_row_ref_in_tuple(), row_create_prebuilt(), row_rec_to_index_entry(), row_truncate_table_for_mysql(), and trx_undo_rec_get_row_ref().
01716 : data tuple */ 01717 dict_index_t* index, /* in: index */ 01718 ulint n_fields) /* in: number of field types to copy */ 01719 { 01720 dtype_t* dfield_type; 01721 dtype_t* type; 01722 ulint i; 01723 01724 if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) { 01725 dtuple_set_types_binary(tuple, n_fields); 01726 01727 return; 01728 } 01729 01730 for (i = 0; i < n_fields; i++) { 01731 dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i)); 01732 type = dict_col_get_type(dict_field_get_col( 01733 dict_index_get_nth_field(index, i))); 01734 *dfield_type = *type; 01735 } 01736 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ibool dict_index_find_cols | ( | dict_table_t * | table, | |
| dict_index_t * | index | |||
| ) | [static] |
Definition at line 1613 of file dict0dict.c.
References dict_field_struct::col, dict_sys_struct::col_hash, dict_index_get_nth_field(), dict_sys, DICT_TABLE_MAGIC_N, FALSE, hash(), HASH_SEARCH, index(), dict_table_struct::magic_n, dict_sys_struct::mutex, dict_col_struct::name, dict_field_struct::name, dict_table_struct::name, NULL, dict_col_struct::table, TRUE, ut_ad, ut_fold_string(), ut_fold_ulint_pair(), and ut_strcmp().
Referenced by dict_index_add_to_cache().
01615 : TRUE if success */ 01616 dict_table_t* table, /* in: table */ 01617 dict_index_t* index) /* in: index */ 01618 { 01619 dict_col_t* col; 01620 dict_field_t* field; 01621 ulint fold; 01622 ulint i; 01623 01624 ut_ad(table && index); 01625 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01626 #ifdef UNIV_SYNC_DEBUG 01627 ut_ad(mutex_own(&(dict_sys->mutex))); 01628 #endif /* UNIV_SYNC_DEBUG */ 01629 01630 for (i = 0; i < index->n_fields; i++) { 01631 field = dict_index_get_nth_field(index, i); 01632 01633 fold = ut_fold_ulint_pair(ut_fold_string(table->name), 01634 ut_fold_string(field->name)); 01635 01636 HASH_SEARCH(hash, dict_sys->col_hash, fold, col, 01637 (ut_strcmp(col->name, field->name) == 0) 01638 && (ut_strcmp((col->table)->name, table->name) 01639 == 0)); 01640 if (col == NULL) { 01641 01642 return(FALSE); 01643 } else { 01644 field->col = col; 01645 } 01646 } 01647 01648 return(TRUE); 01649 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dict_index_t* dict_index_find_on_id_low | ( | dulint | id | ) |
Definition at line 970 of file dict0dict.c.
References dict_sys, dict_table_get_first_index(), dict_table_get_next_index(), index(), NULL, dict_sys_struct::table_LRU, ut_dulint_cmp(), UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
Referenced by buf_page_print().
00972 : index or NULL if not found from cache */ 00973 dulint id) /* in: index id */ 00974 { 00975 dict_table_t* table; 00976 dict_index_t* index; 00977 00978 table = UT_LIST_GET_FIRST(dict_sys->table_LRU); 00979 00980 while (table) { 00981 index = dict_table_get_first_index(table); 00982 00983 while (index) { 00984 if (0 == ut_dulint_cmp(id, index->tree->id)) { 00985 /* Found */ 00986 00987 return(index); 00988 } 00989 00990 index = dict_table_get_next_index(index); 00991 } 00992 00993 table = UT_LIST_GET_NEXT(table_LRU, table); 00994 } 00995 00996 return(NULL); 00997 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dict_index_t* dict_index_get_if_in_cache | ( | dulint | index_id | ) |
Definition at line 3636 of file dict0dict.c.
References dict_sys, index(), dict_table_struct::indexes, dict_sys_struct::mutex, mutex_enter, mutex_exit(), NULL, dict_sys_struct::table_LRU, ut_dulint_cmp(), UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
03638 : index, NULL if not found */ 03639 dulint index_id) /* in: index id */ 03640 { 03641 dict_table_t* table; 03642 dict_index_t* index; 03643 03644 if (dict_sys == NULL) { 03645 return(NULL); 03646 } 03647 03648 mutex_enter(&(dict_sys->mutex)); 03649 03650 table = UT_LIST_GET_FIRST(dict_sys->table_LRU); 03651 03652 while (table) { 03653 index = UT_LIST_GET_FIRST(table->indexes); 03654 03655 while (index) { 03656 if (0 == ut_dulint_cmp(index->id, index_id)) { 03657 03658 goto found; 03659 } 03660 03661 index = UT_LIST_GET_NEXT(indexes, index); 03662 } 03663 03664 table = UT_LIST_GET_NEXT(table_LRU, table); 03665 } 03666 03667 index = NULL; 03668 found: 03669 mutex_exit(&(dict_sys->mutex)); 03670 03671 return(index); 03672 }
Here is the call graph for this function:

| ulint dict_index_get_nth_col_pos | ( | dict_index_t * | index, | |
| ulint | n | |||
| ) |
Definition at line 539 of file dict0dict.c.
References dict_col_struct::clust_pos, dict_field_struct::col, DICT_CLUSTERED, dict_index_get_n_fields(), dict_index_get_nth_field(), DICT_INDEX_MAGIC_N, dict_table_get_nth_col(), index(), pos(), dict_field_struct::prefix_len, and ut_ad.
Referenced by dict_table_get_nth_col_pos(), opt_find_all_cols(), pars_process_assign_list(), and trx_undo_page_report_modify().
00541 : position in internal representation 00542 of the index; if not contained, returns 00543 ULINT_UNDEFINED */ 00544 dict_index_t* index, /* in: index */ 00545 ulint n) /* in: column number */ 00546 { 00547 dict_field_t* field; 00548 dict_col_t* col; 00549 ulint pos; 00550 ulint n_fields; 00551 00552 ut_ad(index); 00553 ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); 00554 00555 col = dict_table_get_nth_col(index->table, n); 00556 00557 if (index->type & DICT_CLUSTERED) { 00558 00559 return(col->clust_pos); 00560 } 00561 00562 n_fields = dict_index_get_n_fields(index); 00563 00564 for (pos = 0; pos < n_fields; pos++) { 00565 field = dict_index_get_nth_field(index, pos); 00566 00567 if (col == field->col && field->prefix_len == 0) { 00568 00569 return(pos); 00570 } 00571 } 00572 00573 return(ULINT_UNDEFINED); 00574 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_index_get_nth_field_pos | ( | dict_index_t * | index, | |
| dict_index_t * | index2, | |||
| ulint | n | |||
| ) |
Definition at line 623 of file dict0dict.c.
References dict_field_struct::col, dict_index_get_n_fields(), dict_index_get_nth_field(), DICT_INDEX_MAGIC_N, index(), pos(), dict_field_struct::prefix_len, and ut_ad.
Referenced by opt_clust_access(), row_build_row_ref(), and row_build_row_ref_in_tuple().
00625 : position in internal representation 00626 of the index; if not contained, returns 00627 ULINT_UNDEFINED */ 00628 dict_index_t* index, /* in: index from which to search */ 00629 dict_index_t* index2, /* in: index */ 00630 ulint n) /* in: field number in index2 */ 00631 { 00632 dict_field_t* field; 00633 dict_field_t* field2; 00634 ulint n_fields; 00635 ulint pos; 00636 00637 ut_ad(index); 00638 ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); 00639 00640 field2 = dict_index_get_nth_field(index2, n); 00641 00642 n_fields = dict_index_get_n_fields(index); 00643 00644 for (pos = 0; pos < n_fields; pos++) { 00645 field = dict_index_get_nth_field(index, pos); 00646 00647 if (field->col == field2->col 00648 && (field->prefix_len == 0 00649 || (field->prefix_len >= field2->prefix_len 00650 && field2->prefix_len != 0))) { 00651 00652 return(pos); 00653 } 00654 } 00655 00656 return(ULINT_UNDEFINED); 00657 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_index_name_print | ( | FILE * | file, | |
| trx_t * | trx, | |||
| const dict_index_t * | index | |||
| ) |
Definition at line 4445 of file dict0dict.c.
References FALSE, index(), TRUE, and ut_print_name().
Referenced by btr_cur_optimistic_insert(), btr_index_rec_validate_report(), btr_validate_report1(), btr_validate_report2(), buf_page_print(), lock_check_trx_id_sanity(), lock_rec_print(), opt_print_query_plan(), page_validate(), row_check_table_for_mysql(), row_create_index_for_mysql(), row_ins_foreign_check_on_constraint(), row_scan_and_check_index(), row_search_for_mysql(), row_sel_convert_mysql_key_to_innobase(), row_sel_get_clust_rec_for_mysql(), row_sel_store_row_id_to_prebuilt(), row_undo_mod_del_unmark_sec_and_undo_update(), row_upd_sec_index_entry(), and trx_undo_update_rec_get_update().
04447 : output stream */ 04448 trx_t* trx, /* in: transaction */ 04449 const dict_index_t* index) /* in: index to print */ 04450 { 04451 fputs("index ", file); 04452 ut_print_name(file, trx, FALSE, index->name); 04453 fputs(" of table ", file); 04454 ut_print_name(file, trx, TRUE, index->table_name); 04455 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_index_print_low | ( | dict_index_t * | index | ) | [static] |
Definition at line 4177 of file dict0dict.c.
References dict_field_print_low(), dict_index_get_nth_field(), dict_sys, dict_tree_struct::id, index(), dict_sys_struct::mutex, dict_tree_struct::page, ut_ad, ut_dulint_get_high(), and ut_dulint_get_low().
Referenced by dict_table_print_low().
04179 : index */ 04180 { 04181 dict_tree_t* tree; 04182 ib_longlong n_vals; 04183 ulint i; 04184 04185 #ifdef UNIV_SYNC_DEBUG 04186 ut_ad(mutex_own(&(dict_sys->mutex))); 04187 #endif /* UNIV_SYNC_DEBUG */ 04188 04189 tree = index->tree; 04190 04191 if (index->n_user_defined_cols > 0) { 04192 n_vals = index->stat_n_diff_key_vals[ 04193 index->n_user_defined_cols]; 04194 } else { 04195 n_vals = index->stat_n_diff_key_vals[1]; 04196 } 04197 04198 fprintf(stderr, 04199 " INDEX: name %s, id %lu %lu, fields %lu/%lu, uniq %lu, type %lu\n" 04200 " root page %lu, appr.key vals %lu," 04201 " leaf pages %lu, size pages %lu\n" 04202 " FIELDS: ", 04203 index->name, 04204 (ulong) ut_dulint_get_high(tree->id), 04205 (ulong) ut_dulint_get_low(tree->id), 04206 (ulong) index->n_user_defined_cols, 04207 (ulong) index->n_fields, 04208 (ulong) index->n_uniq, 04209 (ulong) index->type, 04210 (ulong) tree->page, 04211 (ulong) n_vals, 04212 (ulong) index->stat_n_leaf_pages, 04213 (ulong) index->stat_index_size); 04214 04215 for (i = 0; i < index->n_fields; i++) { 04216 dict_field_print_low(dict_index_get_nth_field(index, i)); 04217 } 04218 04219 putc('\n', stderr); 04220 04221 #ifdef UNIV_BTR_PRINT 04222 btr_print_size(tree); 04223 04224 btr_print_tree(tree, 7); 04225 #endif /* UNIV_BTR_PRINT */ 04226 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_index_remove_from_cache | ( | dict_table_t * | table, | |
| dict_index_t * | index | |||
| ) | [static] |
Definition at line 1568 of file dict0dict.c.
References dict_field_get_col(), dict_index_get_n_unique(), dict_index_get_nth_field(), DICT_INDEX_MAGIC_N, dict_mem_index_free(), dict_sys, DICT_TABLE_MAGIC_N, dict_tree_free(), index(), dict_table_struct::indexes, dict_table_struct::magic_n, mem_heap_get_size(), dict_sys_struct::mutex, dict_col_struct::ord_part, dict_sys_struct::size, ut_ad, and UT_LIST_REMOVE.
Referenced by dict_table_remove_from_cache().
01570 : table */ 01571 dict_index_t* index) /* in, own: index */ 01572 { 01573 dict_field_t* field; 01574 ulint size; 01575 ulint i; 01576 01577 ut_ad(table && index); 01578 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01579 ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); 01580 #ifdef UNIV_SYNC_DEBUG 01581 ut_ad(mutex_own(&(dict_sys->mutex))); 01582 #endif /* UNIV_SYNC_DEBUG */ 01583 01584 ut_ad(index->tree->tree_index); 01585 dict_tree_free(index->tree); 01586 01587 /* Decrement the ord_part counts in columns which are ordering */ 01588 for (i = 0; i < dict_index_get_n_unique(index); i++) { 01589 01590 field = dict_index_get_nth_field(index, i); 01591 01592 ut_ad(dict_field_get_col(field)->ord_part > 0); 01593 (dict_field_get_col(field)->ord_part)--; 01594 } 01595 01596 /* Remove the index from the list of indexes of the table */ 01597 UT_LIST_REMOVE(indexes, table->indexes, index); 01598 01599 size = mem_heap_get_size(index->heap); 01600 01601 ut_ad(dict_sys->size >= size); 01602 01603 dict_sys->size -= size; 01604 01605 dict_mem_index_free(index); 01606 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_init | ( | void | ) |
Definition at line 764 of file dict0dict.c.
References buf_pool_get_max_size(), dict_sys_struct::col_hash, dict_foreign_err_file, dict_foreign_err_mutex, dict_operation_lock, DICT_POOL_PER_COL_HASH, DICT_POOL_PER_TABLE_HASH, dict_sys, hash_create(), mem_alloc, dict_sys_struct::mutex, mutex_create, os_file_create_tmpfile(), rw_lock_create, dict_sys_struct::size, SYNC_ANY_LATCH, SYNC_DICT, SYNC_DICT_OPERATION, dict_sys_struct::table_hash, dict_sys_struct::table_id_hash, dict_sys_struct::table_LRU, ut_a, and UT_LIST_INIT.
Referenced by dict_boot().
00766 { 00767 dict_sys = mem_alloc(sizeof(dict_sys_t)); 00768 00769 mutex_create(&dict_sys->mutex, SYNC_DICT); 00770 00771 dict_sys->table_hash = hash_create(buf_pool_get_max_size() / 00772 (DICT_POOL_PER_TABLE_HASH * 00773 UNIV_WORD_SIZE)); 00774 dict_sys->table_id_hash = hash_create(buf_pool_get_max_size() / 00775 (DICT_POOL_PER_TABLE_HASH * 00776 UNIV_WORD_SIZE)); 00777 dict_sys->col_hash = hash_create(buf_pool_get_max_size() / 00778 (DICT_POOL_PER_COL_HASH * 00779 UNIV_WORD_SIZE)); 00780 dict_sys->size = 0; 00781 00782 UT_LIST_INIT(dict_sys->table_LRU); 00783 00784 rw_lock_create(&dict_operation_lock, SYNC_DICT_OPERATION); 00785 00786 dict_foreign_err_file = os_file_create_tmpfile(); 00787 ut_a(dict_foreign_err_file); 00788 00789 mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH); 00790 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_mutex_enter_for_mysql | ( | void | ) |
Definition at line 322 of file dict0dict.c.
References dict_sys, dict_sys_struct::mutex, and mutex_enter.
00324 { 00325 mutex_enter(&(dict_sys->mutex)); 00326 }
| void dict_mutex_exit_for_mysql | ( | void | ) |
Definition at line 332 of file dict0dict.c.
References dict_sys, dict_sys_struct::mutex, and mutex_exit().
00334 { 00335 mutex_exit(&(dict_sys->mutex)); 00336 }
Here is the call graph for this function:

| void dict_print_info_on_foreign_key_in_create_format | ( | FILE * | file, | |
| trx_t * | trx, | |||
| dict_foreign_t * | foreign, | |||
| ibool | add_newline | |||
| ) |
Definition at line 4251 of file dict0dict.c.
References DICT_FOREIGN_ON_DELETE_CASCADE, DICT_FOREIGN_ON_DELETE_NO_ACTION, DICT_FOREIGN_ON_DELETE_SET_NULL, DICT_FOREIGN_ON_UPDATE_CASCADE, DICT_FOREIGN_ON_UPDATE_NO_ACTION, DICT_FOREIGN_ON_UPDATE_SET_NULL, dict_get_db_name_len(), dict_remove_db_name(), dict_tables_have_same_db(), FALSE, dict_foreign_struct::foreign_col_names, dict_foreign_struct::foreign_table_name, dict_foreign_struct::id, dict_foreign_struct::referenced_col_names, dict_foreign_struct::referenced_table_name, strchr(), TRUE, dict_foreign_struct::type, ut_print_name(), and ut_print_namel().
Referenced by dict_foreign_error_report(), dict_print_info_on_foreign_keys(), row_ins_foreign_report_add_err(), row_ins_foreign_report_err(), and row_ins_set_detailed().
04253 : file where to print */ 04254 trx_t* trx, /* in: transaction */ 04255 dict_foreign_t* foreign, /* in: foreign key constraint */ 04256 ibool add_newline) /* in: whether to add a newline */ 04257 { 04258 const char* stripped_id; 04259 ulint i; 04260 04261 if (strchr(foreign->id, '/')) { 04262 /* Strip the preceding database name from the constraint id */ 04263 stripped_id = foreign->id + 1 04264 + dict_get_db_name_len(foreign->id); 04265 } else { 04266 stripped_id = foreign->id; 04267 } 04268 04269 putc(',', file); 04270 04271 if (add_newline) { 04272 /* SHOW CREATE TABLE wants constraints each printed nicely 04273 on its own line, while error messages want no newlines 04274 inserted. */ 04275 fputs("\n ", file); 04276 } 04277 04278 fputs(" CONSTRAINT ", file); 04279 ut_print_name(file, trx, FALSE, stripped_id); 04280 fputs(" FOREIGN KEY (", file); 04281 04282 for (i = 0;;) { 04283 ut_print_name(file, trx, FALSE, foreign->foreign_col_names[i]); 04284 if (++i < foreign->n_fields) { 04285 fputs(", ", file); 04286 } else { 04287 break; 04288 } 04289 } 04290 04291 fputs(") REFERENCES ", file); 04292 04293 if (dict_tables_have_same_db(foreign->foreign_table_name, 04294 foreign->referenced_table_name)) { 04295 /* Do not print the database name of the referenced table */ 04296 ut_print_name(file, trx, TRUE, dict_remove_db_name( 04297 foreign->referenced_table_name)); 04298 } else { 04299 /* Look for the '/' in the table name */ 04300 04301 i = 0; 04302 while (foreign->referenced_table_name[i] != '/') { 04303 i++; 04304 } 04305 04306 ut_print_namel(file, trx, TRUE, 04307 foreign->referenced_table_name, i); 04308 putc('.', file); 04309 ut_print_name(file, trx, TRUE, 04310 foreign->referenced_table_name + i + 1); 04311 } 04312 04313 putc(' ', file); 04314 putc('(', file); 04315 04316 for (i = 0;;) { 04317 ut_print_name(file, trx, FALSE, 04318 foreign->referenced_col_names[i]); 04319 if (++i < foreign->n_fields) { 04320 fputs(", ", file); 04321 } else { 04322 break; 04323 } 04324 } 04325 04326 putc(')', file); 04327 04328 if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) { 04329 fputs(" ON DELETE CASCADE", file); 04330 } 04331 04332 if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) { 04333 fputs(" ON DELETE SET NULL", file); 04334 } 04335 04336 if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { 04337 fputs(" ON DELETE NO ACTION", file); 04338 } 04339 04340 if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { 04341 fputs(" ON UPDATE CASCADE", file); 04342 } 04343 04344 if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { 04345 fputs(" ON UPDATE SET NULL", file); 04346 } 04347 04348 if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { 04349 fputs(" ON UPDATE NO ACTION", file); 04350 } 04351 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_print_info_on_foreign_keys | ( | ibool | create_table_format, | |
| FILE * | file, | |||
| trx_t * | trx, | |||
| dict_table_t * | table | |||
| ) |
Definition at line 4357 of file dict0dict.c.
References DICT_FOREIGN_ON_DELETE_CASCADE, DICT_FOREIGN_ON_DELETE_NO_ACTION, DICT_FOREIGN_ON_DELETE_SET_NULL, DICT_FOREIGN_ON_UPDATE_CASCADE, DICT_FOREIGN_ON_UPDATE_NO_ACTION, DICT_FOREIGN_ON_UPDATE_SET_NULL, dict_print_info_on_foreign_key_in_create_format(), dict_sys, FALSE, dict_foreign_struct::foreign_col_names, dict_table_struct::foreign_list, dict_sys_struct::mutex, mutex_enter, mutex_exit(), dict_foreign_struct::n_fields, NULL, dict_foreign_struct::referenced_col_names, dict_foreign_struct::referenced_table_name, TRUE, dict_foreign_struct::type, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, and ut_print_name().
04359 : if TRUE then print in 04360 a format suitable to be inserted into 04361 a CREATE TABLE, otherwise in the format 04362 of SHOW TABLE STATUS */ 04363 FILE* file, /* in: file where to print */ 04364 trx_t* trx, /* in: transaction */ 04365 dict_table_t* table) /* in: table */ 04366 { 04367 dict_foreign_t* foreign; 04368 04369 mutex_enter(&(dict_sys->mutex)); 04370 04371 foreign = UT_LIST_GET_FIRST(table->foreign_list); 04372 04373 if (foreign == NULL) { 04374 mutex_exit(&(dict_sys->mutex)); 04375 04376 return; 04377 } 04378 04379 while (foreign != NULL) { 04380 if (create_table_format) { 04381 dict_print_info_on_foreign_key_in_create_format( 04382 file, trx, foreign, TRUE); 04383 } else { 04384 ulint i; 04385 fputs("; (", file); 04386 04387 for (i = 0; i < foreign->n_fields; i++) { 04388 if (i) { 04389 putc(' ', file); 04390 } 04391 04392 ut_print_name(file, trx, FALSE, 04393 foreign->foreign_col_names[i]); 04394 } 04395 04396 fputs(") REFER ", file); 04397 ut_print_name(file, trx, TRUE, 04398 foreign->referenced_table_name); 04399 putc('(', file); 04400 04401 for (i = 0; i < foreign->n_fields; i++) { 04402 if (i) { 04403 putc(' ', file); 04404 } 04405 ut_print_name(file, trx, FALSE, 04406 foreign->referenced_col_names[i]); 04407 } 04408 04409 putc(')', file); 04410 04411 if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { 04412 fputs(" ON DELETE CASCADE", file); 04413 } 04414 04415 if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { 04416 fputs(" ON DELETE SET NULL", file); 04417 } 04418 04419 if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { 04420 fputs(" ON DELETE NO ACTION", file); 04421 } 04422 04423 if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { 04424 fputs(" ON UPDATE CASCADE", file); 04425 } 04426 04427 if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { 04428 fputs(" ON UPDATE SET NULL", file); 04429 } 04430 04431 if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { 04432 fputs(" ON UPDATE NO ACTION", file); 04433 } 04434 } 04435 04436 foreign = UT_LIST_GET_NEXT(foreign_list, foreign); 04437 } 04438 04439 mutex_exit(&(dict_sys->mutex)); 04440 }
Here is the call graph for this function:

| const char* dict_remove_db_name | ( | const char * | name | ) |
Definition at line 290 of file dict0dict.c.
References strchr(), and ut_a.
Referenced by dict_foreign_parse_drop_constraints(), dict_print_info_on_foreign_key_in_create_format(), and dict_table_rename_in_cache().
00292 : table name */ 00293 const char* name) /* in: table name in the form 00294 dbname '/' tablename */ 00295 { 00296 const char* s = strchr(name, '/'); 00297 ut_a(s); 00298 00299 return(s + 1); 00300 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static const char* dict_scan_col | ( | struct charset_info_st * | cs, | |
| const char * | ptr, | |||
| ibool * | success, | |||
| dict_table_t * | table, | |||
| dict_col_t ** | column, | |||
| mem_heap_t * | heap, | |||
| const char ** | name | |||
| ) | [static] |
Definition at line 2538 of file dict0dict.c.
References dict_scan_id(), dict_table_get_n_cols(), dict_table_get_nth_col(), FALSE, innobase_strcasecmp(), dict_col_struct::name, NULL, and TRUE.
Referenced by dict_create_foreign_constraints_low().
02540 : scanned to */ 02541 struct charset_info_st* cs,/* in: the character set of ptr */ 02542 const char* ptr, /* in: scanned to */ 02543 ibool* success,/* out: TRUE if success */ 02544 dict_table_t* table, /* in: table in which the column is */ 02545 dict_col_t** column, /* out: pointer to column if success */ 02546 mem_heap_t* heap, /* in: heap where to allocate the name */ 02547 const char** name) /* out,own: the column name; NULL if no name 02548 was scannable */ 02549 { 02550 dict_col_t* col; 02551 ulint i; 02552 02553 *success = FALSE; 02554 02555 ptr = dict_scan_id(cs, ptr, heap, name, FALSE, TRUE); 02556 02557 if (*name == NULL) { 02558 02559 return(ptr); /* Syntax error */ 02560 } 02561 02562 if (table == NULL) { 02563 *success = TRUE; 02564 *column = NULL; 02565 } else { 02566 for (i = 0; i < dict_table_get_n_cols(table); i++) { 02567 02568 col = dict_table_get_nth_col(table, i); 02569 02570 if (0 == innobase_strcasecmp(col->name, *name)) { 02571 /* Found */ 02572 02573 *success = TRUE; 02574 *column = col; 02575 strcpy((char*) *name, col->name); 02576 02577 break; 02578 } 02579 } 02580 } 02581 02582 return(ptr); 02583 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static const char* dict_scan_id | ( | struct charset_info_st * | cs, | |
| const char * | ptr, | |||
| mem_heap_t * | heap, | |||
| const char ** | id, | |||
| ibool | table_id, | |||
| ibool | accept_also_dot | |||
| ) | [static] |
Definition at line 2419 of file dict0dict.c.
References innobase_convert_from_id(), innobase_convert_from_table_id(), mem_heap_alloc(), mem_heap_strdupl(), my_isspace, NULL, srv_mysql50_table_name_prefix, and ut_ad.
Referenced by dict_create_foreign_constraints_low(), dict_foreign_parse_drop_constraints(), dict_scan_col(), dict_scan_table_name(), and dict_skip_word().
02421 : scanned to */ 02422 struct charset_info_st* cs,/* in: the character set of ptr */ 02423 const char* ptr, /* in: scanned to */ 02424 mem_heap_t* heap, /* in: heap where to allocate the id 02425 (NULL=id will not be allocated, but it 02426 will point to string near ptr) */ 02427 const char** id, /* out,own: the id; NULL if no id was 02428 scannable */ 02429 ibool table_id,/* in: TRUE=convert the allocated id 02430 as a table name; FALSE=convert to UTF-8 */ 02431 ibool accept_also_dot) 02432 /* in: TRUE if also a dot can appear in a 02433 non-quoted id; in a quoted id it can appear 02434 always */ 02435 { 02436 char quote = '\0'; 02437 ulint len = 0; 02438 const char* s; 02439 char* str; 02440 char* dst; 02441 02442 *id = NULL; 02443 02444 while (my_isspace(cs, *ptr)) { 02445 ptr++; 02446 } 02447 02448 if (*ptr == '\0') { 02449 02450 return(ptr); 02451 } 02452 02453 if (*ptr == '`' || *ptr == '"') { 02454 quote = *ptr++; 02455 } 02456 02457 s = ptr; 02458 02459 if (quote) { 02460 for (;;) { 02461 if (!*ptr) { 02462 /* Syntax error */ 02463 return(ptr); 02464 } 02465 if (*ptr == quote) { 02466 ptr++; 02467 if (*ptr != quote) { 02468 break; 02469 } 02470 } 02471 ptr++; 02472 len++; 02473 } 02474 } else { 02475 while (!my_isspace(cs, *ptr) && *ptr != '(' && *ptr != ')' 02476 && (accept_also_dot || *ptr != '.') 02477 && *ptr != ',' && *ptr != '\0') { 02478 02479 ptr++; 02480 } 02481 02482 len = ptr - s; 02483 } 02484 02485 if (UNIV_UNLIKELY(!heap)) { 02486 /* no heap given: id will point to source string */ 02487 *id = s; 02488 return(ptr); 02489 } 02490 02491 if (quote) { 02492 char* d; 02493 str = d = mem_heap_alloc(heap, len + 1); 02494 while (len--) { 02495 if ((*d++ = *s++) == quote) { 02496 s++; 02497 } 02498 } 02499 *d++ = 0; 02500 len = d - str; 02501 ut_ad(*s == quote); 02502 ut_ad(s + 1 == ptr); 02503 } else { 02504 str = mem_heap_strdupl(heap, s, len); 02505 } 02506 02507 if (!table_id) { 02508 convert_id: 02509 /* Convert the identifier from connection character set 02510 to UTF-8. */ 02511 len = 3 * len + 1; 02512 *id = dst = mem_heap_alloc(heap, len); 02513 02514 innobase_convert_from_id(dst, str, len); 02515 } else if (!strncmp(str, srv_mysql50_table_name_prefix, 02516 sizeof srv_mysql50_table_name_prefix)) { 02517 /* This is a pre-5.1 table name 02518 containing chars other than [A-Za-z0-9]. 02519 Discard the prefix and use raw UTF-8 encoding. */ 02520 str += sizeof srv_mysql50_table_name_prefix; 02521 len -= sizeof srv_mysql50_table_name_prefix; 02522 goto convert_id; 02523 } else { 02524 /* Encode using filename-safe characters. */ 02525 len = 5 * len + 1; 02526 *id = dst = mem_heap_alloc(heap, len); 02527 02528 innobase_convert_from_table_id(dst, str, len); 02529 } 02530 02531 return(ptr); 02532 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static const char* dict_scan_table_name | ( | struct charset_info_st * | cs, | |
| const char * | ptr, | |||
| dict_table_t ** | table, | |||
| const char * | name, | |||
| ibool * | success, | |||
| mem_heap_t * | heap, | |||
| const char ** | ref_name | |||
| ) | [static] |
Definition at line 2589 of file dict0dict.c.
References dict_get_db_name_len(), dict_scan_id(), dict_table_get_low(), FALSE, innobase_casedn_str(), mem_heap_alloc(), memcpy, NULL, srv_lower_case_table_names, strlen(), and TRUE.
Referenced by dict_create_foreign_constraints_low().
02591 : scanned to */ 02592 struct charset_info_st* cs,/* in: the character set of ptr */ 02593 const char* ptr, /* in: scanned to */ 02594 dict_table_t** table, /* out: table object or NULL */ 02595 const char* name, /* in: foreign key table name */ 02596 ibool* success,/* out: TRUE if ok name found */ 02597 mem_heap_t* heap, /* in: heap where to allocate the id */ 02598 const char** ref_name)/* out,own: the table name; 02599 NULL if no name was scannable */ 02600 { 02601 const char* database_name = NULL; 02602 ulint database_name_len = 0; 02603 const char* table_name = NULL; 02604 ulint table_name_len; 02605 const char* scan_name; 02606 char* ref; 02607 02608 *success = FALSE; 02609 *table = NULL; 02610 02611 ptr = dict_scan_id(cs, ptr, heap, &scan_name, TRUE, FALSE); 02612 02613 if (scan_name == NULL) { 02614 02615 return(ptr); /* Syntax error */ 02616 } 02617 02618 if (*ptr == '.') { 02619 /* We scanned the database name; scan also the table name */ 02620 02621 ptr++; 02622 02623 database_name = scan_name; 02624 database_name_len = strlen(database_name); 02625 02626 ptr = dict_scan_id(cs, ptr, heap, &table_name, TRUE, FALSE); 02627 02628 if (table_name == NULL) { 02629 02630 return(ptr); /* Syntax error */ 02631 } 02632 } else { 02633 /* To be able to read table dumps made with InnoDB-4.0.17 or 02634 earlier, we must allow the dot separator between the database 02635 name and the table name also to appear within a quoted 02636 identifier! InnoDB used to print a constraint as: 02637 ... REFERENCES `databasename.tablename` ... 02638 starting from 4.0.18 it is 02639 ... REFERENCES `databasename`.`tablename` ... */ 02640 const char* s; 02641 02642 for (s = scan_name; *s; s++) { 02643 if (*s == '.') { 02644 database_name = scan_name; 02645 database_name_len = s - scan_name; 02646 scan_name = ++s; 02647 break;/* to do: multiple dots? */ 02648 } 02649 } 02650 02651 table_name = scan_name; 02652 } 02653 02654 if (database_name == NULL) { 02655 /* Use the database name of the foreign key table */ 02656 02657 database_name = name; 02658 database_name_len = dict_get_db_name_len(name); 02659 } 02660 02661 table_name_len = strlen(table_name); 02662 02663 /* Copy database_name, '/', table_name, '\0' */ 02664 ref = mem_heap_alloc(heap, database_name_len + table_name_len + 2); 02665 memcpy(ref, database_name, database_name_len); 02666 ref[database_name_len] = '/'; 02667 memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); 02668 #ifndef __WIN__ 02669 if (srv_lower_case_table_names) { 02670 #endif /* !__WIN__ */ 02671 /* The table name is always put to lower case on Windows. */ 02672 innobase_casedn_str(ref); 02673 #ifndef __WIN__ 02674 } 02675 #endif /* !__WIN__ */ 02676 02677 *success = TRUE; 02678 *ref_name = ref; 02679 *table = dict_table_get_low(ref); 02680 02681 return(ptr); 02682 }
Here is the call graph for this function:

Here is the caller graph for this function:

| const char* dict_scan_to | ( | const char * | ptr, | |
| const char * | string | |||
| ) |
Definition at line 2341 of file dict0dict.c.
Referenced by dict_accept(), dict_create_foreign_constraints_low(), and dict_foreign_parse_drop_constraints().
02343 : scanned up to this */ 02344 const char* ptr, /* in: scan from */ 02345 const char* string) /* in: look for this */ 02346 { 02347 char quote = '\0'; 02348 02349 for (; *ptr; ptr++) { 02350 if (*ptr == quote) { 02351 /* Closing quote character: do not look for 02352 starting quote or the keyword. */ 02353 quote = '\0'; 02354 } else if (quote) { 02355 /* Within quotes: do nothing. */ 02356 } else if (*ptr == '`' || *ptr == '"') { 02357 /* Starting quote: remember the quote character. */ 02358 quote = *ptr; 02359 } else { 02360 /* Outside quotes: look for the keyword. */ 02361 ulint i; 02362 for (i = 0; string[i]; i++) { 02363 if (toupper((int)(unsigned char)(ptr[i])) 02364 != toupper((int)(unsigned char) 02365 (string[i]))) { 02366 goto nomatch; 02367 } 02368 } 02369 break; 02370 nomatch: 02371 ; 02372 } 02373 } 02374 02375 return(ptr); 02376 }
Here is the caller graph for this function:

| static const char* dict_skip_word | ( | struct charset_info_st * | cs, | |
| const char * | ptr, | |||
| ibool * | success | |||
| ) | [static] |
Definition at line 2688 of file dict0dict.c.
References dict_scan_id(), FALSE, NULL, start(), and TRUE.
Referenced by dict_create_foreign_constraints_low().
02690 : scanned to */ 02691 struct charset_info_st* cs,/* in: the character set of ptr */ 02692 const char* ptr, /* in: scanned to */ 02693 ibool* success)/* out: TRUE if success, FALSE if just spaces 02694 left in string or a syntax error */ 02695 { 02696 const char* start; 02697 02698 *success = FALSE; 02699 02700 ptr = dict_scan_id(cs, ptr, NULL, &start, FALSE, TRUE); 02701 02702 if (start) { 02703 *success = TRUE; 02704 } 02705 02706 return(ptr); 02707 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool dict_str_starts_with_keyword | ( | void * | mysql_thd, | |
| const char * | str, | |||
| const char * | keyword | |||
| ) |
Definition at line 3432 of file dict0dict.c.
References dict_accept(), and innobase_get_charset().
Referenced by row_search_for_mysql().
03434 : TRUE if str starts 03435 with keyword */ 03436 void* mysql_thd, /* in: MySQL thread handle */ 03437 const char* str, /* in: string to scan for keyword */ 03438 const char* keyword) /* in: keyword to look for */ 03439 { 03440 struct charset_info_st* cs = innobase_get_charset(mysql_thd); 03441 ibool success; 03442 03443 dict_accept(cs, str, keyword, &success); 03444 return(success); 03445 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static char* dict_strip_comments | ( | const char * | sql_string | ) | [static] |
Definition at line 2717 of file dict0dict.c.
References mem_alloc, strlen(), and ut_a.
Referenced by dict_create_foreign_constraints(), and dict_foreign_parse_drop_constraints().
02719 : SQL string stripped from 02720 comments; the caller must free this 02721 with mem_free()! */ 02722 const char* sql_string) /* in: SQL string */ 02723 { 02724 char* str; 02725 const char* sptr; 02726 char* ptr; 02727 /* unclosed quote character (0 if none) */ 02728 char quote = 0; 02729 02730 str = mem_alloc(strlen(sql_string) + 1); 02731 02732 sptr = sql_string; 02733 ptr = str; 02734 02735 for (;;) { 02736 scan_more: 02737 if (*sptr == '\0') { 02738 *ptr = '\0'; 02739 02740 ut_a(ptr <= str + strlen(sql_string)); 02741 02742 return(str); 02743 } 02744 02745 if (*sptr == quote) { 02746 /* Closing quote character: do not look for 02747 starting quote or comments. */ 02748 quote = 0; 02749 } else if (quote) { 02750 /* Within quotes: do not look for 02751 starting quotes or comments. */ 02752 } else if (*sptr == '"' || *sptr == '`') { 02753 /* Starting quote: remember the quote character. */ 02754 quote = *sptr; 02755 } else if (*sptr == '#' 02756 || (sptr[0] == '-' && sptr[1] == '-' && 02757 sptr[2] == ' ')) { 02758 for (;;) { 02759 /* In Unix a newline is 0x0A while in Windows 02760 it is 0x0D followed by 0x0A */ 02761 02762 if (*sptr == (char)0x0A 02763 || *sptr == (char)0x0D 02764 || *sptr == '\0') { 02765 02766 goto scan_more; 02767 } 02768 02769 sptr++; 02770 } 02771 } else if (!quote && *sptr == '/' && *(sptr + 1) == '*') { 02772 for (;;) { 02773 if (*sptr == '*' && *(sptr + 1) == '/') { 02774 02775 sptr += 2; 02776 02777 goto scan_more; 02778 } 02779 02780 if (*sptr == '\0') { 02781 02782 goto scan_more; 02783 } 02784 02785 sptr++; 02786 } 02787 } 02788 02789 *ptr = *sptr; 02790 02791 ptr++; 02792 sptr++; 02793 } 02794 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_table_add_to_cache | ( | dict_table_t * | table | ) |
Definition at line 857 of file dict0dict.c.
References dict_table_struct::cached, DATA_MIX_ID, DATA_MIX_ID_LEN, DATA_N_SYS_COLS, DATA_NOT_NULL, DATA_ROLL_PTR, DATA_ROLL_PTR_LEN, DATA_ROW_ID, DATA_ROW_ID_LEN, DATA_SYS, DATA_TRX_ID, DATA_TRX_ID_LEN, dict_col_add_to_cache(), dict_col_get_type(), dict_mem_table_add_col(), dict_sys, dict_table_get_nth_col(), DICT_TABLE_MAGIC_N, dtype_get_max_size(), FALSE, HASH_INSERT, HASH_SEARCH, dict_table_struct::heap, dict_table_struct::id, dict_table_struct::magic_n, dict_table_struct::max_row_size, mem_heap_get_size(), dict_sys_struct::mutex, dict_table_struct::n_cols, dict_table_struct::n_def, dict_table_struct::name, NULL, dict_sys_struct::size, table2, dict_sys_struct::table_hash, dict_sys_struct::table_id_hash, dict_sys_struct::table_LRU, TRUE, ut_a, ut_ad, ut_dulint_cmp(), ut_fold_dulint(), ut_fold_string(), UT_LIST_ADD_FIRST, ut_max(), and ut_strcmp().
Referenced by dict_boot(), dict_create_table_step(), dict_load_table(), and ibuf_data_init_for_space().
00859 : table */ 00860 { 00861 ulint fold; 00862 ulint id_fold; 00863 ulint i; 00864 ulint row_len; 00865 00866 ut_ad(table); 00867 #ifdef UNIV_SYNC_DEBUG 00868 ut_ad(mutex_own(&(dict_sys->mutex))); 00869 #endif /* UNIV_SYNC_DEBUG */ 00870 ut_ad(table->n_def == table->n_cols - DATA_N_SYS_COLS); 00871 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 00872 ut_ad(table->cached == FALSE); 00873 00874 fold = ut_fold_string(table->name); 00875 id_fold = ut_fold_dulint(table->id); 00876 00877 table->cached = TRUE; 00878 00879 /* NOTE: the system columns MUST be added in the following order 00880 (so that they can be indexed by the numerical value of DATA_ROW_ID, 00881 etc.) and as the last columns of the table memory object. 00882 The clustered index will not always physically contain all 00883 system columns. */ 00884 00885 dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS, 00886 DATA_ROW_ID | DATA_NOT_NULL, DATA_ROW_ID_LEN, 0); 00887 #if DATA_ROW_ID != 0 00888 #error "DATA_ROW_ID != 0" 00889 #endif 00890 dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS, 00891 DATA_TRX_ID | DATA_NOT_NULL, DATA_TRX_ID_LEN, 0); 00892 #if DATA_TRX_ID != 1 00893 #error "DATA_TRX_ID != 1" 00894 #endif 00895 dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS, 00896 DATA_ROLL_PTR | DATA_NOT_NULL, DATA_ROLL_PTR_LEN, 0); 00897 #if DATA_ROLL_PTR != 2 00898 #error "DATA_ROLL_PTR != 2" 00899 #endif 00900 dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS, 00901 DATA_MIX_ID | DATA_NOT_NULL, DATA_MIX_ID_LEN, 0); 00902 #if DATA_MIX_ID != 3 00903 #error "DATA_MIX_ID != 3" 00904 #endif 00905 00906 /* This check reminds that if a new system column is added to 00907 the program, it should be dealt with here */ 00908 #if DATA_N_SYS_COLS != 4 00909 #error "DATA_N_SYS_COLS != 4" 00910 #endif 00911 00912 row_len = 0; 00913 for (i = 0; i < table->n_def; i++) { 00914 ulint col_len = dtype_get_max_size( 00915 dict_col_get_type(dict_table_get_nth_col(table, i))); 00916 00917 /* If we have a single unbounded field, or several gigantic 00918 fields, mark the maximum row size as ULINT_MAX. */ 00919 if (ut_max(col_len, row_len) >= (ULINT_MAX / 2)) { 00920 row_len = ULINT_MAX; 00921 00922 break; 00923 } 00924 00925 row_len += col_len; 00926 } 00927 00928 table->max_row_size = row_len; 00929 00930 /* Look for a table with the same name: error if such exists */ 00931 { 00932 dict_table_t* table2; 00933 HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2, 00934 (ut_strcmp(table2->name, table->name) == 0)); 00935 ut_a(table2 == NULL); 00936 } 00937 00938 /* Look for a table with the same id: error if such exists */ 00939 { 00940 dict_table_t* table2; 00941 HASH_SEARCH(id_hash, dict_sys->table_id_hash, id_fold, table2, 00942 (ut_dulint_cmp(table2->id, table->id) == 0)); 00943 ut_a(table2 == NULL); 00944 } 00945 00946 /* Add the columns to the column hash table */ 00947 for (i = 0; i < table->n_cols; i++) { 00948 dict_col_add_to_cache(table, dict_table_get_nth_col(table, i)); 00949 } 00950 00951 /* Add table to hash table of tables */ 00952 HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, 00953 table); 00954 00955 /* Add table to hash table of tables based on table id */ 00956 HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, id_fold, 00957 table); 00958 /* Add table to LRU list of tables */ 00959 UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); 00960 00961 dict_sys->size += mem_heap_get_size(table->heap); 00962 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_table_autoinc_decrement | ( | dict_table_t * | table | ) |
Definition at line 454 of file dict0dict.c.
References dict_table_struct::autoinc, dict_table_struct::autoinc_mutex, mutex_enter, and mutex_exit().
00456 : table */ 00457 { 00458 mutex_enter(&(table->autoinc_mutex)); 00459 00460 table->autoinc = table->autoinc - 1; 00461 00462 mutex_exit(&(table->autoinc_mutex)); 00463 }
Here is the call graph for this function:

| ib_longlong dict_table_autoinc_get | ( | dict_table_t * | table | ) |
Definition at line 428 of file dict0dict.c.
References dict_table_struct::autoinc, dict_table_struct::autoinc_inited, dict_table_struct::autoinc_mutex, mutex_enter, mutex_exit(), and value.
00430 : value for a new row, or 0 */ 00431 dict_table_t* table) /* in: table */ 00432 { 00433 ib_longlong value; 00434 00435 mutex_enter(&(table->autoinc_mutex)); 00436 00437 if (!table->autoinc_inited) { 00438 00439 value = 0; 00440 } else { 00441 value = table->autoinc; 00442 table->autoinc = table->autoinc + 1; 00443 } 00444 00445 mutex_exit(&(table->autoinc_mutex)); 00446 00447 return(value); 00448 }
Here is the call graph for this function:

| void dict_table_autoinc_initialize | ( | dict_table_t * | table, | |
| ib_longlong | value | |||
| ) |
Definition at line 410 of file dict0dict.c.
References dict_table_struct::autoinc, dict_table_struct::autoinc_inited, dict_table_struct::autoinc_mutex, mutex_enter, mutex_exit(), and TRUE.
Referenced by row_truncate_table_for_mysql().
00412 : table */ 00413 ib_longlong value) /* in: next value to assign to a row */ 00414 { 00415 mutex_enter(&(table->autoinc_mutex)); 00416 00417 table->autoinc_inited = TRUE; 00418 table->autoinc = value; 00419 00420 mutex_exit(&(table->autoinc_mutex)); 00421 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ib_longlong dict_table_autoinc_peek | ( | dict_table_t * | table | ) |
Definition at line 496 of file dict0dict.c.
References dict_table_struct::autoinc, dict_table_struct::autoinc_inited, and value.
00498 : value of the counter */ 00499 dict_table_t* table) /* in: table */ 00500 { 00501 ib_longlong value; 00502 00503 if (!table->autoinc_inited) { 00504 00505 value = 0; 00506 } else { 00507 value = table->autoinc; 00508 } 00509 00510 return(value); 00511 }
| ib_longlong dict_table_autoinc_read | ( | dict_table_t * | table | ) |
Definition at line 470 of file dict0dict.c.
References dict_table_struct::autoinc, dict_table_struct::autoinc_inited, dict_table_struct::autoinc_mutex, mutex_enter, mutex_exit(), and value.
00472 : value for a new row, or 0 */ 00473 dict_table_t* table) /* in: table */ 00474 { 00475 ib_longlong value; 00476 00477 mutex_enter(&(table->autoinc_mutex)); 00478 00479 if (!table->autoinc_inited) { 00480 00481 value = 0; 00482 } else { 00483 value = table->autoinc; 00484 } 00485 00486 mutex_exit(&(table->autoinc_mutex)); 00487 00488 return(value); 00489 }
Here is the call graph for this function:

| void dict_table_autoinc_update | ( | dict_table_t * | table, | |
| ib_longlong | value | |||
| ) |
Definition at line 518 of file dict0dict.c.
References dict_table_struct::autoinc, dict_table_struct::autoinc_inited, dict_table_struct::autoinc_mutex, mutex_enter, and mutex_exit().
00521 : table */ 00522 ib_longlong value) /* in: value which was assigned to a row */ 00523 { 00524 mutex_enter(&(table->autoinc_mutex)); 00525 00526 if (table->autoinc_inited) { 00527 if (value >= table->autoinc) { 00528 table->autoinc = value + 1; 00529 } 00530 } 00531 00532 mutex_exit(&(table->autoinc_mutex)); 00533 }
Here is the call graph for this function:

| void dict_table_change_id_in_cache | ( | dict_table_t * | table, | |
| dulint | new_id | |||
| ) |
Definition at line 1228 of file dict0dict.c.
References dict_sys, DICT_TABLE_MAGIC_N, HASH_DELETE, HASH_INSERT, dict_table_struct::id, dict_table_struct::magic_n, dict_sys_struct::mutex, dict_sys_struct::table_id_hash, ut_ad, and ut_fold_dulint().
Referenced by row_discard_tablespace_for_mysql(), and row_truncate_table_for_mysql().
01230 : table object already in cache */ 01231 dulint new_id) /* in: new id to set */ 01232 { 01233 ut_ad(table); 01234 #ifdef UNIV_SYNC_DEBUG 01235 ut_ad(mutex_own(&(dict_sys->mutex))); 01236 #endif /* UNIV_SYNC_DEBUG */ 01237 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01238 01239 /* Remove the table from the hash table of id's */ 01240 01241 HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash, 01242 ut_fold_dulint(table->id), table); 01243 table->id = new_id; 01244 01245 /* Add the table back to the hash table */ 01246 HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, 01247 ut_fold_dulint(table->id), table); 01248 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool dict_table_col_in_clustered_key | ( | dict_table_t * | table, | |
| ulint | n | |||
| ) |
Definition at line 727 of file dict0dict.c.
References dict_field_struct::col, dict_index_get_n_unique(), dict_index_get_nth_field(), dict_table_get_first_index(), dict_table_get_nth_col(), index(), pos(), TRUE, and ut_ad.
00729 : TRUE if the column, or its prefix, is 00730 in the clustered key */ 00731 dict_table_t* table, /* in: table */ 00732 ulint n) /* in: column number */ 00733 { 00734 dict_index_t* index; 00735 dict_field_t* field; 00736 dict_col_t* col; 00737 ulint pos; 00738 ulint n_fields; 00739 00740 ut_ad(table); 00741 00742 col = dict_table_get_nth_col(table, n); 00743 00744 index = dict_table_get_first_index(table); 00745 00746 n_fields = dict_index_get_n_unique(index); 00747 00748 for (pos = 0; pos < n_fields; pos++) { 00749 field = dict_index_get_nth_field(index, pos); 00750 00751 if (col == field->col) { 00752 00753 return(TRUE); 00754 } 00755 } 00756 00757 return(FALSE); 00758 }
Here is the call graph for this function:

| void dict_table_copy_types | ( | dtuple_t * | tuple, | |
| dict_table_t * | table | |||
| ) |
Definition at line 1742 of file dict0dict.c.
References dfield_get_type(), dict_col_get_type(), dict_table_get_nth_col(), dtuple_get_n_fields(), and dtuple_get_nth_field().
Referenced by dict_create_sys_columns_tuple(), dict_create_sys_fields_tuple(), dict_create_sys_indexes_tuple(), dict_create_sys_tables_tuple(), pars_insert_statement(), row_build(), row_get_prebuilt_insert_row(), and trx_undo_rec_get_partial_row().
01744 : data tuple */ 01745 dict_table_t* table) /* in: index */ 01746 { 01747 dtype_t* dfield_type; 01748 dtype_t* type; 01749 ulint i; 01750 01751 for (i = 0; i < dtuple_get_n_fields(tuple); i++) { 01752 01753 dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i)); 01754 type = dict_col_get_type(dict_table_get_nth_col(table, i)); 01755 01756 *dfield_type = *type; 01757 } 01758 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_table_decrement_handle_count | ( | dict_table_t * | table | ) |
Definition at line 342 of file dict0dict.c.
References dict_sys, dict_sys_struct::mutex, mutex_enter, mutex_exit(), dict_table_struct::n_mysql_handles_opened, and ut_a.
00344 : table */ 00345 { 00346 mutex_enter(&(dict_sys->mutex)); 00347 00348 ut_a(table->n_mysql_handles_opened > 0); 00349 00350 table->n_mysql_handles_opened--; 00351 00352 mutex_exit(&(dict_sys->mutex)); 00353 }
Here is the call graph for this function:

| dict_table_t* dict_table_get | ( | const char * | table_name | ) |
Definition at line 798 of file dict0dict.c.
References dict_sys, dict_table_get_low(), dict_update_statistics(), dict_sys_struct::mutex, mutex_enter, mutex_exit(), NULL, and dict_table_struct::stat_initialized.
Referenced by row_ins_check_foreign_constraints(), row_search_check_if_query_cache_permitted(), and row_upd_check_references_constraints().
00800 : table, NULL if 00801 does not exist */ 00802 const char* table_name) /* in: table name */ 00803 { 00804 dict_table_t* table; 00805 00806 mutex_enter(&(dict_sys->mutex)); 00807 00808 table = dict_table_get_low(table_name); 00809 00810 mutex_exit(&(dict_sys->mutex)); 00811 00812 if (table != NULL) { 00813 if (!table->stat_initialized) { 00814 dict_update_statistics(table); 00815 } 00816 } 00817 00818 return(table); 00819 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dict_table_t* dict_table_get_and_increment_handle_count | ( | const char * | table_name | ) |
Definition at line 825 of file dict0dict.c.
References dict_sys, dict_table_get_low(), dict_update_statistics(), dict_table_struct::ibd_file_missing, dict_sys_struct::mutex, mutex_enter, mutex_exit(), dict_table_struct::n_mysql_handles_opened, NULL, and dict_table_struct::stat_initialized.
00827 : table, NULL if 00828 does not exist */ 00829 const char* table_name) /* in: table name */ 00830 { 00831 dict_table_t* table; 00832 00833 mutex_enter(&(dict_sys->mutex)); 00834 00835 table = dict_table_get_low(table_name); 00836 00837 if (table != NULL) { 00838 00839 table->n_mysql_handles_opened++; 00840 } 00841 00842 mutex_exit(&(dict_sys->mutex)); 00843 00844 if (table != NULL) { 00845 if (!table->stat_initialized && !table->ibd_file_missing) { 00846 dict_update_statistics(table); 00847 } 00848 } 00849 00850 return(table); 00851 }
Here is the call graph for this function:

| dict_index_t* dict_table_get_first_index_noninline | ( | dict_table_t * | table | ) |
Definition at line 372 of file dict0dict.c.
References dict_table_get_first_index().
00374 : index, NULL if none exists */ 00375 dict_table_t* table) /* in: table */ 00376 { 00377 return(dict_table_get_first_index(table)); 00378 }
Here is the call graph for this function:

| static ulint dict_table_get_highest_foreign_id | ( | dict_table_t * | table | ) | [static] |
Definition at line 2802 of file dict0dict.c.
References dict_ibfk, dict_table_struct::foreign_list, dict_foreign_struct::id, id, dict_table_struct::name, strtoul(), ut_a, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, ut_memcmp(), and ut_strlen().
Referenced by dict_create_foreign_constraints_low().
02804 : highest number, 0 if table has no new 02805 format foreign key constraints */ 02806 dict_table_t* table) /* in: table in the dictionary memory cache */ 02807 { 02808 dict_foreign_t* foreign; 02809 char* endp; 02810 ulint biggest_id = 0; 02811 ulint id; 02812 ulint len; 02813 02814 ut_a(table); 02815 02816 len = ut_strlen(table->name); 02817 foreign = UT_LIST_GET_FIRST(table->foreign_list); 02818 02819 while (foreign) { 02820 if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len 02821 && 0 == ut_memcmp(foreign->id, table->name, len) 02822 && 0 == ut_memcmp(foreign->id + len, 02823 dict_ibfk, (sizeof dict_ibfk) - 1) 02824 && foreign->id[len + ((sizeof dict_ibfk) - 1)] != '0') { 02825 /* It is of the >= 4.0.18 format */ 02826 02827 id = strtoul(foreign->id + len + ((sizeof dict_ibfk) - 1), 02828 &endp, 10); 02829 if (*endp == '\0') { 02830 ut_a(id != biggest_id); 02831 02832 if (id > biggest_id) { 02833 biggest_id = id; 02834 } 02835 } 02836 } 02837 02838 foreign = UT_LIST_GET_NEXT(foreign_list, foreign); 02839 } 02840 02841 return(biggest_id); 02842 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dict_index_t* dict_table_get_index_noninline | ( | dict_table_t * | table, | |
| const char * | name | |||
| ) |
Definition at line 396 of file dict0dict.c.
References dict_table_get_index().
00398 : index, NULL if does not exist */ 00399 dict_table_t* table, /* in: table */ 00400 const char* name) /* in: index name */ 00401 { 00402 return(dict_table_get_index(table, name)); 00403 }
Here is the call graph for this function:

| dict_table_t* dict_table_get_low_noninlined | ( | const char * | table_name | ) |
Definition at line 4022 of file dict0dict.c.
References dict_table_get_low().
04024 : table, NULL if not found */ 04025 const char* table_name) /* in: table name */ 04026 { 04027 return(dict_table_get_low(table_name)); 04028 }
Here is the call graph for this function:

| dict_index_t* dict_table_get_next_index_noninline | ( | dict_index_t * | index | ) |
Definition at line 384 of file dict0dict.c.
References dict_table_get_next_index(), and index().
00386 : index, NULL if none left */ 00387 dict_index_t* index) /* in: index */ 00388 { 00389 return(dict_table_get_next_index(index)); 00390 }
Here is the call graph for this function:

| dict_col_t* dict_table_get_nth_col_noninline | ( | dict_table_t * | table, | |
| ulint | pos | |||
| ) |
Definition at line 359 of file dict0dict.c.
References dict_table_get_nth_col().
00361 : pointer to column object */ 00362 dict_table_t* table, /* in: table */ 00363 ulint pos) /* in: position of column */ 00364 { 00365 return(dict_table_get_nth_col(table, pos)); 00366 }
Here is the call graph for this function:

| ulint dict_table_get_nth_col_pos | ( | dict_table_t * | table, | |
| ulint | n | |||
| ) |
Definition at line 698 of file dict0dict.c.
References dict_index_get_nth_col_pos(), and dict_table_get_first_index().
Referenced by row_ins_cascade_calc_update_vec(), and row_ins_foreign_check_on_constraint().
00700 : position in internal representation 00701 of the clustered index */ 00702 dict_table_t* table, /* in: table */ 00703 ulint n) /* in: column number */ 00704 { 00705 return(dict_index_get_nth_col_pos(dict_table_get_first_index(table), 00706 n)); 00707 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dict_table_t* dict_table_get_on_id | ( | dulint | table_id, | |
| trx_t * | trx | |||
| ) |
Definition at line 663 of file dict0dict.c.
References DICT_FIELDS_ID, trx_struct::dict_operation_lock_mode, dict_sys, dict_table_get_on_id_low(), dict_sys_struct::mutex, mutex_enter, mutex_exit(), RW_X_LATCH, ut_ad, and ut_dulint_cmp().
Referenced by row_undo_ins_parse_undo_rec(), and row_undo_mod_parse_undo_rec().
00665 : table, NULL if does not exist */ 00666 dulint table_id, /* in: table id */ 00667 trx_t* trx) /* in: transaction handle */ 00668 { 00669 dict_table_t* table; 00670 00671 if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 00672 || trx->dict_operation_lock_mode == RW_X_LATCH) { 00673 /* It is a system table which will always exist in the table 00674 cache: we avoid acquiring the dictionary mutex, because 00675 if we are doing a rollback to handle an error in TABLE 00676 CREATE, for example, we already have the mutex! */ 00677 00678 #ifdef UNIV_SYNC_DEBUG 00679 ut_ad(mutex_own(&(dict_sys->mutex))); 00680 #endif /* UNIV_SYNC_DEBUG */ 00681 00682 return(dict_table_get_on_id_low(table_id)); 00683 } 00684 00685 mutex_enter(&(dict_sys->mutex)); 00686 00687 table = dict_table_get_on_id_low(table_id); 00688 00689 mutex_exit(&(dict_sys->mutex)); 00690 00691 return(table); 00692 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool dict_table_is_comp_noninline | ( | const dict_table_t * | table | ) |
Definition at line 713 of file dict0dict.c.
References dict_table_is_comp().
00715 : TRUE if table uses the 00716 compact page format */ 00717 const dict_table_t* table) /* in: table */ 00718 { 00719 return(dict_table_is_comp(table)); 00720 }
Here is the call graph for this function:

| void dict_table_print | ( | dict_table_t * | table | ) |
Definition at line 4066 of file dict0dict.c.
References dict_sys, dict_table_print_low(), dict_sys_struct::mutex, mutex_enter, and mutex_exit().
04068 : table */ 04069 { 04070 mutex_enter(&(dict_sys->mutex)); 04071 dict_table_print_low(table); 04072 mutex_exit(&(dict_sys->mutex)); 04073 }
Here is the call graph for this function:

| void dict_table_print_by_name | ( | const char * | name | ) |
Definition at line 4079 of file dict0dict.c.
References dict_sys, dict_table_get_low(), dict_table_print_low(), dict_sys_struct::mutex, mutex_enter, mutex_exit(), and ut_a.
04082 { 04083 dict_table_t* table; 04084 04085 mutex_enter(&(dict_sys->mutex)); 04086 04087 table = dict_table_get_low(name); 04088 04089 ut_a(table); 04090 04091 dict_table_print_low(table); 04092 mutex_exit(&(dict_sys->mutex)); 04093 }
Here is the call graph for this function:

| void dict_table_print_low | ( | dict_table_t * | table | ) |
Definition at line 4099 of file dict0dict.c.
References dict_col_print_low(), dict_foreign_print_low(), dict_index_print_low(), dict_sys, dict_table_get_nth_col(), dict_update_statistics_low(), dict_table_struct::foreign_list, dict_table_struct::id, index(), dict_table_struct::indexes, dict_sys_struct::mutex, dict_table_struct::n_cols, dict_table_struct::name, NULL, dict_table_struct::referenced_list, dict_table_struct::stat_n_rows, TRUE, ut_ad, ut_dulint_get_high(), ut_dulint_get_low(), UT_LIST_GET_FIRST, UT_LIST_GET_LEN, and UT_LIST_GET_NEXT.
Referenced by dict_print(), dict_table_print(), and dict_table_print_by_name().
04101 : table */ 04102 { 04103 dict_index_t* index; 04104 dict_foreign_t* foreign; 04105 ulint i; 04106 04107 #ifdef UNIV_SYNC_DEBUG 04108 ut_ad(mutex_own(&(dict_sys->mutex))); 04109 #endif /* UNIV_SYNC_DEBUG */ 04110 04111 dict_update_statistics_low(table, TRUE); 04112 04113 fprintf(stderr, 04114 "--------------------------------------\n" 04115 "TABLE: name %s, id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n" 04116 " COLUMNS: ", 04117 table->name, 04118 (ulong) ut_dulint_get_high(table->id), 04119 (ulong) ut_dulint_get_low(table->id), 04120 (ulong) table->n_cols, 04121 (ulong) UT_LIST_GET_LEN(table->indexes), 04122 (ulong) table->stat_n_rows); 04123 04124 for (i = 0; i < table->n_cols - 1; i++) { 04125 dict_col_print_low(dict_table_get_nth_col(table, i)); 04126 fputs("; ", stderr); 04127 } 04128 04129 putc('\n', stderr); 04130 04131 index = UT_LIST_GET_FIRST(table->indexes); 04132 04133 while (index != NULL) { 04134 dict_index_print_low(index); 04135 index = UT_LIST_GET_NEXT(indexes, index); 04136 } 04137 04138 foreign = UT_LIST_GET_FIRST(table->foreign_list); 04139 04140 while (foreign != NULL) { 04141 dict_foreign_print_low(foreign); 04142 foreign = UT_LIST_GET_NEXT(foreign_list, foreign); 04143 } 04144 04145 foreign = UT_LIST_GET_FIRST(table->referenced_list); 04146 04147 while (foreign != NULL) { 04148 dict_foreign_print_low(foreign); 04149 foreign = UT_LIST_GET_NEXT(referenced_list, foreign); 04150 } 04151 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool dict_table_referenced_by_foreign_key | ( | dict_table_t * | table | ) |
Definition at line 2026 of file dict0dict.c.
References FALSE, dict_table_struct::referenced_list, TRUE, and UT_LIST_GET_LEN.
02028 : TRUE if table is referenced by a 02029 foreign key */ 02030 dict_table_t* table) /* in: InnoDB table */ 02031 { 02032 if (UT_LIST_GET_LEN(table->referenced_list) > 0) { 02033 02034 return(TRUE); 02035 } 02036 02037 return(FALSE); 02038 }
| void dict_table_remove_from_cache | ( | dict_table_t * | table | ) |
Definition at line 1254 of file dict0dict.c.
References dict_col_remove_from_cache(), dict_foreign_remove_from_cache(), dict_index_remove_from_cache(), dict_mem_table_free(), dict_sys, dict_table_get_nth_col(), DICT_TABLE_MAGIC_N, dict_table_struct::foreign_list, HASH_DELETE, dict_table_struct::heap, dict_table_struct::id, index(), dict_table_struct::indexes, dict_table_struct::magic_n, mem_heap_get_size(), dict_sys_struct::mutex, dict_table_struct::n_cols, dict_table_struct::name, NULL, dict_foreign_struct::referenced_index, dict_table_struct::referenced_list, dict_foreign_struct::referenced_table, dict_sys_struct::size, dict_sys_struct::table_hash, dict_sys_struct::table_id_hash, dict_sys_struct::table_LRU, ut_ad, ut_fold_dulint(), ut_fold_string(), UT_LIST_GET_FIRST, UT_LIST_GET_LAST, UT_LIST_GET_NEXT, UT_LIST_REMOVE, and ut_print_name().
Referenced by row_drop_table_for_mysql().
01256 : table */ 01257 { 01258 dict_foreign_t* foreign; 01259 dict_index_t* index; 01260 ulint size; 01261 ulint i; 01262 01263 ut_ad(table); 01264 #ifdef UNIV_SYNC_DEBUG 01265 ut_ad(mutex_own(&(dict_sys->mutex))); 01266 #endif /* UNIV_SYNC_DEBUG */ 01267 ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); 01268 01269 #if 0 01270 fputs("Removing table ", stderr); 01271 ut_print_name(stderr, table->name, ULINT_UNDEFINED); 01272 fputs(" from dictionary cache\n", stderr); 01273 #endif 01274 01275 /* Remove the foreign constraints from the cache */ 01276 foreign = UT_LIST_GET_LAST(table->foreign_list); 01277 01278 while (foreign != NULL) { 01279 dict_foreign_remove_from_cache(foreign); 01280 foreign = UT_LIST_GET_LAST(table->foreign_list); 01281 } 01282 01283 /* Reset table field in referencing constraints */ 01284 01285 foreign = UT_LIST_GET_FIRST(table->referenced_list); 01286 01287 while (foreign != NULL) { 01288 foreign->referenced_table = NULL; 01289 foreign->referenced_index = NULL; 01290 01291 foreign = UT_LIST_GET_NEXT(referenced_list, foreign); 01292 } 01293 01294 /* Remove the indexes from the cache */ 01295 index = UT_LIST_GET_LAST(table->indexes); 01296 01297 while (index != NULL) { 01298 dict_index_remove_from_cache(table, index); 01299 index = UT_LIST_GET_LAST(table->indexes); 01300 } 01301 01302 /* Remove the columns of the table from the cache */ 01303 for (i = 0; i < table->n_cols; i++) { 01304 dict_col_remove_from_cache(table, 01305 dict_table_get_nth_col(table, i)); 01306 } 01307 01308 /* Remove table from the hash tables of tables */ 01309 HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, 01310 ut_fold_string(table->name), table); 01311 HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash, 01312 ut_fold_dulint(table->id), table); 01313 01314 /* Remove table from LRU list of tables */ 01315 UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); 01316 01317 size = mem_heap_get_size(table->heap); 01318 01319 ut_ad(dict_sys->size >= size); 01320 01321 dict_sys->size -= size; 01322 01323 dict_mem_table_free(table); 01324 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool dict_table_rename_in_cache | ( | dict_table_t * | table, | |
| const char * | new_name, | |||
| ibool | rename_also_foreigns | |||
| ) |
Definition at line 1003 of file dict0dict.c.
References dict_col_reposition_in_cache(), dict_foreign_remove_from_cache(), dict_get_db_name_len(), dict_ibfk, dict_remove_db_name(), dict_sys, dict_table_get_first_index(), dict_table_get_next_index(), dict_table_get_nth_col(), dict_table_struct::dir_path_of_temp_table, FALSE, fil_rename_tablespace(), dict_table_struct::foreign_list, dict_foreign_struct::foreign_table_name, HASH_DELETE, HASH_INSERT, HASH_SEARCH, dict_table_struct::heap, dict_foreign_struct::heap, dict_foreign_struct::id, index(), mem_free, mem_heap_alloc(), mem_heap_get_size(), mem_heap_strdup(), mem_strdup(), dict_sys_struct::mutex, dict_table_struct::n_cols, dict_table_struct::name, NULL, dict_foreign_struct::referenced_index, dict_table_struct::referenced_list, dict_foreign_struct::referenced_table, dict_foreign_struct::referenced_table_name, dict_sys_struct::size, dict_table_struct::space, strcat(), strchr(), table2, dict_sys_struct::table_hash, TRUE, ut_ad, ut_fold_string(), UT_LIST_GET_FIRST, UT_LIST_GET_LAST, UT_LIST_GET_NEXT, UT_LIST_INIT, ut_memcmp(), ut_memcpy(), ut_strcmp(), and ut_strlen().
Referenced by row_rename_table_for_mysql().
01005 : TRUE if success */ 01006 dict_table_t* table, /* in: table */ 01007 const char* new_name, /* in: new name */ 01008 ibool rename_also_foreigns)/* in: in ALTER TABLE we want 01009 to preserve the original table name 01010 in constraints which reference it */ 01011 { 01012 dict_foreign_t* foreign; 01013 dict_index_t* index; 01014 ulint fold; 01015 ulint old_size; 01016 char* old_name; 01017 ibool success; 01018 ulint i; 01019 01020 ut_ad(table); 01021 #ifdef UNIV_SYNC_DEBUG 01022 ut_ad(mutex_own(&(dict_sys->mutex))); 01023 #endif /* UNIV_SYNC_DEBUG */ 01024 01025 old_size = mem_heap_get_size(table->heap); 01026 01027 fold = ut_fold_string(new_name); 01028 01029 /* Look for a table with the same name: error if such exists */ 01030 { 01031 dict_table_t* table2; 01032 HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2, 01033 (ut_strcmp(table2->name, new_name) == 0)); 01034 if (table2) { 01035 fprintf(stderr, 01036 "InnoDB: Error: dictionary cache already contains a table of name %s\n", 01037 new_name); 01038 return(FALSE); 01039 } 01040 } 01041 01042 /* If the table is stored in a single-table tablespace, rename the 01043 .ibd file */ 01044 01045 if (table->space != 0) { 01046 if (table->dir_path_of_temp_table != NULL) { 01047 fprintf(stderr, 01048 "InnoDB: Error: trying to rename a table %s (%s) created with CREATE\n" 01049 "InnoDB: TEMPORARY TABLE\n", table->name, table->dir_path_of_temp_table); 01050 success = FALSE; 01051 } else { 01052 success = fil_rename_tablespace(table->name, 01053 table->space, new_name); 01054 } 01055 01056 if (!success) { 01057 01058 return(FALSE); 01059 } 01060 } 01061 01062 /* Reposition the columns in the column hash table; they are hashed 01063 according to the pair (table name, column name) */ 01064 01065 for (i = 0; i < table->n_cols; i++) { 01066 dict_col_reposition_in_cache(table, 01067 dict_table_get_nth_col(table, i), new_name); 01068 } 01069 01070 /* Remove table from the hash tables of tables */ 01071 HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, 01072 ut_fold_string(table->name), table); 01073 old_name = mem_heap_strdup(table->heap, table->name); 01074 table->name = mem_heap_strdup(table->heap, new_name); 01075 01076 /* Add table to hash table of tables */ 01077 HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, 01078 table); 01079 dict_sys->size += (mem_heap_get_size(table->heap) - old_size); 01080 01081 /* Update the table_name field in indexes */ 01082 index = dict_table_get_first_index(table); 01083 01084 while (index != NULL) { 01085 index->table_name = table->name; 01086 01087 index = dict_table_get_next_index(index); 01088 } 01089 01090 if (!rename_also_foreigns) { 01091 /* In ALTER TABLE we think of the rename table operation 01092 in the direction table -> temporary table (#sql...) 01093 as dropping the table with the old name and creating 01094 a new with the new name. Thus we kind of drop the 01095 constraints from the dictionary cache here. The foreign key 01096 constraints will be inherited to the new table from the 01097 system tables through a call of dict_load_foreigns. */ 01098 01099 /* Remove the foreign constraints from the cache */ 01100 foreign = UT_LIST_GET_LAST(table->foreign_list); 01101 01102 while (foreign != NULL) { 01103 dict_foreign_remove_from_cache(foreign); 01104 foreign = UT_LIST_GET_LAST(table->foreign_list); 01105 } 01106 01107 /* Reset table field in referencing constraints */ 01108 01109 foreign = UT_LIST_GET_FIRST(table->referenced_list); 01110 01111 while (foreign != NULL) { 01112 foreign->referenced_table = NULL; 01113 foreign->referenced_index = NULL; 01114 01115 foreign = UT_LIST_GET_NEXT(referenced_list, foreign); 01116 } 01117 01118 /* Make the list of referencing constraints empty */ 01119 01120 UT_LIST_INIT(table->referenced_list); 01121 01122 return(TRUE); 01123 } 01124 01125 /* Update the table name fields in foreign constraints, and update also 01126 the constraint id of new format >= 4.0.18 constraints. Note that at 01127 this point we have already changed table->name to the new name. */ 01128 01129 foreign = UT_LIST_GET_FIRST(table->foreign_list); 01130 01131 while (foreign != NULL) { 01132 if (ut_strlen(foreign->foreign_table_name) < 01133 ut_strlen(table->name)) { 01134 /* Allocate a longer name buffer; 01135 TODO: store buf len to save memory */ 01136 01137 foreign->foreign_table_name = mem_heap_alloc( 01138 foreign->heap, 01139 ut_strlen(table->name) + 1); 01140 } 01141 01142 strcpy(foreign->foreign_table_name, table->name); 01143 01144 if (strchr(foreign->id, '/')) { 01145 ulint db_len; 01146 char* old_id; 01147 01148 /* This is a >= 4.0.18 format id */ 01149 01150 old_id = mem_strdup(foreign->id); 01151 01152 if (ut_strlen(foreign->id) > ut_strlen(old_name) 01153 + ((sizeof dict_ibfk) - 1) 01154 && 0 == ut_memcmp(foreign->id, old_name, 01155 ut_strlen(old_name)) 01156 && 0 == ut_memcmp( 01157 foreign->id + ut_strlen(old_name), 01158 dict_ibfk, (sizeof dict_ibfk) - 1)) { 01159 01160 /* This is a generated >= 4.0.18 format id */ 01161 01162 if (ut_strlen(table->name) > ut_strlen(old_name)) { 01163 foreign->id = mem_heap_alloc( 01164 foreign->heap, 01165 ut_strlen(table->name) 01166 + ut_strlen(old_id) + 1); 01167 } 01168 01169 /* Replace the prefix 'databasename/tablename' 01170 with the new names */ 01171 strcpy(foreign->id, table->name); 01172 strcat(foreign->id, 01173 old_id + ut_strlen(old_name)); 01174 } else { 01175 /* This is a >= 4.0.18 format id where the user 01176 gave the id name */ 01177 db_len = dict_get_db_name_len(table->name) + 1; 01178 01179 if (dict_get_db_name_len(table->name) 01180 > dict_get_db_name_len(foreign->id)) { 01181 01182 foreign->id = mem_heap_alloc( 01183 foreign->heap, 01184 db_len + ut_strlen(old_id) + 1); 01185 } 01186 01187 /* Replace the database prefix in id with the 01188 one from table->name */ 01189 01190 ut_memcpy(foreign->id, table->name, db_len); 01191 01192 strcpy(foreign->id + db_len, 01193 dict_remove_db_name(old_id)); 01194 } 01195 01196 mem_free(old_id); 01197 } 01198 01199 foreign = UT_LIST_GET_NEXT(foreign_list, foreign); 01200 } 01201 01202 foreign = UT_LIST_GET_FIRST(table->referenced_list); 01203 01204 while (foreign != NULL) { 01205 if (ut_strlen(foreign->referenced_table_name) < 01206 ut_strlen(table->name)) { 01207 /* Allocate a longer name buffer; 01208 TODO: store buf len to save memory */ 01209 01210 foreign->referenced_table_name = mem_heap_alloc( 01211 foreign->heap, 01212 ut_strlen(table->name) + 1); 01213 } 01214 01215 strcpy(foreign->referenced_table_name, table->name); 01216 01217 foreign = UT_LIST_GET_NEXT(referenced_list, foreign); 01218 } 01219 01220 return(TRUE); 01221 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool dict_tables_have_same_db | ( | const char * | name1, | |
| const char * | name2 | |||
| ) |
Definition at line 269 of file dict0dict.c.
References FALSE, TRUE, and ut_a.
Referenced by dict_print_info_on_foreign_key_in_create_format(), and row_drop_table_for_mysql().
00271 : TRUE if same db name */ 00272 const char* name1, /* in: table name in the form 00273 dbname '/' tablename */ 00274 const char* name2) /* in: table name in the form 00275 dbname '/' tablename */ 00276 { 00277 for (; *name1 == *name2; name1++, name2++) { 00278 if (*name1 == '/') { 00279 return(TRUE); 00280 } 00281 ut_a(*name1); /* the names must contain '/' */ 00282 } 00283 return(FALSE); 00284 }
Here is the caller graph for this function:

| dtuple_t* dict_tree_build_data_tuple | ( | dict_tree_t * | tree, | |
| rec_t * | rec, | |||
| ulint | n_fields, | |||
| mem_heap_t * | heap | |||
| ) |
Definition at line 3849 of file dict0dict.c.
References dict_index_copy_types(), dict_table_is_comp(), dtuple_check_typed(), dtuple_create(), rec_copy_prefix_to_dtuple(), rec_get_n_fields_old(), dict_index_struct::table, dict_tree_struct::tree_index, and ut_ad.
Referenced by btr_pcur_restore_position().
03851 : data tuple */ 03852 dict_tree_t* tree, /* in: index tree */ 03853 rec_t* rec, /* in: record for which to build data tuple */ 03854 ulint n_fields,/* in: number of data fields */ 03855 mem_heap_t* heap) /* in: memory heap where tuple created */ 03856 { 03857 dtuple_t* tuple; 03858 dict_index_t* ind; 03859 03860 ind = tree->tree_index; 03861 03862 ut_ad(dict_table_is_comp(ind->table) 03863 || n_fields <= rec_get_n_fields_old(rec)); 03864 03865 tuple = dtuple_create(heap, n_fields); 03866 03867 dict_index_copy_types(tuple, ind, n_fields); 03868 03869 rec_copy_prefix_to_dtuple(tuple, rec, ind, n_fields, heap); 03870 03871 ut_ad(dtuple_check_typed(tuple)); 03872 03873 return(tuple); 03874 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dtuple_t* dict_tree_build_node_ptr | ( | dict_tree_t * | tree, | |
| rec_t * | rec, | |||
| ulint | page_no, | |||
| mem_heap_t * | heap, | |||
| ulint | level | |||
| ) |
Definition at line 3747 of file dict0dict.c.
References buf, DATA_NOT_NULL, DATA_SYS_CHILD, dfield_get_type(), dfield_set_data(), dict_index_copy_types(), dict_index_get_n_unique_in_tree(), dict_table_is_comp(), DICT_UNIVERSAL, dtuple_check_typed(), dtuple_create(), dtuple_get_info_bits(), dtuple_get_nth_field(), dtuple_set_info_bits(), dtuple_set_n_fields_cmp(), dtype_set(), mach_write_to_4(), mem_heap_alloc(), rec_copy_prefix_to_dtuple(), rec_get_n_fields_old(), REC_STATUS_NODE_PTR, dict_index_struct::table, dict_tree_struct::tree_index, dict_tree_struct::type, ut_a, and ut_ad.
Referenced by btr_attach_half_pages(), btr_cur_pessimistic_delete(), btr_page_get_father_for_rec(), btr_root_raise_and_insert(), and btr_validate_level().
03749 : node pointer */ 03750 dict_tree_t* tree, /* in: index tree */ 03751 rec_t* rec, /* in: record for which to build node 03752 pointer */ 03753 ulint page_no,/* in: page number to put in node pointer */ 03754 mem_heap_t* heap, /* in: memory heap where pointer created */ 03755 ulint level) /* in: level of rec in tree: 0 means leaf 03756 level */ 03757 { 03758 dtuple_t* tuple; 03759 dict_index_t* ind; 03760 dfield_t* field; 03761 byte* buf; 03762 ulint n_unique; 03763 03764 ind = tree->tree_index; 03765 03766 if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) { 03767 /* In a universal index tree, we take the whole record as 03768 the node pointer if the reord is on the leaf level, 03769 on non-leaf levels we remove the last field, which 03770 contains the page number of the child page */ 03771 03772 ut_a(!dict_table_is_comp(ind->table)); 03773 n_unique = rec_get_n_fields_old(rec); 03774 03775 if (level > 0) { 03776 ut_a(n_unique > 1); 03777 n_unique--; 03778 } 03779 } else { 03780 n_unique = dict_index_get_n_unique_in_tree(ind); 03781 } 03782 03783 tuple = dtuple_create(heap, n_unique + 1); 03784 03785 /* When searching in the tree for the node pointer, we must not do 03786 comparison on the last field, the page number field, as on upper 03787 levels in the tree there may be identical node pointers with a 03788 different page number; therefore, we set the n_fields_cmp to one 03789 less: */ 03790 03791 dtuple_set_n_fields_cmp(tuple, n_unique); 03792 03793 dict_index_copy_types(tuple, ind, n_unique); 03794 03795 buf = mem_heap_alloc(heap, 4); 03796 03797 mach_write_to_4(buf, page_no); 03798 03799 field = dtuple_get_nth_field(tuple, n_unique); 03800 dfield_set_data(field, buf, 4); 03801 03802 dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4, 0); 03803 03804 rec_copy_prefix_to_dtuple(tuple, rec, ind, n_unique, heap); 03805 dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple) | 03806 REC_STATUS_NODE_PTR); 03807 03808 ut_ad(dtuple_check_typed(tuple)); 03809 03810 return(tuple); 03811 }
Here is the call graph for this function:

Here is the caller graph for this function:

| rec_t* dict_tree_copy_rec_order_prefix | ( | dict_tree_t * | tree, | |
| rec_t * | rec, | |||
| ulint * | n_fields, | |||
| byte ** | buf, | |||
| ulint * | buf_size | |||
| ) |
Definition at line 3818 of file dict0dict.c.
References dict_index_get_n_unique_in_tree(), dict_table_is_comp(), DICT_UNIVERSAL, index(), n, rec_copy_prefix_to_buf(), rec_get_n_fields_old(), dict_tree_struct::tree_index, dict_tree_struct::type, and ut_a.
Referenced by btr_pcur_store_position().
03820 : pointer to the prefix record */ 03821 dict_tree_t* tree, /* in: index tree */ 03822 rec_t* rec, /* in: record for which to copy prefix */ 03823 ulint* n_fields,/* out: number of fields copied */ 03824 byte** buf, /* in/out: memory buffer for the copied prefix, 03825 or NULL */ 03826 ulint* buf_size)/* in/out: buffer size */ 03827 { 03828 dict_index_t* index; 03829 ulint n; 03830 03831 UNIV_PREFETCH_R(rec); 03832 index = tree->tree_index; 03833 03834 if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) { 03835 ut_a(!dict_table_is_comp(index->table)); 03836 n = rec_get_n_fields_old(rec); 03837 } else { 03838 n = dict_index_get_n_unique_in_tree(index); 03839 } 03840 03841 *n_fields = n; 03842 return(rec_copy_prefix_to_buf(rec, index, n, buf, buf_size)); 03843 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dict_tree_t* dict_tree_create | ( | dict_index_t * | index, | |
| ulint | page_no | |||
| ) |
Definition at line 3678 of file dict0dict.c.
References DICT_TREE_MAGIC_N, dict_tree_struct::id, index(), dict_tree_struct::lock, dict_tree_struct::magic_n, mem_alloc, NULL, dict_tree_struct::page, rw_lock_create, dict_tree_struct::space, SYNC_INDEX_TREE, dict_tree_struct::tree_index, and dict_tree_struct::type.
Referenced by dict_index_add_to_cache().
03680 : created tree */ 03681 dict_index_t* index, /* in: the index for which to create: in the 03682 case of a mixed tree, this should be the 03683 index of the cluster object */ 03684 ulint page_no)/* in: root page number of the index */ 03685 { 03686 dict_tree_t* tree; 03687 03688 tree = mem_alloc(sizeof(dict_tree_t)); 03689 03690 /* Inherit info from the index */ 03691 03692 tree->type = index->type; 03693 tree->space = index->space; 03694 tree->page = page_no; 03695 03696 tree->id = index->id; 03697 03698 tree->tree_index = NULL; 03699 03700 tree->magic_n = DICT_TREE_MAGIC_N; 03701 03702 rw_lock_create(&tree->lock, SYNC_INDEX_TREE); 03703 03704 return(tree); 03705 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_tree_free | ( | dict_tree_t * | tree | ) |
Definition at line 3711 of file dict0dict.c.
References DICT_TREE_MAGIC_N, dict_tree_struct::lock, dict_tree_struct::magic_n, mem_free, rw_lock_free(), ut_a, and ut_ad.
Referenced by dict_index_remove_from_cache().
03713 : index tree */ 03714 { 03715 ut_a(tree); 03716 ut_ad(tree->magic_n == DICT_TREE_MAGIC_N); 03717 03718 rw_lock_free(&(tree->lock)); 03719 mem_free(tree); 03720 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_update_statistics | ( | dict_table_t * | table | ) |
Definition at line 4011 of file dict0dict.c.
References dict_update_statistics_low(), and FALSE.
Referenced by dict_table_get(), dict_table_get_and_increment_handle_count(), row_truncate_table_for_mysql(), and row_update_statistics_if_needed().
04013 : table */ 04014 { 04015 dict_update_statistics_low(table, FALSE); 04016 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void dict_update_statistics_low | ( | dict_table_t * | table, | |
| ibool has_dict_mutex | __attribute__((unused)) | |||
| ) |
Definition at line 3928 of file dict0dict.c.
References btr_estimate_number_of_different_key_vals(), btr_get_size(), BTR_N_LEAF_PAGES, BTR_TOTAL_SIZE, dict_index_get_n_unique(), dict_table_get_first_index(), dict_table_get_next_index(), dict_table_struct::ibd_file_missing, index(), dict_table_struct::name, NULL, SRV_FORCE_NO_IBUF_MERGE, srv_force_recovery, dict_table_struct::stat_clustered_index_size, dict_table_struct::stat_initialized, dict_table_struct::stat_modified_counter, dict_table_struct::stat_n_rows, dict_table_struct::stat_sum_of_other_index_sizes, TRUE, and ut_print_timestamp().
Referenced by dict_print(), dict_table_print_low(), and dict_update_statistics().
03930 : table */ 03931 ibool has_dict_mutex __attribute__((unused))) 03932 /* in: TRUE if the caller has the 03933 dictionary mutex */ 03934 { 03935 dict_index_t* index; 03936 ulint size; 03937 ulint sum_of_index_sizes = 0; 03938 03939 if (table->ibd_file_missing) { 03940 ut_print_timestamp(stderr); 03941 fprintf(stderr, 03942 " InnoDB: cannot calculate statistics for table %s\n" 03943 "InnoDB: because the .ibd file is missing. For help, please refer to\n" 03944 "InnoDB: " 03945 "http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n", 03946 table->name); 03947 03948 return; 03949 } 03950 03951 /* If we have set a high innodb_force_recovery level, do not calculate 03952 statistics, as a badly corrupted index can cause a crash in it. */ 03953 03954 if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { 03955 03956 return; 03957 } 03958 03959 /* Find out the sizes of the indexes and how many different values 03960 for the key they approximately have */ 03961 03962 index = dict_table_get_first_index(table); 03963 03964 if (index == NULL) { 03965 /* Table definition is corrupt */ 03966 03967 return; 03968 } 03969 03970 while (index) { 03971 size = btr_get_size(index, BTR_TOTAL_SIZE); 03972 03973 index->stat_index_size = size; 03974 03975 sum_of_index_sizes += size; 03976 03977 size = btr_get_size(index, BTR_N_LEAF_PAGES); 03978 03979 if (size == 0) { 03980 /* The root node of the tree is a leaf */ 03981 size = 1; 03982 } 03983 03984 index->stat_n_leaf_pages = size; 03985 03986 btr_estimate_number_of_different_key_vals(index); 03987 03988 index = dict_table_get_next_index(index); 03989 } 03990 03991 index = dict_table_get_first_index(table); 03992 03993 table->stat_n_rows = index->stat_n_diff_key_vals[ 03994 dict_index_get_n_unique(index)]; 03995 03996 table->stat_clustered_index_size = index->stat_index_size; 03997 03998 table->stat_sum_of_other_index_sizes = sum_of_index_sizes 03999 - index->stat_index_size; 04000 04001 table->stat_initialized = TRUE; 04002 04003 table->stat_modified_counter = 0; 04004 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void innobase_casedn_str | ( | char * | a | ) |
Referenced by dict_casedn_str(), and dict_scan_table_name().
Here is the caller graph for this function:

| void innobase_convert_from_filename | ( | char * | s | ) |
| void innobase_convert_from_id | ( | char * | to, | |
| const char * | from, | |||
| ulint | len | |||
| ) |
| void innobase_convert_from_table_id | ( | char * | to, | |
| const char * | from, | |||
| ulint | len | |||
| ) |
| struct charset_info_st* innobase_get_charset | ( | void * | mysql_thd | ) |
Referenced by dict_create_foreign_constraints(), dict_foreign_parse_drop_constraints(), and dict_str_starts_with_keyword().
Here is the caller graph for this function:

| int innobase_strcasecmp | ( | const char * | a, | |
| const char * | b | |||
| ) |
Referenced by dict_foreign_find_index(), and dict_scan_col().
Here is the caller graph for this function:

| FILE* dict_foreign_err_file = NULL |
Definition at line 248 of file dict0dict.c.
Referenced by dict_create_foreign_constraints_low(), dict_foreign_add_to_cache(), dict_foreign_eval_sql(), dict_foreign_parse_drop_constraints(), dict_foreign_report_syntax_err(), dict_init(), innobase_shutdown_for_mysql(), row_discard_tablespace_for_mysql(), row_drop_table_for_mysql(), row_ins_foreign_report_add_err(), row_ins_foreign_report_err(), row_truncate_table_for_mysql(), and srv_printf_innodb_monitor().
Definition at line 249 of file dict0dict.c.
Referenced by dict_create_foreign_constraints_low(), dict_foreign_error_report(), dict_foreign_eval_sql(), dict_foreign_parse_drop_constraints(), dict_foreign_report_syntax_err(), dict_init(), row_discard_tablespace_for_mysql(), row_drop_table_for_mysql(), row_ins_foreign_report_add_err(), row_ins_foreign_report_err(), row_truncate_table_for_mysql(), and srv_printf_innodb_monitor().
char dict_ibfk[] = "_ibfk_" [static] |
Definition at line 57 of file dict0dict.c.
Referenced by dict_table_get_highest_foreign_id(), and dict_table_rename_in_cache().
Definition at line 35 of file dict0dict.c.
Referenced by dict_init(), row_create_index_for_mysql(), row_create_table_for_mysql(), row_drop_table_for_mysql(), row_ins_check_foreign_constraint(), row_mysql_freeze_data_dictionary(), row_mysql_lock_data_dictionary(), row_mysql_unfreeze_data_dictionary(), row_mysql_unlock_data_dictionary(), row_table_add_foreign_constraints(), and row_truncate_table_for_mysql().
| dict_sys_t* dict_sys = NULL |
Definition at line 33 of file dict0dict.c.
Referenced by buf_page_print(), dict_boot(), dict_build_index_def_step(), dict_build_table_def_step(), dict_check_tablespaces_and_store_max_id(), dict_col_add_to_cache(), dict_col_print_low(), dict_col_remove_from_cache(), dict_col_reposition_in_cache(), dict_create_add_foreigns_to_dictionary(), dict_create_foreign_constraints_low(), dict_create_index_step(), dict_create_index_tree_step(), dict_create_or_check_foreign_constraint_tables(), dict_create_sys_columns_tuple(), dict_create_sys_fields_tuple(), dict_create_sys_indexes_tuple(), dict_create_sys_tables_tuple(), dict_create_table_step(), dict_drop_index_tree(), dict_field_print_low(), dict_foreign_add_to_cache(), dict_foreign_find(), dict_foreign_parse_drop_constraints(), dict_foreign_print_low(), dict_foreign_remove_from_cache(), dict_get_first_table_name_in_db(), dict_hdr_flush_row_id(), dict_index_add_to_cache(), dict_index_build_internal_clust(), dict_index_build_internal_non_clust(), dict_index_find_cols(), dict_index_find_on_id_low(), dict_index_get_if_in_cache(), dict_index_print_low(), dict_index_remove_from_cache(), dict_init(), dict_load_columns(), dict_load_fields(), dict_load_foreign(), dict_load_foreign_cols(), dict_load_foreigns(), dict_load_indexes(), dict_load_sys_table(), dict_load_table(), dict_load_table_on_id(), dict_mutex_enter_for_mysql(), dict_mutex_exit_for_mysql(), dict_print(), dict_print_info_on_foreign_keys(), dict_table_add_to_cache(), dict_table_change_id_in_cache(), dict_table_decrement_handle_count(), dict_table_get(), dict_table_get_and_increment_handle_count(), dict_table_get_on_id(), dict_table_print(), dict_table_print_by_name(), dict_table_print_low(), dict_table_remove_from_cache(), dict_table_rename_in_cache(), dict_truncate_index_tree(), ind_create_graph_create(), pars_sql(), que_eval_sql(), row_create_index_for_mysql(), row_create_table_for_mysql(), row_drop_table_for_mysql(), row_drop_tables_for_mysql_in_background(), row_ins_check_foreign_constraints(), row_mysql_lock_data_dictionary(), row_mysql_unlock_data_dictionary(), row_purge_parse_undo_rec(), row_table_add_foreign_constraints(), row_truncate_table_for_mysql(), row_upd_check_references_constraints(), srv_printf_innodb_monitor(), and tab_create_graph_create().
1.4.7

