#include "dict0crea.h"#include "btr0pcur.h"#include "btr0btr.h"#include "page0page.h"#include "mach0data.h"#include "dict0boot.h"#include "dict0dict.h"#include "que0que.h"#include "row0ins.h"#include "row0mysql.h"#include "pars0pars.h"#include "trx0roll.h"#include "usr0sess.h"#include "ut0vec.h"Include dependency graph for dict0crea.c:

Go to the source code of this file.
| static ulint dict_build_col_def_step | ( | tab_node_t * | node | ) | [static] |
Definition at line 280 of file dict0crea.c.
References tab_node_struct::col_def, tab_node_struct::col_no, DB_SUCCESS, dict_create_sys_columns_tuple(), tab_node_struct::heap, ins_node_set_new_row(), and tab_node_struct::table.
Referenced by dict_create_table_step().
00282 : DB_SUCCESS */ 00283 tab_node_t* node) /* in: table create node */ 00284 { 00285 dtuple_t* row; 00286 00287 row = dict_create_sys_columns_tuple(node->table, node->col_no, 00288 node->heap); 00289 ins_node_set_new_row(node->col_def, row); 00290 00291 return(DB_SUCCESS); 00292 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ulint dict_build_field_def_step | ( | ind_node_t * | node | ) | [static] |
Definition at line 552 of file dict0crea.c.
References DB_SUCCESS, dict_create_sys_fields_tuple(), ind_node_struct::field_def, ind_node_struct::field_no, ind_node_struct::heap, ind_node_struct::index, index(), and ins_node_set_new_row().
Referenced by dict_create_index_step().
00554 : DB_SUCCESS */ 00555 ind_node_t* node) /* in: index create node */ 00556 { 00557 dict_index_t* index; 00558 dtuple_t* row; 00559 00560 index = node->index; 00561 00562 row = dict_create_sys_fields_tuple(index, node->field_no, node->heap); 00563 00564 ins_node_set_new_row(node->field_def, row); 00565 00566 return(DB_SUCCESS); 00567 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ulint dict_build_index_def_step | ( | que_thr_t * | thr, | |
| ind_node_t * | node | |||
| ) | [static] |
Definition at line 501 of file dict0crea.c.
References DB_SUCCESS, DB_TABLE_NOT_FOUND, DICT_CLUSTERED, dict_create_sys_indexes_tuple(), dict_hdr_get_new_id(), DICT_HDR_INDEX_ID, dict_sys, dict_table_get_low(), FIL_NULL, ind_node_struct::heap, dict_table_struct::id, ind_node_struct::ind_def, ind_node_struct::ind_row, ind_node_struct::index, index(), dict_table_struct::indexes, ins_node_set_new_row(), dict_sys_struct::mutex, NULL, ind_node_struct::page_no, dict_table_struct::space, ind_node_struct::table, trx_struct::table_id, thr_get_trx(), ut_ad, and UT_LIST_GET_LEN.
Referenced by dict_create_index_step().
00503 : DB_SUCCESS or error code */ 00504 que_thr_t* thr, /* in: query thread */ 00505 ind_node_t* node) /* in: index create node */ 00506 { 00507 dict_table_t* table; 00508 dict_index_t* index; 00509 dtuple_t* row; 00510 trx_t* trx; 00511 00512 #ifdef UNIV_SYNC_DEBUG 00513 ut_ad(mutex_own(&(dict_sys->mutex))); 00514 #endif /* UNIV_SYNC_DEBUG */ 00515 00516 trx = thr_get_trx(thr); 00517 00518 index = node->index; 00519 00520 table = dict_table_get_low(index->table_name); 00521 00522 if (table == NULL) { 00523 return(DB_TABLE_NOT_FOUND); 00524 } 00525 00526 trx->table_id = table->id; 00527 00528 node->table = table; 00529 00530 ut_ad((UT_LIST_GET_LEN(table->indexes) > 0) 00531 || (index->type & DICT_CLUSTERED)); 00532 00533 index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID); 00534 00535 /* Inherit the space id from the table; we store all indexes of a 00536 table in the same tablespace */ 00537 00538 index->space = table->space; 00539 node->page_no = FIL_NULL; 00540 row = dict_create_sys_indexes_tuple(index, node->heap); 00541 node->ind_row = row; 00542 00543 ins_node_set_new_row(node->ind_def, row); 00544 00545 return(DB_SUCCESS); 00546 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ulint dict_build_table_def_step | ( | que_thr_t * | thr, | |
| tab_node_t * | node | |||
| ) | [static] |
Definition at line 198 of file dict0crea.c.
References BTR_PAGE_MAX_REC_SIZE, dict_table_struct::cols, DB_SUCCESS, DB_TOO_BIG_RECORD, dict_col_get_type(), dict_hdr_get_new_id(), DICT_HDR_TABLE_ID, dict_sys, dict_table_struct::dir_path_of_temp_table, dtype_get_min_size(), error, FALSE, fil_create_new_single_table_tablespace(), FIL_IBD_FILE_INITIAL_SIZE, fsp_header_init(), dict_table_struct::id, mtr_commit(), mtr_start(), dict_sys_struct::mutex, dict_table_struct::n_def, dict_table_struct::name, dict_table_struct::space, srv_file_per_table, tab_node_struct::table, trx_struct::table_id, thr_get_trx(), TRUE, and ut_ad.
Referenced by dict_create_table_step().
00200 : DB_SUCCESS or error code */ 00201 que_thr_t* thr, /* in: query thread */ 00202 tab_node_t* node) /* in: table create node */ 00203 { 00204 dict_table_t* table; 00205 dtuple_t* row; 00206 ulint error; 00207 const char* path_or_name; 00208 ibool is_path; 00209 mtr_t mtr; 00210 ulint i; 00211 ulint row_len; 00212 00213 #ifdef UNIV_SYNC_DEBUG 00214 ut_ad(mutex_own(&(dict_sys->mutex))); 00215 #endif /* UNIV_SYNC_DEBUG */ 00216 00217 table = node->table; 00218 00219 table->id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); 00220 00221 thr_get_trx(thr)->table_id = table->id; 00222 00223 row_len = 0; 00224 for (i = 0; i < table->n_def; i++) { 00225 row_len += dtype_get_min_size(dict_col_get_type( 00226 &table->cols[i])); 00227 } 00228 if (row_len > BTR_PAGE_MAX_REC_SIZE) { 00229 return(DB_TOO_BIG_RECORD); 00230 } 00231 00232 if (srv_file_per_table) { 00233 /* We create a new single-table tablespace for the table. 00234 We initially let it be 4 pages: 00235 - page 0 is the fsp header and an extent descriptor page, 00236 - page 1 is an ibuf bitmap page, 00237 - page 2 is the first inode page, 00238 - page 3 will contain the root of the clustered index of the 00239 table we create here. */ 00240 00241 table->space = 0; /* reset to zero for the call below */ 00242 00243 if (table->dir_path_of_temp_table) { 00244 /* We place tables created with CREATE TEMPORARY 00245 TABLE in the tmp dir of mysqld server */ 00246 00247 path_or_name = table->dir_path_of_temp_table; 00248 is_path = TRUE; 00249 } else { 00250 path_or_name = table->name; 00251 is_path = FALSE; 00252 } 00253 00254 error = fil_create_new_single_table_tablespace( 00255 &(table->space), path_or_name, is_path, 00256 FIL_IBD_FILE_INITIAL_SIZE); 00257 if (error != DB_SUCCESS) { 00258 00259 return(error); 00260 } 00261 00262 mtr_start(&mtr); 00263 00264 fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); 00265 00266 mtr_commit(&mtr); 00267 } 00268 00269 row = dict_create_sys_tables_tuple(table, node->heap); 00270 00271 ins_node_set_new_row(node->tab_def, row); 00272 00273 return(DB_SUCCESS); 00274 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ulint dict_create_add_foreign_field_to_dictionary | ( | ulint | field_nr, | |
| dict_table_t * | table, | |||
| dict_foreign_t * | foreign, | |||
| trx_t * | trx | |||
| ) | [static] |
Definition at line 1299 of file dict0crea.c.
References dict_foreign_eval_sql(), dict_foreign_struct::foreign_col_names, dict_foreign_struct::id, info, pars_info_add_int4_literal(), pars_info_add_str_literal(), pars_info_create(), and dict_foreign_struct::referenced_col_names.
Referenced by dict_create_add_foreign_to_dictionary().
01301 : error code or DB_SUCCESS */ 01302 ulint field_nr, /* in: foreign field number */ 01303 dict_table_t* table, /* in: table */ 01304 dict_foreign_t* foreign, /* in: foreign */ 01305 trx_t* trx) /* in: transaction */ 01306 { 01307 pars_info_t* info = pars_info_create(); 01308 01309 pars_info_add_str_literal(info, "id", foreign->id); 01310 01311 pars_info_add_int4_literal(info, "pos", field_nr); 01312 01313 pars_info_add_str_literal(info, "for_col_name", 01314 foreign->foreign_col_names[field_nr]); 01315 01316 pars_info_add_str_literal(info, "ref_col_name", 01317 foreign->referenced_col_names[field_nr]); 01318 01319 return dict_foreign_eval_sql(info, 01320 "PROCEDURE P () IS\n" 01321 "BEGIN\n" 01322 "INSERT INTO SYS_FOREIGN_COLS VALUES" 01323 "(:id, :pos, :for_col_name, :ref_col_name);\n" 01324 "END;\n" 01325 , table, foreign, trx); 01326 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ulint dict_create_add_foreign_to_dictionary | ( | ulint * | id_nr, | |
| dict_table_t * | table, | |||
| dict_foreign_t * | foreign, | |||
| trx_t * | trx | |||
| ) | [static] |
Definition at line 1337 of file dict0crea.c.
References DB_SUCCESS, dict_create_add_foreign_field_to_dictionary(), dict_foreign_eval_sql(), error, dict_foreign_struct::heap, dict_foreign_struct::id, info, mem_heap_alloc(), dict_foreign_struct::n_fields, dict_table_struct::name, NULL, pars_info_add_int4_literal(), pars_info_add_str_literal(), pars_info_create(), dict_foreign_struct::referenced_table_name, strlen(), and dict_foreign_struct::type.
Referenced by dict_create_add_foreigns_to_dictionary().
01339 : error code or DB_SUCCESS */ 01340 ulint* id_nr, /* in/out: number to use in id generation; 01341 incremented if used */ 01342 dict_table_t* table, /* in: table */ 01343 dict_foreign_t* foreign,/* in: foreign */ 01344 trx_t* trx) /* in: transaction */ 01345 { 01346 ulint error; 01347 ulint i; 01348 01349 pars_info_t* info = pars_info_create(); 01350 01351 if (foreign->id == NULL) { 01352 /* Generate a new constraint id */ 01353 ulint namelen = strlen(table->name); 01354 char* id = mem_heap_alloc(foreign->heap, namelen + 20); 01355 /* no overflow if number < 1e13 */ 01356 sprintf(id, "%s_ibfk_%lu", table->name, (ulong) (*id_nr)++); 01357 foreign->id = id; 01358 } 01359 01360 pars_info_add_str_literal(info, "id", foreign->id); 01361 01362 pars_info_add_str_literal(info, "for_name", table->name); 01363 01364 pars_info_add_str_literal(info, "ref_name", 01365 foreign->referenced_table_name); 01366 01367 pars_info_add_int4_literal(info, "n_cols", 01368 foreign->n_fields + (foreign->type << 24)); 01369 01370 error = dict_foreign_eval_sql(info, 01371 "PROCEDURE P () IS\n" 01372 "BEGIN\n" 01373 "INSERT INTO SYS_FOREIGN VALUES" 01374 "(:id, :for_name, :ref_name, :n_cols);\n" 01375 "END;\n" 01376 , table, foreign, trx); 01377 01378 if (error != DB_SUCCESS) { 01379 01380 return(error); 01381 } 01382 01383 for (i = 0; i < foreign->n_fields; i++) { 01384 error = dict_create_add_foreign_field_to_dictionary(i, 01385 table, foreign, trx); 01386 01387 if (error != DB_SUCCESS) { 01388 01389 return(error); 01390 } 01391 } 01392 01393 error = dict_foreign_eval_sql(NULL, 01394 "PROCEDURE P () IS\n" 01395 "BEGIN\n" 01396 "COMMIT WORK;\n" 01397 "END;\n" 01398 , table, foreign, trx); 01399 01400 return(error); 01401 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_create_add_foreigns_to_dictionary | ( | ulint | start_id, | |
| dict_table_t * | table, | |||
| trx_t * | trx | |||
| ) |
Definition at line 1407 of file dict0crea.c.
References DB_ERROR, DB_SUCCESS, dict_create_add_foreign_to_dictionary(), dict_sys, dict_table_get_low(), error, dict_table_struct::foreign_list, dict_sys_struct::mutex, NULL, ut_ad, UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
Referenced by dict_create_foreign_constraints_low().
01409 : error code or DB_SUCCESS */ 01410 ulint start_id,/* in: if we are actually doing ALTER TABLE 01411 ADD CONSTRAINT, we want to generate constraint 01412 numbers which are bigger than in the table so 01413 far; we number the constraints from 01414 start_id + 1 up; start_id should be set to 0 if 01415 we are creating a new table, or if the table 01416 so far has no constraints for which the name 01417 was generated here */ 01418 dict_table_t* table, /* in: table */ 01419 trx_t* trx) /* in: transaction */ 01420 { 01421 dict_foreign_t* foreign; 01422 ulint number = start_id + 1; 01423 ulint error; 01424 01425 #ifdef UNIV_SYNC_DEBUG 01426 ut_ad(mutex_own(&(dict_sys->mutex))); 01427 #endif /* UNIV_SYNC_DEBUG */ 01428 01429 if (NULL == dict_table_get_low("SYS_FOREIGN")) { 01430 fprintf(stderr, 01431 "InnoDB: table SYS_FOREIGN not found from internal data dictionary\n"); 01432 01433 return(DB_ERROR); 01434 } 01435 01436 for (foreign = UT_LIST_GET_FIRST(table->foreign_list); 01437 foreign; 01438 foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) { 01439 01440 error = dict_create_add_foreign_to_dictionary(&number, 01441 table, foreign, trx); 01442 01443 if (error != DB_SUCCESS) { 01444 01445 return(error); 01446 } 01447 } 01448 01449 return(DB_SUCCESS); 01450 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1000 of file dict0crea.c.
References DB_ERROR, DB_LOCK_WAIT, DB_SUCCESS, dict_build_field_def_step(), dict_build_index_def_step(), dict_create_index_tree_step(), dict_index_add_to_cache(), dict_sys, err, trx_struct::error_state, ind_node_struct::field_def, ind_node_struct::field_no, ind_node_struct::ind_def, ind_node_struct::index, INDEX_ADD_TO_CACHE, INDEX_BUILD_FIELD_DEF, INDEX_BUILD_INDEX_DEF, INDEX_COMMIT_WORK, INDEX_CREATE_INDEX_TREE, dict_sys_struct::mutex, NULL, ind_node_struct::page_no, que_thr_struct::prev_node, QUE_NODE_CREATE_INDEX, que_node_get_parent(), que_node_get_type(), que_thr_struct::run_node, ind_node_struct::state, ind_node_struct::table, thr_get_trx(), ut_a, and ut_ad.
Referenced by que_thr_step().
01002 : query thread to run next or NULL */ 01003 que_thr_t* thr) /* in: query thread */ 01004 { 01005 ind_node_t* node; 01006 ibool success; 01007 ulint err = DB_ERROR; 01008 trx_t* trx; 01009 01010 ut_ad(thr); 01011 #ifdef UNIV_SYNC_DEBUG 01012 ut_ad(mutex_own(&(dict_sys->mutex))); 01013 #endif /* UNIV_SYNC_DEBUG */ 01014 01015 trx = thr_get_trx(thr); 01016 01017 node = thr->run_node; 01018 01019 ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_INDEX); 01020 01021 if (thr->prev_node == que_node_get_parent(node)) { 01022 node->state = INDEX_BUILD_INDEX_DEF; 01023 } 01024 01025 if (node->state == INDEX_BUILD_INDEX_DEF) { 01026 /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */ 01027 err = dict_build_index_def_step(thr, node); 01028 01029 if (err != DB_SUCCESS) { 01030 01031 goto function_exit; 01032 } 01033 01034 node->state = INDEX_BUILD_FIELD_DEF; 01035 node->field_no = 0; 01036 01037 thr->run_node = node->ind_def; 01038 01039 return(thr); 01040 } 01041 01042 if (node->state == INDEX_BUILD_FIELD_DEF) { 01043 01044 if (node->field_no < (node->index)->n_fields) { 01045 01046 err = dict_build_field_def_step(node); 01047 01048 if (err != DB_SUCCESS) { 01049 01050 goto function_exit; 01051 } 01052 01053 node->field_no++; 01054 01055 thr->run_node = node->field_def; 01056 01057 return(thr); 01058 } else { 01059 node->state = INDEX_CREATE_INDEX_TREE; 01060 } 01061 } 01062 01063 if (node->state == INDEX_CREATE_INDEX_TREE) { 01064 01065 err = dict_create_index_tree_step(node); 01066 01067 if (err != DB_SUCCESS) { 01068 01069 goto function_exit; 01070 } 01071 01072 node->state = INDEX_COMMIT_WORK; 01073 } 01074 01075 if (node->state == INDEX_COMMIT_WORK) { 01076 01077 /* Index was correctly defined: do NOT commit the transaction 01078 (CREATE INDEX does NOT currently do an implicit commit of 01079 the current transaction) */ 01080 01081 node->state = INDEX_ADD_TO_CACHE; 01082 01083 /* thr->run_node = node->commit_node; 01084 01085 return(thr); */ 01086 } 01087 01088 if (node->state == INDEX_ADD_TO_CACHE) { 01089 01090 success = dict_index_add_to_cache(node->table, node->index, 01091 node->page_no); 01092 01093 ut_a(success); 01094 01095 err = DB_SUCCESS; 01096 } 01097 01098 function_exit: 01099 trx->error_state = err; 01100 01101 if (err == DB_SUCCESS) { 01102 /* Ok: do nothing */ 01103 01104 } else if (err == DB_LOCK_WAIT) { 01105 01106 return(NULL); 01107 } else { 01108 /* SQL error detected */ 01109 01110 return(NULL); 01111 } 01112 01113 thr->run_node = que_node_get_parent(node); 01114 01115 return(thr); 01116 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ulint dict_create_index_tree_step | ( | ind_node_t * | node | ) | [static] |
Definition at line 573 of file dict0crea.c.
References btr_create(), BTR_MODIFY_LEAF, btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open(), DB_OUT_OF_FILE_SPACE, DB_SUCCESS, dict_create_search_tuple(), dict_sys, DICT_SYS_INDEXES_PAGE_NO_FIELD, dict_table_is_comp(), FIL_NULL, ind_node_struct::heap, ind_node_struct::ind_row, ind_node_struct::index, index(), dict_table_struct::indexes, mtr_commit(), mtr_start(), dict_sys_struct::mutex, PAGE_CUR_L, ind_node_struct::page_no, page_rec_write_index_page_no(), dict_sys_struct::sys_indexes, ind_node_struct::table, ut_ad, and UT_LIST_GET_FIRST.
Referenced by dict_create_index_step().
00575 : DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ 00576 ind_node_t* node) /* in: index create node */ 00577 { 00578 dict_index_t* index; 00579 dict_table_t* sys_indexes; 00580 dict_table_t* table; 00581 dtuple_t* search_tuple; 00582 btr_pcur_t pcur; 00583 mtr_t mtr; 00584 00585 #ifdef UNIV_SYNC_DEBUG 00586 ut_ad(mutex_own(&(dict_sys->mutex))); 00587 #endif /* UNIV_SYNC_DEBUG */ 00588 00589 index = node->index; 00590 table = node->table; 00591 00592 sys_indexes = dict_sys->sys_indexes; 00593 00594 /* Run a mini-transaction in which the index tree is allocated for 00595 the index and its root address is written to the index entry in 00596 sys_indexes */ 00597 00598 mtr_start(&mtr); 00599 00600 search_tuple = dict_create_search_tuple(node->ind_row, node->heap); 00601 00602 btr_pcur_open(UT_LIST_GET_FIRST(sys_indexes->indexes), 00603 search_tuple, PAGE_CUR_L, BTR_MODIFY_LEAF, 00604 &pcur, &mtr); 00605 00606 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 00607 00608 node->page_no = btr_create(index->type, index->space, index->id, 00609 dict_table_is_comp(table), &mtr); 00610 /* printf("Created a new index tree in space %lu root page %lu\n", 00611 index->space, index->page_no); */ 00612 00613 page_rec_write_index_page_no(btr_pcur_get_rec(&pcur), 00614 DICT_SYS_INDEXES_PAGE_NO_FIELD, 00615 node->page_no, &mtr); 00616 btr_pcur_close(&pcur); 00617 mtr_commit(&mtr); 00618 00619 if (node->page_no == FIL_NULL) { 00620 00621 return(DB_OUT_OF_FILE_SPACE); 00622 } 00623 00624 return(DB_SUCCESS); 00625 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_create_or_check_foreign_constraint_tables | ( | void | ) |
Definition at line 1124 of file dict0crea.c.
References DB_MUST_GET_MORE_FILE_SPACE, DB_OUT_OF_FILE_SPACE, DB_SUCCESS, dict_sys, dict_table_get_low(), error, FALSE, dict_table_struct::indexes, dict_sys_struct::mutex, mutex_enter, mutex_exit(), NULL, trx_struct::op_info, que_eval_sql(), row_drop_table_for_mysql(), row_mysql_lock_data_dictionary(), row_mysql_unlock_data_dictionary(), table2, TRUE, trx_allocate_for_mysql(), trx_free_for_mysql(), ut_a, and UT_LIST_GET_LEN.
Referenced by innobase_start_or_create_for_mysql().
01126 : DB_SUCCESS or error code */ 01127 { 01128 dict_table_t* table1; 01129 dict_table_t* table2; 01130 ulint error; 01131 trx_t* trx; 01132 01133 mutex_enter(&(dict_sys->mutex)); 01134 01135 table1 = dict_table_get_low("SYS_FOREIGN"); 01136 table2 = dict_table_get_low("SYS_FOREIGN_COLS"); 01137 01138 if (table1 && table2 01139 && UT_LIST_GET_LEN(table1->indexes) == 3 01140 && UT_LIST_GET_LEN(table2->indexes) == 1) { 01141 01142 /* Foreign constraint system tables have already been 01143 created, and they are ok */ 01144 01145 mutex_exit(&(dict_sys->mutex)); 01146 01147 return(DB_SUCCESS); 01148 } 01149 01150 mutex_exit(&(dict_sys->mutex)); 01151 01152 trx = trx_allocate_for_mysql(); 01153 01154 trx->op_info = "creating foreign key sys tables"; 01155 01156 row_mysql_lock_data_dictionary(trx); 01157 01158 if (table1) { 01159 fprintf(stderr, 01160 "InnoDB: dropping incompletely created SYS_FOREIGN table\n"); 01161 row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); 01162 } 01163 01164 if (table2) { 01165 fprintf(stderr, 01166 "InnoDB: dropping incompletely created SYS_FOREIGN_COLS table\n"); 01167 row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); 01168 } 01169 01170 fprintf(stderr, 01171 "InnoDB: Creating foreign key constraint system tables\n"); 01172 01173 /* NOTE: in dict_load_foreigns we use the fact that 01174 there are 2 secondary indexes on SYS_FOREIGN, and they 01175 are defined just like below */ 01176 01177 /* NOTE: when designing InnoDB's foreign key support in 2001, we made 01178 an error and made the table names and the foreign key id of type 01179 'CHAR' (internally, really a VARCHAR). We should have made the type 01180 VARBINARY, like in other InnoDB system tables, to get a clean 01181 design. */ 01182 01183 error = que_eval_sql(NULL, 01184 "PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n" 01185 "BEGIN\n" 01186 "CREATE TABLE\n" 01187 "SYS_FOREIGN(ID CHAR, FOR_NAME CHAR, REF_NAME CHAR, N_COLS INT);\n" 01188 "CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN (ID);\n" 01189 "CREATE INDEX FOR_IND ON SYS_FOREIGN (FOR_NAME);\n" 01190 "CREATE INDEX REF_IND ON SYS_FOREIGN (REF_NAME);\n" 01191 "CREATE TABLE\n" 01192 "SYS_FOREIGN_COLS(ID CHAR, POS INT, FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n" 01193 "CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN_COLS (ID, POS);\n" 01194 "COMMIT WORK;\n" 01195 "END;\n" 01196 , FALSE, trx); 01197 01198 if (error != DB_SUCCESS) { 01199 fprintf(stderr, "InnoDB: error %lu in creation\n", 01200 (ulong) error); 01201 01202 ut_a(error == DB_OUT_OF_FILE_SPACE); 01203 01204 fprintf(stderr, "InnoDB: creation failed\n"); 01205 fprintf(stderr, "InnoDB: tablespace is full\n"); 01206 fprintf(stderr, 01207 "InnoDB: dropping incompletely created SYS_FOREIGN tables\n"); 01208 01209 row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); 01210 row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); 01211 01212 error = DB_MUST_GET_MORE_FILE_SPACE; 01213 } 01214 01215 trx->op_info = ""; 01216 01217 row_mysql_unlock_data_dictionary(trx); 01218 01219 trx_free_for_mysql(trx); 01220 01221 if (error == DB_SUCCESS) { 01222 fprintf(stderr, 01223 "InnoDB: Foreign key constraint system tables created\n"); 01224 } 01225 01226 return(error); 01227 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dtuple_t* dict_create_search_tuple | ( | dtuple_t * | tuple, | |
| mem_heap_t * | heap | |||
| ) | [static] |
Definition at line 466 of file dict0crea.c.
References dfield_copy(), dtuple_create(), dtuple_get_nth_field(), and ut_ad.
Referenced by dict_create_index_tree_step().
00468 : the tuple for search */ 00469 dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES 00470 table */ 00471 mem_heap_t* heap) /* in: memory heap from which the memory for 00472 the built tuple is allocated */ 00473 { 00474 dtuple_t* search_tuple; 00475 dfield_t* field1; 00476 dfield_t* field2; 00477 00478 ut_ad(tuple && heap); 00479 00480 search_tuple = dtuple_create(heap, 2); 00481 00482 field1 = dtuple_get_nth_field(tuple, 0); 00483 field2 = dtuple_get_nth_field(search_tuple, 0); 00484 00485 dfield_copy(field2, field1); 00486 00487 field1 = dtuple_get_nth_field(tuple, 1); 00488 field2 = dtuple_get_nth_field(search_tuple, 1); 00489 00490 dfield_copy(field2, field1); 00491 00492 ut_ad(dtuple_validate(search_tuple)); 00493 00494 return(search_tuple); 00495 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dtuple_t* dict_create_sys_columns_tuple | ( | dict_table_t * | table, | |
| ulint | i, | |||
| mem_heap_t * | heap | |||
| ) | [static] |
Definition at line 119 of file dict0crea.c.
References DATA_N_SYS_COLS, dfield_set_data(), dict_sys, dict_table_copy_types(), dict_table_get_nth_col(), dtuple_create(), dtuple_get_nth_field(), dict_table_struct::id, mach_write_to_4(), mach_write_to_8(), mem_heap_alloc(), dict_col_struct::name, dict_sys_struct::sys_columns, dict_col_struct::type, ut_ad, and ut_strlen().
Referenced by dict_build_col_def_step().
00121 : the tuple which should be inserted */ 00122 dict_table_t* table, /* in: table */ 00123 ulint i, /* in: column number */ 00124 mem_heap_t* heap) /* in: memory heap from which the memory for 00125 the built tuple is allocated */ 00126 { 00127 dict_table_t* sys_columns; 00128 dtuple_t* entry; 00129 dict_col_t* column; 00130 dfield_t* dfield; 00131 byte* ptr; 00132 00133 ut_ad(table && heap); 00134 00135 column = dict_table_get_nth_col(table, i); 00136 00137 sys_columns = dict_sys->sys_columns; 00138 00139 entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS); 00140 00141 /* 0: TABLE_ID -----------------------*/ 00142 dfield = dtuple_get_nth_field(entry, 0); 00143 00144 ptr = mem_heap_alloc(heap, 8); 00145 mach_write_to_8(ptr, table->id); 00146 00147 dfield_set_data(dfield, ptr, 8); 00148 /* 1: POS ----------------------------*/ 00149 dfield = dtuple_get_nth_field(entry, 1); 00150 00151 ptr = mem_heap_alloc(heap, 4); 00152 mach_write_to_4(ptr, i); 00153 00154 dfield_set_data(dfield, ptr, 4); 00155 /* 4: NAME ---------------------------*/ 00156 dfield = dtuple_get_nth_field(entry, 2); 00157 00158 dfield_set_data(dfield, column->name, ut_strlen(column->name)); 00159 /* 5: MTYPE --------------------------*/ 00160 dfield = dtuple_get_nth_field(entry, 3); 00161 00162 ptr = mem_heap_alloc(heap, 4); 00163 mach_write_to_4(ptr, (column->type).mtype); 00164 00165 dfield_set_data(dfield, ptr, 4); 00166 /* 6: PRTYPE -------------------------*/ 00167 dfield = dtuple_get_nth_field(entry, 4); 00168 00169 ptr = mem_heap_alloc(heap, 4); 00170 mach_write_to_4(ptr, (column->type).prtype); 00171 00172 dfield_set_data(dfield, ptr, 4); 00173 /* 7: LEN ----------------------------*/ 00174 dfield = dtuple_get_nth_field(entry, 5); 00175 00176 ptr = mem_heap_alloc(heap, 4); 00177 mach_write_to_4(ptr, (column->type).len); 00178 00179 dfield_set_data(dfield, ptr, 4); 00180 /* 8: PREC ---------------------------*/ 00181 dfield = dtuple_get_nth_field(entry, 6); 00182 00183 ptr = mem_heap_alloc(heap, 4); 00184 mach_write_to_4(ptr, (column->type).prec); 00185 00186 dfield_set_data(dfield, ptr, 4); 00187 /*---------------------------------*/ 00188 00189 dict_table_copy_types(entry, sys_columns); 00190 00191 return(entry); 00192 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dtuple_t* dict_create_sys_fields_tuple | ( | dict_index_t * | index, | |
| ulint | i, | |||
| mem_heap_t * | heap | |||
| ) | [static] |
Definition at line 391 of file dict0crea.c.
References DATA_N_SYS_COLS, dfield_set_data(), dict_index_get_nth_field(), dict_sys, dict_table_copy_types(), dtuple_create(), dtuple_get_nth_field(), FALSE, index(), mach_write_to_4(), mach_write_to_8(), mem_heap_alloc(), dict_field_struct::name, dict_field_struct::prefix_len, dict_sys_struct::sys_fields, TRUE, ut_ad, and ut_strlen().
Referenced by dict_build_field_def_step().
00393 : the tuple which should be inserted */ 00394 dict_index_t* index, /* in: index */ 00395 ulint i, /* in: field number */ 00396 mem_heap_t* heap) /* in: memory heap from which the memory for 00397 the built tuple is allocated */ 00398 { 00399 dict_table_t* sys_fields; 00400 dtuple_t* entry; 00401 dict_field_t* field; 00402 dfield_t* dfield; 00403 byte* ptr; 00404 ibool index_contains_column_prefix_field = FALSE; 00405 ulint j; 00406 00407 ut_ad(index && heap); 00408 00409 for (j = 0; j < index->n_fields; j++) { 00410 if (dict_index_get_nth_field(index, j)->prefix_len > 0) { 00411 index_contains_column_prefix_field = TRUE; 00412 } 00413 } 00414 00415 field = dict_index_get_nth_field(index, i); 00416 00417 sys_fields = dict_sys->sys_fields; 00418 00419 entry = dtuple_create(heap, 3 + DATA_N_SYS_COLS); 00420 00421 /* 0: INDEX_ID -----------------------*/ 00422 dfield = dtuple_get_nth_field(entry, 0); 00423 00424 ptr = mem_heap_alloc(heap, 8); 00425 mach_write_to_8(ptr, index->id); 00426 00427 dfield_set_data(dfield, ptr, 8); 00428 /* 1: POS + PREFIX LENGTH ----------------------------*/ 00429 00430 dfield = dtuple_get_nth_field(entry, 1); 00431 00432 ptr = mem_heap_alloc(heap, 4); 00433 00434 if (index_contains_column_prefix_field) { 00435 /* If there are column prefix fields in the index, then 00436 we store the number of the field to the 2 HIGH bytes 00437 and the prefix length to the 2 low bytes, */ 00438 00439 mach_write_to_4(ptr, (i << 16) + field->prefix_len); 00440 } else { 00441 /* Else we store the number of the field to the 2 LOW bytes. 00442 This is to keep the storage format compatible with 00443 InnoDB versions < 4.0.14. */ 00444 00445 mach_write_to_4(ptr, i); 00446 } 00447 00448 dfield_set_data(dfield, ptr, 4); 00449 /* 4: COL_NAME -------------------------*/ 00450 dfield = dtuple_get_nth_field(entry, 2); 00451 00452 dfield_set_data(dfield, field->name, 00453 ut_strlen(field->name)); 00454 /*---------------------------------*/ 00455 00456 dict_table_copy_types(entry, sys_fields); 00457 00458 return(entry); 00459 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dtuple_t* dict_create_sys_indexes_tuple | ( | dict_index_t * | index, | |
| mem_heap_t * | heap | |||
| ) | [static] |
Definition at line 299 of file dict0crea.c.
References DATA_N_SYS_COLS, dfield_set_data(), dict_sys, dict_table_copy_types(), dict_table_get_low(), dtuple_create(), dtuple_get_nth_field(), FIL_NULL, dict_table_struct::id, index(), mach_write_to_4(), mach_write_to_8(), mem_heap_alloc(), dict_sys_struct::mutex, dict_sys_struct::sys_indexes, ut_ad, and ut_strlen().
Referenced by dict_build_index_def_step().
00301 : the tuple which should be inserted */ 00302 dict_index_t* index, /* in: index */ 00303 mem_heap_t* heap) /* in: memory heap from which the memory for 00304 the built tuple is allocated */ 00305 { 00306 dict_table_t* sys_indexes; 00307 dict_table_t* table; 00308 dtuple_t* entry; 00309 dfield_t* dfield; 00310 byte* ptr; 00311 00312 #ifdef UNIV_SYNC_DEBUG 00313 ut_ad(mutex_own(&(dict_sys->mutex))); 00314 #endif /* UNIV_SYNC_DEBUG */ 00315 ut_ad(index && heap); 00316 00317 sys_indexes = dict_sys->sys_indexes; 00318 00319 table = dict_table_get_low(index->table_name); 00320 00321 entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS); 00322 00323 /* 0: TABLE_ID -----------------------*/ 00324 dfield = dtuple_get_nth_field(entry, 0); 00325 00326 ptr = mem_heap_alloc(heap, 8); 00327 mach_write_to_8(ptr, table->id); 00328 00329 dfield_set_data(dfield, ptr, 8); 00330 /* 1: ID ----------------------------*/ 00331 dfield = dtuple_get_nth_field(entry, 1); 00332 00333 ptr = mem_heap_alloc(heap, 8); 00334 mach_write_to_8(ptr, index->id); 00335 00336 dfield_set_data(dfield, ptr, 8); 00337 /* 4: NAME --------------------------*/ 00338 dfield = dtuple_get_nth_field(entry, 2); 00339 00340 dfield_set_data(dfield, index->name, ut_strlen(index->name)); 00341 /* 5: N_FIELDS ----------------------*/ 00342 dfield = dtuple_get_nth_field(entry, 3); 00343 00344 ptr = mem_heap_alloc(heap, 4); 00345 mach_write_to_4(ptr, index->n_fields); 00346 00347 dfield_set_data(dfield, ptr, 4); 00348 /* 6: TYPE --------------------------*/ 00349 dfield = dtuple_get_nth_field(entry, 4); 00350 00351 ptr = mem_heap_alloc(heap, 4); 00352 mach_write_to_4(ptr, index->type); 00353 00354 dfield_set_data(dfield, ptr, 4); 00355 /* 7: SPACE --------------------------*/ 00356 00357 #if DICT_SYS_INDEXES_SPACE_NO_FIELD != 7 00358 #error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 7" 00359 #endif 00360 00361 dfield = dtuple_get_nth_field(entry, 5); 00362 00363 ptr = mem_heap_alloc(heap, 4); 00364 mach_write_to_4(ptr, index->space); 00365 00366 dfield_set_data(dfield, ptr, 4); 00367 /* 8: PAGE_NO --------------------------*/ 00368 00369 #if DICT_SYS_INDEXES_PAGE_NO_FIELD != 8 00370 #error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 8" 00371 #endif 00372 00373 dfield = dtuple_get_nth_field(entry, 6); 00374 00375 ptr = mem_heap_alloc(heap, 4); 00376 mach_write_to_4(ptr, FIL_NULL); 00377 00378 dfield_set_data(dfield, ptr, 4); 00379 /*--------------------------------*/ 00380 00381 dict_table_copy_types(entry, sys_indexes); 00382 00383 return(entry); 00384 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static dtuple_t* dict_create_sys_tables_tuple | ( | dict_table_t * | table, | |
| mem_heap_t * | heap | |||
| ) | [static] |
Definition at line 34 of file dict0crea.c.
References DATA_N_SYS_COLS, dfield_set_data(), dict_sys, dict_table_copy_types(), DICT_TABLE_ORDINARY, DICT_TF_COMPACT, dtuple_create(), dtuple_get_nth_field(), dict_table_struct::flags, dict_table_struct::id, mach_write_to_4(), mach_write_to_8(), mem_heap_alloc(), memset, dict_table_struct::n_def, dict_table_struct::name, NULL, dict_table_struct::space, dict_sys_struct::sys_tables, ut_ad, and ut_strlen().
00036 : the tuple which should be inserted */ 00037 dict_table_t* table, /* in: table */ 00038 mem_heap_t* heap) /* in: memory heap from which the memory for 00039 the built tuple is allocated */ 00040 { 00041 dict_table_t* sys_tables; 00042 dtuple_t* entry; 00043 dfield_t* dfield; 00044 byte* ptr; 00045 00046 ut_ad(table && heap); 00047 00048 sys_tables = dict_sys->sys_tables; 00049 00050 entry = dtuple_create(heap, 8 + DATA_N_SYS_COLS); 00051 00052 /* 0: NAME -----------------------------*/ 00053 dfield = dtuple_get_nth_field(entry, 0); 00054 00055 dfield_set_data(dfield, table->name, ut_strlen(table->name)); 00056 /* 3: ID -------------------------------*/ 00057 dfield = dtuple_get_nth_field(entry, 1); 00058 00059 ptr = mem_heap_alloc(heap, 8); 00060 mach_write_to_8(ptr, table->id); 00061 00062 dfield_set_data(dfield, ptr, 8); 00063 /* 4: N_COLS ---------------------------*/ 00064 dfield = dtuple_get_nth_field(entry, 2); 00065 00066 #if DICT_TF_COMPACT != 1 00067 #error 00068 #endif 00069 00070 ptr = mem_heap_alloc(heap, 4); 00071 mach_write_to_4(ptr, table->n_def 00072 | ((table->flags & DICT_TF_COMPACT) << 31)); 00073 dfield_set_data(dfield, ptr, 4); 00074 /* 5: TYPE -----------------------------*/ 00075 dfield = dtuple_get_nth_field(entry, 3); 00076 00077 ptr = mem_heap_alloc(heap, 4); 00078 mach_write_to_4(ptr, DICT_TABLE_ORDINARY); 00079 00080 dfield_set_data(dfield, ptr, 4); 00081 /* 6: MIX_ID ---------------------------*/ 00082 dfield = dtuple_get_nth_field(entry, 4); 00083 00084 ptr = mem_heap_alloc(heap, 8); 00085 memset(ptr, 0, 8); 00086 00087 dfield_set_data(dfield, ptr, 8); 00088 /* 7: MIX_LEN --------------------------*/ 00089 00090 dfield = dtuple_get_nth_field(entry, 5); 00091 00092 ptr = mem_heap_alloc(heap, 4); 00093 memset(ptr, 0, 4); 00094 00095 dfield_set_data(dfield, ptr, 4); 00096 /* 8: CLUSTER_NAME ---------------------*/ 00097 dfield = dtuple_get_nth_field(entry, 6); 00098 dfield_set_data(dfield, NULL, UNIV_SQL_NULL); /* not supported */ 00099 00100 /* 9: SPACE ----------------------------*/ 00101 dfield = dtuple_get_nth_field(entry, 7); 00102 00103 ptr = mem_heap_alloc(heap, 4); 00104 mach_write_to_4(ptr, table->space); 00105 00106 dfield_set_data(dfield, ptr, 4); 00107 /*----------------------------------*/ 00108 00109 dict_table_copy_types(entry, sys_tables); 00110 00111 return(entry); 00112 }
Here is the call graph for this function:

Definition at line 891 of file dict0crea.c.
References tab_node_struct::col_def, tab_node_struct::col_no, DB_ERROR, DB_LOCK_WAIT, DB_SUCCESS, dict_build_col_def_step(), dict_build_table_def_step(), dict_sys, dict_table_add_to_cache(), err, trx_struct::error_state, dict_sys_struct::mutex, NULL, que_thr_struct::prev_node, QUE_NODE_CREATE_TABLE, que_node_get_parent(), que_node_get_type(), que_thr_struct::run_node, tab_node_struct::state, tab_node_struct::tab_def, tab_node_struct::table, TABLE_ADD_TO_CACHE, TABLE_BUILD_COL_DEF, TABLE_BUILD_TABLE_DEF, TABLE_COMMIT_WORK, thr_get_trx(), and ut_ad.
Referenced by que_thr_step().
00893 : query thread to run next or NULL */ 00894 que_thr_t* thr) /* in: query thread */ 00895 { 00896 tab_node_t* node; 00897 ulint err = DB_ERROR; 00898 trx_t* trx; 00899 00900 ut_ad(thr); 00901 #ifdef UNIV_SYNC_DEBUG 00902 ut_ad(mutex_own(&(dict_sys->mutex))); 00903 #endif /* UNIV_SYNC_DEBUG */ 00904 00905 trx = thr_get_trx(thr); 00906 00907 node = thr->run_node; 00908 00909 ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_TABLE); 00910 00911 if (thr->prev_node == que_node_get_parent(node)) { 00912 node->state = TABLE_BUILD_TABLE_DEF; 00913 } 00914 00915 if (node->state == TABLE_BUILD_TABLE_DEF) { 00916 00917 /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */ 00918 00919 err = dict_build_table_def_step(thr, node); 00920 00921 if (err != DB_SUCCESS) { 00922 00923 goto function_exit; 00924 } 00925 00926 node->state = TABLE_BUILD_COL_DEF; 00927 node->col_no = 0; 00928 00929 thr->run_node = node->tab_def; 00930 00931 return(thr); 00932 } 00933 00934 if (node->state == TABLE_BUILD_COL_DEF) { 00935 00936 if (node->col_no < (node->table)->n_def) { 00937 00938 err = dict_build_col_def_step(node); 00939 00940 if (err != DB_SUCCESS) { 00941 00942 goto function_exit; 00943 } 00944 00945 node->col_no++; 00946 00947 thr->run_node = node->col_def; 00948 00949 return(thr); 00950 } else { 00951 node->state = TABLE_COMMIT_WORK; 00952 } 00953 } 00954 00955 if (node->state == TABLE_COMMIT_WORK) { 00956 00957 /* Table was correctly defined: do NOT commit the transaction 00958 (CREATE TABLE does NOT do an implicit commit of the current 00959 transaction) */ 00960 00961 node->state = TABLE_ADD_TO_CACHE; 00962 00963 /* thr->run_node = node->commit_node; 00964 00965 return(thr); */ 00966 } 00967 00968 if (node->state == TABLE_ADD_TO_CACHE) { 00969 00970 dict_table_add_to_cache(node->table); 00971 00972 err = DB_SUCCESS; 00973 } 00974 00975 function_exit: 00976 trx->error_state = err; 00977 00978 if (err == DB_SUCCESS) { 00979 /* Ok: do nothing */ 00980 00981 } else if (err == DB_LOCK_WAIT) { 00982 00983 return(NULL); 00984 } else { 00985 /* SQL error detected */ 00986 00987 return(NULL); 00988 } 00989 00990 thr->run_node = que_node_get_parent(node); 00991 00992 return(thr); 00993 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 631 of file dict0crea.c.
References btr_free_but_not_root(), btr_free_root(), dict_sys, DICT_SYS_INDEXES_PAGE_NO_FIELD, DICT_SYS_INDEXES_SPACE_NO_FIELD, dict_table_is_comp(), FIL_NULL, fil_tablespace_exists_in_mem(), MLOG_4BYTES, mtr_read_ulint(), dict_sys_struct::mutex, page_rec_write_index_page_no(), rec_get_nth_field_old(), dict_sys_struct::sys_indexes, ut_a, and ut_ad.
Referenced by row_undo_ins_remove_clust_rec(), and row_upd_clust_step().
00633 : record in the clustered index of SYS_INDEXES 00634 table */ 00635 mtr_t* mtr) /* in: mtr having the latch on the record page */ 00636 { 00637 ulint root_page_no; 00638 ulint space; 00639 byte* ptr; 00640 ulint len; 00641 00642 #ifdef UNIV_SYNC_DEBUG 00643 ut_ad(mutex_own(&(dict_sys->mutex))); 00644 #endif /* UNIV_SYNC_DEBUG */ 00645 00646 ut_a(!dict_table_is_comp(dict_sys->sys_indexes)); 00647 ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); 00648 00649 ut_ad(len == 4); 00650 00651 root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); 00652 00653 if (root_page_no == FIL_NULL) { 00654 /* The tree has already been freed */ 00655 00656 return; 00657 } 00658 00659 ptr = rec_get_nth_field_old(rec, 00660 DICT_SYS_INDEXES_SPACE_NO_FIELD, &len); 00661 00662 ut_ad(len == 4); 00663 00664 space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); 00665 00666 if (!fil_tablespace_exists_in_mem(space)) { 00667 /* It is a single table tablespace and the .ibd file is 00668 missing: do nothing */ 00669 00670 return; 00671 } 00672 00673 /* We free all the pages but the root page first; this operation 00674 may span several mini-transactions */ 00675 00676 btr_free_but_not_root(space, root_page_no); 00677 00678 /* Then we free the root page in the same mini-transaction where 00679 we write FIL_NULL to the appropriate field in the SYS_INDEXES 00680 record: this mini-transaction marks the B-tree totally freed */ 00681 00682 /* printf("Dropping index tree in space %lu root page %lu\n", space, 00683 root_page_no); */ 00684 btr_free_root(space, root_page_no, mtr); 00685 00686 page_rec_write_index_page_no(rec, 00687 DICT_SYS_INDEXES_PAGE_NO_FIELD, FIL_NULL, mtr); 00688 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_foreign_eval_sql | ( | pars_info_t * | info, | |
| const char * | sql, | |||
| dict_table_t * | table, | |||
| dict_foreign_t * | foreign, | |||
| trx_t * | trx | |||
| ) |
Definition at line 1233 of file dict0crea.c.
References DB_DUPLICATE_KEY, DB_SUCCESS, dict_foreign_err_file, dict_foreign_err_mutex, error, FALSE, dict_foreign_struct::id, mutex_enter, mutex_exit(), dict_table_struct::name, que_eval_sql(), TRUE, ut_print_name(), and ut_print_timestamp().
Referenced by dict_create_add_foreign_field_to_dictionary(), and dict_create_add_foreign_to_dictionary().
01235 : error code or DB_SUCCESS */ 01236 pars_info_t* info, /* in: info struct, or NULL */ 01237 const char* sql, /* in: SQL string to evaluate */ 01238 dict_table_t* table, /* in: table */ 01239 dict_foreign_t* foreign,/* in: foreign */ 01240 trx_t* trx) /* in: transaction */ 01241 { 01242 ulint error; 01243 FILE* ef = dict_foreign_err_file; 01244 01245 error = que_eval_sql(info, sql, FALSE, trx); 01246 01247 if (error == DB_DUPLICATE_KEY) { 01248 mutex_enter(&dict_foreign_err_mutex); 01249 rewind(ef); 01250 ut_print_timestamp(ef); 01251 fputs(" Error in foreign key constraint creation for table ", 01252 ef); 01253 ut_print_name(ef, trx, TRUE, table->name); 01254 fputs(".\nA foreign key constraint of name ", ef); 01255 ut_print_name(ef, trx, FALSE, foreign->id); 01256 fputs("\nalready exists." 01257 " (Note that internally InnoDB adds 'databasename/'\n" 01258 "in front of the user-defined constraint name).\n", 01259 ef); 01260 fputs("Note that InnoDB's FOREIGN KEY system tables store\n" 01261 "constraint names as case-insensitive, with the\n" 01262 "MySQL standard latin1_swedish_ci collation. If you\n" 01263 "create tables or databases whose names differ only in\n" 01264 "the character case, then collisions in constraint\n" 01265 "names can occur. Workaround: name your constraints\n" 01266 "explicitly with unique names.\n", 01267 ef); 01268 01269 mutex_exit(&dict_foreign_err_mutex); 01270 01271 return(error); 01272 } 01273 01274 if (error != DB_SUCCESS) { 01275 fprintf(stderr, 01276 "InnoDB: Foreign key constraint creation failed:\n" 01277 "InnoDB: internal error number %lu\n", (ulong) error); 01278 01279 mutex_enter(&dict_foreign_err_mutex); 01280 ut_print_timestamp(ef); 01281 fputs(" Internal error in foreign key constraint creation" 01282 " for table ", ef); 01283 ut_print_name(ef, trx, TRUE, table->name); 01284 fputs(".\n" 01285 "See the MySQL .err log in the datadir for more information.\n", ef); 01286 mutex_exit(&dict_foreign_err_mutex); 01287 01288 return(error); 01289 } 01290 01291 return(DB_SUCCESS); 01292 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_truncate_index_tree | ( | dict_table_t * | table, | |
| rec_t * | rec, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 694 of file dict0crea.c.
References btr_create(), btr_free_but_not_root(), btr_free_root(), btr_page_get(), dict_sys, DICT_SYS_INDEXES_PAGE_NO_FIELD, DICT_SYS_INDEXES_SPACE_NO_FIELD, DICT_SYS_INDEXES_TYPE_FIELD, dict_table_is_comp(), FIL_NULL, fil_tablespace_exists_in_mem(), index(), dict_table_struct::indexes, mach_read_from_4(), mach_read_from_8(), MLOG_4BYTES, mtr_commit(), mtr_read_ulint(), mtr_start(), dict_sys_struct::mutex, dict_table_struct::name, NULL, page_is_comp(), page_rec_write_index_page_no(), rec_get_nth_field_old(), RW_X_LATCH, dict_sys_struct::sys_indexes, ut_a, ut_ad, ut_dulint_cmp(), ut_dulint_get_high(), ut_dulint_get_low(), UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, and ut_print_timestamp().
Referenced by row_truncate_table_for_mysql().
00696 : new root page number, or 00697 FIL_NULL on failure */ 00698 dict_table_t* table, /* in: the table the index belongs to */ 00699 rec_t* rec, /* in: record in the clustered index of 00700 SYS_INDEXES table */ 00701 mtr_t* mtr) /* in: mtr having the latch 00702 on the record page. The mtr may be 00703 committed and restarted in this call. */ 00704 { 00705 ulint root_page_no; 00706 ulint space; 00707 ulint type; 00708 dulint index_id; 00709 byte* ptr; 00710 ulint len; 00711 ulint comp; 00712 dict_index_t* index; 00713 00714 #ifdef UNIV_SYNC_DEBUG 00715 ut_ad(mutex_own(&(dict_sys->mutex))); 00716 #endif /* UNIV_SYNC_DEBUG */ 00717 00718 ut_a(!dict_table_is_comp(dict_sys->sys_indexes)); 00719 ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); 00720 00721 ut_ad(len == 4); 00722 00723 root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); 00724 00725 if (root_page_no == FIL_NULL) { 00726 /* The tree has been freed. */ 00727 00728 ut_print_timestamp(stderr); 00729 fprintf(stderr, " InnoDB: Trying to TRUNCATE" 00730 " a missing index of table %s!\n", table->name); 00731 return(FIL_NULL); 00732 } 00733 00734 ptr = rec_get_nth_field_old(rec, 00735 DICT_SYS_INDEXES_SPACE_NO_FIELD, &len); 00736 00737 ut_ad(len == 4); 00738 00739 space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); 00740 00741 if (!fil_tablespace_exists_in_mem(space)) { 00742 /* It is a single table tablespace and the .ibd file is 00743 missing: do nothing */ 00744 00745 ut_print_timestamp(stderr); 00746 fprintf(stderr, " InnoDB: Trying to TRUNCATE" 00747 " a missing .ibd file of table %s!\n", table->name); 00748 return(FIL_NULL); 00749 } 00750 00751 ptr = rec_get_nth_field_old(rec, 00752 DICT_SYS_INDEXES_TYPE_FIELD, &len); 00753 ut_ad(len == 4); 00754 type = mach_read_from_4(ptr); 00755 00756 ptr = rec_get_nth_field_old(rec, 1, &len); 00757 ut_ad(len == 8); 00758 index_id = mach_read_from_8(ptr); 00759 00760 /* We free all the pages but the root page first; this operation 00761 may span several mini-transactions */ 00762 00763 btr_free_but_not_root(space, root_page_no); 00764 00765 /* Then we free the root page in the same mini-transaction where 00766 we create the b-tree and write its new root page number to the 00767 appropriate field in the SYS_INDEXES record: this mini-transaction 00768 marks the B-tree totally truncated */ 00769 00770 comp = page_is_comp(btr_page_get( 00771 space, root_page_no, RW_X_LATCH, mtr)); 00772 00773 btr_free_root(space, root_page_no, mtr); 00774 /* We will temporarily write FIL_NULL to the PAGE_NO field 00775 in SYS_INDEXES, so that the database will not get into an 00776 inconsistent state in case it crashes between the mtr_commit() 00777 below and the following mtr_commit() call. */ 00778 page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, 00779 FIL_NULL, mtr); 00780 00781 /* We will need to commit the mini-transaction in order to avoid 00782 deadlocks in the btr_create() call, because otherwise we would 00783 be freeing and allocating pages in the same mini-transaction. */ 00784 mtr_commit(mtr); 00785 /* mtr_commit() will invalidate rec. */ 00786 rec = NULL; 00787 mtr_start(mtr); 00788 00789 /* Find the index corresponding to this SYS_INDEXES record. */ 00790 for (index = UT_LIST_GET_FIRST(table->indexes); 00791 index; 00792 index = UT_LIST_GET_NEXT(indexes, index)) { 00793 if (!ut_dulint_cmp(index->id, index_id)) { 00794 break; 00795 } 00796 } 00797 00798 root_page_no = btr_create(type, space, index_id, comp, mtr); 00799 if (index) { 00800 index->tree->page = root_page_no; 00801 } else { 00802 ut_print_timestamp(stderr); 00803 fprintf(stderr, 00804 " InnoDB: Index %lu %lu of table %s is missing\n" 00805 "InnoDB: from the data dictionary during TRUNCATE!\n", 00806 ut_dulint_get_high(index_id), 00807 ut_dulint_get_low(index_id), 00808 table->name); 00809 } 00810 00811 return(root_page_no); 00812 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ind_node_t* ind_create_graph_create | ( | dict_index_t * | index, | |
| mem_heap_t * | heap | |||
| ) |
Definition at line 854 of file dict0crea.c.
References ind_node_struct::commit_node, commit_node_create(), ind_node_struct::common, ins_node_struct::common, commit_node_struct::common, dict_sys, ind_node_struct::field_def, FIL_NULL, ind_node_struct::heap, ind_node_struct::ind_def, ind_node_struct::index, index(), INDEX_BUILD_INDEX_DEF, INS_DIRECT, ins_node_create(), mem_heap_alloc(), mem_heap_create, ind_node_struct::page_no, que_common_struct::parent, QUE_NODE_CREATE_INDEX, ind_node_struct::state, dict_sys_struct::sys_fields, dict_sys_struct::sys_indexes, and que_common_struct::type.
Referenced by pars_create_index(), and row_create_index_for_mysql().
00856 : index create node */ 00857 dict_index_t* index, /* in: index to create, built as a memory data 00858 structure */ 00859 mem_heap_t* heap) /* in: heap where created */ 00860 { 00861 ind_node_t* node; 00862 00863 node = mem_heap_alloc(heap, sizeof(ind_node_t)); 00864 00865 node->common.type = QUE_NODE_CREATE_INDEX; 00866 00867 node->index = index; 00868 00869 node->state = INDEX_BUILD_INDEX_DEF; 00870 node->page_no = FIL_NULL; 00871 node->heap = mem_heap_create(256); 00872 00873 node->ind_def = ins_node_create(INS_DIRECT, 00874 dict_sys->sys_indexes, heap); 00875 node->ind_def->common.parent = node; 00876 00877 node->field_def = ins_node_create(INS_DIRECT, 00878 dict_sys->sys_fields, heap); 00879 node->field_def->common.parent = node; 00880 00881 node->commit_node = commit_node_create(heap); 00882 node->commit_node->common.parent = node; 00883 00884 return(node); 00885 }
Here is the call graph for this function:

Here is the caller graph for this function:

| tab_node_t* tab_create_graph_create | ( | dict_table_t * | table, | |
| mem_heap_t * | heap | |||
| ) |
Definition at line 818 of file dict0crea.c.
References tab_node_struct::col_def, tab_node_struct::commit_node, commit_node_create(), tab_node_struct::common, ins_node_struct::common, commit_node_struct::common, dict_sys, tab_node_struct::heap, INS_DIRECT, ins_node_create(), mem_heap_alloc(), mem_heap_create, que_common_struct::parent, QUE_NODE_CREATE_TABLE, tab_node_struct::state, dict_sys_struct::sys_columns, dict_sys_struct::sys_tables, tab_node_struct::tab_def, tab_node_struct::table, TABLE_BUILD_TABLE_DEF, and que_common_struct::type.
Referenced by pars_create_table(), and row_create_table_for_mysql().
00820 : table create node */ 00821 dict_table_t* table, /* in: table to create, built as a memory data 00822 structure */ 00823 mem_heap_t* heap) /* in: heap where created */ 00824 { 00825 tab_node_t* node; 00826 00827 node = mem_heap_alloc(heap, sizeof(tab_node_t)); 00828 00829 node->common.type = QUE_NODE_CREATE_TABLE; 00830 00831 node->table = table; 00832 00833 node->state = TABLE_BUILD_TABLE_DEF; 00834 node->heap = mem_heap_create(256); 00835 00836 node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables, 00837 heap); 00838 node->tab_def->common.parent = node; 00839 00840 node->col_def = ins_node_create(INS_DIRECT, dict_sys->sys_columns, 00841 heap); 00842 node->col_def->common.parent = node; 00843 00844 node->commit_node = commit_node_create(heap); 00845 node->commit_node->common.parent = node; 00846 00847 return(node); 00848 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.4.7

