Loading innobase/btr/btr0cur.c +7 −4 Original line number Diff line number Diff line Loading @@ -228,6 +228,7 @@ btr_cur_search_to_nth_level( ulint insert_planned; ulint buf_mode; ulint estimate; ulint ignore_sec_unique; ulint root_height; #ifdef BTR_CUR_ADAPT btr_search_t* info; Loading @@ -246,7 +247,9 @@ btr_cur_search_to_nth_level( #endif insert_planned = latch_mode & BTR_INSERT; estimate = latch_mode & BTR_ESTIMATE; latch_mode = latch_mode & ~(BTR_INSERT | BTR_ESTIMATE); ignore_sec_unique = latch_mode & BTR_IGNORE_SEC_UNIQUE; latch_mode = latch_mode & ~(BTR_INSERT | BTR_ESTIMATE | BTR_IGNORE_SEC_UNIQUE); ut_ad(!insert_planned || (mode == PAGE_CUR_LE)); Loading Loading @@ -343,7 +346,8 @@ btr_cur_search_to_nth_level( rw_latch = latch_mode; if (insert_planned && ibuf_should_try(index)) { if (insert_planned && ibuf_should_try(index, ignore_sec_unique)) { /* Try insert to the insert buffer if the page is not in the buffer pool */ Loading @@ -356,7 +360,6 @@ btr_cur_search_to_nth_level( buf_mode, IB__FILE__, __LINE__, mtr); if (page == NULL) { /* This must be a search to perform an insert; try insert to the insert buffer */ Loading @@ -365,7 +368,7 @@ btr_cur_search_to_nth_level( ut_ad(insert_planned); ut_ad(cursor->thr); if (ibuf_should_try(index) && if (ibuf_should_try(index, ignore_sec_unique) && ibuf_insert(tuple, index, space, page_no, cursor->thr)) { /* Insertion to the insert buffer succeeded */ Loading innobase/dict/dict0crea.c +2 −1 Original line number Diff line number Diff line Loading @@ -1201,7 +1201,8 @@ dict_create_add_foreigns_to_dictionary( ut_dulint_get_low(id), table->name, foreign->referenced_table_name, foreign->n_fields); foreign->n_fields + (foreign->type << 24)); for (i = 0; i < foreign->n_fields; i++) { Loading innobase/dict/dict0dict.c +126 −35 Original line number Diff line number Diff line Loading @@ -1648,7 +1648,7 @@ dict_foreign_find_index( ->col->name; if (ut_strlen(columns[i]) != ut_strlen(col_name) || 0 != ut_memcmp(columns[i], || 0 != ut_cmp_in_lower_case(columns[i], col_name, ut_strlen(col_name))) { break; Loading Loading @@ -1853,8 +1853,9 @@ dict_scan_col( ibool* success,/* out: TRUE if success */ dict_table_t* table, /* in: table in which the column is */ dict_col_t** column, /* out: pointer to column if success */ char** column_name)/* out: pointer to column->name if char** column_name,/* out: pointer to column->name if success */ ulint* column_name_len)/* out: column name length */ { dict_col_t* col; char* old_ptr; Loading Loading @@ -1882,6 +1883,13 @@ dict_scan_col( ptr++; } *column_name_len = (ulint)(ptr - old_ptr); if (table == NULL) { *success = TRUE; *column = NULL; *column_name = old_ptr; } else { for (i = 0; i < dict_table_get_n_cols(table); i++) { col = dict_table_get_nth_col(table, i); Loading @@ -1898,6 +1906,7 @@ dict_scan_col( break; } } } if (*ptr == '`') { ptr++; Loading @@ -1914,14 +1923,18 @@ dict_scan_table_name( /*=================*/ /* out: scanned to */ char* ptr, /* in: scanned to */ dict_table_t** table, /* out: table object or NULL if error */ char* name) /* in: foreign key table name */ dict_table_t** table, /* out: table object or NULL */ char* name, /* in: foreign key table name */ ibool* success,/* out: TRUE if ok name found */ char* second_table_name)/* in/out: buffer where to store the referenced table name; must be at least 2500 bytes */ { char* dot_ptr = NULL; char* old_ptr; ulint i; char second_table_name[10000]; *success = FALSE; *table = NULL; while (isspace(*ptr)) { Loading @@ -1947,7 +1960,7 @@ dict_scan_table_name( ptr++; } if (ptr - old_ptr > 9000) { if (ptr - old_ptr > 2000) { return(old_ptr); } Loading Loading @@ -1978,6 +1991,8 @@ dict_scan_table_name( second_table_name[ptr - old_ptr] = '\0'; } *success = TRUE; *table = dict_table_get_low(second_table_name); if (*ptr == '`') { Loading Loading @@ -2043,8 +2058,11 @@ dict_create_foreign_constraints( ibool success; ulint error; ulint i; dict_col_t* columns[1000]; char* column_names[1000]; ulint j; dict_col_t* columns[500]; char* column_names[500]; ulint column_name_lens[500]; char referenced_table_name[2500]; ut_ad(mutex_own(&(dict_sys->mutex))); Loading Loading @@ -2090,7 +2108,7 @@ dict_create_foreign_constraints( /* Scan the columns in the first list */ col_loop1: ptr = dict_scan_col(ptr, &success, table, columns + i, column_names + i); column_names + i, column_name_lens + i); if (!success) { return(DB_CANNOT_ADD_CONSTRAINT); } Loading Loading @@ -2141,9 +2159,13 @@ dict_create_foreign_constraints( 1 + ut_strlen(columns[i]->name)); } ptr = dict_scan_table_name(ptr, &referenced_table, name); ptr = dict_scan_table_name(ptr, &referenced_table, name, &success, referenced_table_name); /* Note that referenced_table can be NULL if the user has suppressed checking of foreign key constraints! */ if (!referenced_table) { if (!success || (!referenced_table && trx->check_foreigns)) { dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); Loading @@ -2161,7 +2183,7 @@ dict_create_foreign_constraints( col_loop2: ptr = dict_scan_col(ptr, &success, referenced_table, columns + i, column_names + i); column_names + i, column_name_lens + i); i++; if (!success) { Loading @@ -2183,43 +2205,104 @@ dict_create_foreign_constraints( return(DB_CANNOT_ADD_CONSTRAINT); } ptr = dict_accept(ptr, "ON", &success); if (!success) { goto try_find_index; } ptr = dict_accept(ptr, "DELETE", &success); if (!success) { goto try_find_index; } ptr = dict_accept(ptr, "CASCADE", &success); if (success) { foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE; goto try_find_index; } ptr = dict_accept(ptr, "SET", &success); if (!success) { goto try_find_index; } ptr = dict_accept(ptr, "NULL", &success); if (success) { for (j = 0; j < foreign->n_fields; j++) { if ((dict_index_get_nth_type( foreign->foreign_index, j)->prtype) & DATA_NOT_NULL) { /* It is not sensible to define SET NULL if the column is not allowed to be NULL! */ dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); } } foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL; goto try_find_index; } try_find_index: /* Try to find an index which contains the columns as the first fields and in the right order, and the types are the same as in foreign->foreign_index */ index = dict_foreign_find_index(referenced_table, column_names, i, if (referenced_table) { index = dict_foreign_find_index(referenced_table, column_names, i, foreign->foreign_index); if (!index) { dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); } } else { ut_a(trx->check_foreigns == FALSE); index = NULL; } foreign->referenced_index = index; foreign->referenced_table = referenced_table; foreign->referenced_table_name = mem_heap_alloc(foreign->heap, 1 + ut_strlen(referenced_table->name)); 1 + ut_strlen(referenced_table_name)); ut_memcpy(foreign->referenced_table_name, referenced_table->name, 1 + ut_strlen(referenced_table->name)); ut_memcpy(foreign->referenced_table_name, referenced_table_name, 1 + ut_strlen(referenced_table_name)); foreign->referenced_col_names = mem_heap_alloc(foreign->heap, i * sizeof(void*)); for (i = 0; i < foreign->n_fields; i++) { foreign->referenced_col_names[i] = mem_heap_alloc(foreign->heap, 1 + ut_strlen(columns[i]->name)); ut_memcpy( foreign->referenced_col_names[i], columns[i]->name, 1 + ut_strlen(columns[i]->name)); 1 + column_name_lens[i]); ut_memcpy(foreign->referenced_col_names[i], column_names[i], column_name_lens[i]); (foreign->referenced_col_names[i])[column_name_lens[i]] = '\0'; } /* We found an ok constraint definition: add to the lists */ UT_LIST_ADD_LAST(foreign_list, table->foreign_list, foreign); UT_LIST_ADD_LAST(referenced_list, referenced_table->referenced_list, if (referenced_table) { UT_LIST_ADD_LAST(referenced_list, referenced_table->referenced_list, foreign); } goto loop; } Loading Loading @@ -3034,6 +3117,14 @@ dict_print_info_on_foreign_keys_in_create_format( buf2 += sprintf(buf2, ")"); if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { buf2 += sprintf(buf2, " ON DELETE CASCADE"); } if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { buf2 += sprintf(buf2, " ON DELETE SET NULL"); } foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } Loading innobase/dict/dict0load.c +5 −0 Original line number Diff line number Diff line Loading @@ -947,6 +947,11 @@ dict_load_foreign( ut_a(len == 4); /* We store the type to the bits 24-31 of n_fields */ foreign->type = foreign->n_fields >> 24; foreign->n_fields = foreign->n_fields & 0xFFFFFF; foreign->id = mem_heap_alloc(foreign->heap, ut_strlen(id) + 1); ut_memcpy(foreign->id, id, ut_strlen(id) + 1); Loading innobase/dict/dict0mem.c +3 −1 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ dict_mem_table_create( table->mem_fix = 0; table->n_mysql_handles_opened = 0; table->n_foreign_key_checks_running = 0; table->cached = FALSE; Loading Loading @@ -235,6 +236,7 @@ dict_mem_foreign_create(void) foreign->id = NULL; foreign->type = 0; foreign->foreign_table_name = NULL; foreign->foreign_table = NULL; foreign->foreign_col_names = NULL; Loading Loading
innobase/btr/btr0cur.c +7 −4 Original line number Diff line number Diff line Loading @@ -228,6 +228,7 @@ btr_cur_search_to_nth_level( ulint insert_planned; ulint buf_mode; ulint estimate; ulint ignore_sec_unique; ulint root_height; #ifdef BTR_CUR_ADAPT btr_search_t* info; Loading @@ -246,7 +247,9 @@ btr_cur_search_to_nth_level( #endif insert_planned = latch_mode & BTR_INSERT; estimate = latch_mode & BTR_ESTIMATE; latch_mode = latch_mode & ~(BTR_INSERT | BTR_ESTIMATE); ignore_sec_unique = latch_mode & BTR_IGNORE_SEC_UNIQUE; latch_mode = latch_mode & ~(BTR_INSERT | BTR_ESTIMATE | BTR_IGNORE_SEC_UNIQUE); ut_ad(!insert_planned || (mode == PAGE_CUR_LE)); Loading Loading @@ -343,7 +346,8 @@ btr_cur_search_to_nth_level( rw_latch = latch_mode; if (insert_planned && ibuf_should_try(index)) { if (insert_planned && ibuf_should_try(index, ignore_sec_unique)) { /* Try insert to the insert buffer if the page is not in the buffer pool */ Loading @@ -356,7 +360,6 @@ btr_cur_search_to_nth_level( buf_mode, IB__FILE__, __LINE__, mtr); if (page == NULL) { /* This must be a search to perform an insert; try insert to the insert buffer */ Loading @@ -365,7 +368,7 @@ btr_cur_search_to_nth_level( ut_ad(insert_planned); ut_ad(cursor->thr); if (ibuf_should_try(index) && if (ibuf_should_try(index, ignore_sec_unique) && ibuf_insert(tuple, index, space, page_no, cursor->thr)) { /* Insertion to the insert buffer succeeded */ Loading
innobase/dict/dict0crea.c +2 −1 Original line number Diff line number Diff line Loading @@ -1201,7 +1201,8 @@ dict_create_add_foreigns_to_dictionary( ut_dulint_get_low(id), table->name, foreign->referenced_table_name, foreign->n_fields); foreign->n_fields + (foreign->type << 24)); for (i = 0; i < foreign->n_fields; i++) { Loading
innobase/dict/dict0dict.c +126 −35 Original line number Diff line number Diff line Loading @@ -1648,7 +1648,7 @@ dict_foreign_find_index( ->col->name; if (ut_strlen(columns[i]) != ut_strlen(col_name) || 0 != ut_memcmp(columns[i], || 0 != ut_cmp_in_lower_case(columns[i], col_name, ut_strlen(col_name))) { break; Loading Loading @@ -1853,8 +1853,9 @@ dict_scan_col( ibool* success,/* out: TRUE if success */ dict_table_t* table, /* in: table in which the column is */ dict_col_t** column, /* out: pointer to column if success */ char** column_name)/* out: pointer to column->name if char** column_name,/* out: pointer to column->name if success */ ulint* column_name_len)/* out: column name length */ { dict_col_t* col; char* old_ptr; Loading Loading @@ -1882,6 +1883,13 @@ dict_scan_col( ptr++; } *column_name_len = (ulint)(ptr - old_ptr); if (table == NULL) { *success = TRUE; *column = NULL; *column_name = old_ptr; } else { for (i = 0; i < dict_table_get_n_cols(table); i++) { col = dict_table_get_nth_col(table, i); Loading @@ -1898,6 +1906,7 @@ dict_scan_col( break; } } } if (*ptr == '`') { ptr++; Loading @@ -1914,14 +1923,18 @@ dict_scan_table_name( /*=================*/ /* out: scanned to */ char* ptr, /* in: scanned to */ dict_table_t** table, /* out: table object or NULL if error */ char* name) /* in: foreign key table name */ dict_table_t** table, /* out: table object or NULL */ char* name, /* in: foreign key table name */ ibool* success,/* out: TRUE if ok name found */ char* second_table_name)/* in/out: buffer where to store the referenced table name; must be at least 2500 bytes */ { char* dot_ptr = NULL; char* old_ptr; ulint i; char second_table_name[10000]; *success = FALSE; *table = NULL; while (isspace(*ptr)) { Loading @@ -1947,7 +1960,7 @@ dict_scan_table_name( ptr++; } if (ptr - old_ptr > 9000) { if (ptr - old_ptr > 2000) { return(old_ptr); } Loading Loading @@ -1978,6 +1991,8 @@ dict_scan_table_name( second_table_name[ptr - old_ptr] = '\0'; } *success = TRUE; *table = dict_table_get_low(second_table_name); if (*ptr == '`') { Loading Loading @@ -2043,8 +2058,11 @@ dict_create_foreign_constraints( ibool success; ulint error; ulint i; dict_col_t* columns[1000]; char* column_names[1000]; ulint j; dict_col_t* columns[500]; char* column_names[500]; ulint column_name_lens[500]; char referenced_table_name[2500]; ut_ad(mutex_own(&(dict_sys->mutex))); Loading Loading @@ -2090,7 +2108,7 @@ dict_create_foreign_constraints( /* Scan the columns in the first list */ col_loop1: ptr = dict_scan_col(ptr, &success, table, columns + i, column_names + i); column_names + i, column_name_lens + i); if (!success) { return(DB_CANNOT_ADD_CONSTRAINT); } Loading Loading @@ -2141,9 +2159,13 @@ dict_create_foreign_constraints( 1 + ut_strlen(columns[i]->name)); } ptr = dict_scan_table_name(ptr, &referenced_table, name); ptr = dict_scan_table_name(ptr, &referenced_table, name, &success, referenced_table_name); /* Note that referenced_table can be NULL if the user has suppressed checking of foreign key constraints! */ if (!referenced_table) { if (!success || (!referenced_table && trx->check_foreigns)) { dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); Loading @@ -2161,7 +2183,7 @@ dict_create_foreign_constraints( col_loop2: ptr = dict_scan_col(ptr, &success, referenced_table, columns + i, column_names + i); column_names + i, column_name_lens + i); i++; if (!success) { Loading @@ -2183,43 +2205,104 @@ dict_create_foreign_constraints( return(DB_CANNOT_ADD_CONSTRAINT); } ptr = dict_accept(ptr, "ON", &success); if (!success) { goto try_find_index; } ptr = dict_accept(ptr, "DELETE", &success); if (!success) { goto try_find_index; } ptr = dict_accept(ptr, "CASCADE", &success); if (success) { foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE; goto try_find_index; } ptr = dict_accept(ptr, "SET", &success); if (!success) { goto try_find_index; } ptr = dict_accept(ptr, "NULL", &success); if (success) { for (j = 0; j < foreign->n_fields; j++) { if ((dict_index_get_nth_type( foreign->foreign_index, j)->prtype) & DATA_NOT_NULL) { /* It is not sensible to define SET NULL if the column is not allowed to be NULL! */ dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); } } foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL; goto try_find_index; } try_find_index: /* Try to find an index which contains the columns as the first fields and in the right order, and the types are the same as in foreign->foreign_index */ index = dict_foreign_find_index(referenced_table, column_names, i, if (referenced_table) { index = dict_foreign_find_index(referenced_table, column_names, i, foreign->foreign_index); if (!index) { dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); } } else { ut_a(trx->check_foreigns == FALSE); index = NULL; } foreign->referenced_index = index; foreign->referenced_table = referenced_table; foreign->referenced_table_name = mem_heap_alloc(foreign->heap, 1 + ut_strlen(referenced_table->name)); 1 + ut_strlen(referenced_table_name)); ut_memcpy(foreign->referenced_table_name, referenced_table->name, 1 + ut_strlen(referenced_table->name)); ut_memcpy(foreign->referenced_table_name, referenced_table_name, 1 + ut_strlen(referenced_table_name)); foreign->referenced_col_names = mem_heap_alloc(foreign->heap, i * sizeof(void*)); for (i = 0; i < foreign->n_fields; i++) { foreign->referenced_col_names[i] = mem_heap_alloc(foreign->heap, 1 + ut_strlen(columns[i]->name)); ut_memcpy( foreign->referenced_col_names[i], columns[i]->name, 1 + ut_strlen(columns[i]->name)); 1 + column_name_lens[i]); ut_memcpy(foreign->referenced_col_names[i], column_names[i], column_name_lens[i]); (foreign->referenced_col_names[i])[column_name_lens[i]] = '\0'; } /* We found an ok constraint definition: add to the lists */ UT_LIST_ADD_LAST(foreign_list, table->foreign_list, foreign); UT_LIST_ADD_LAST(referenced_list, referenced_table->referenced_list, if (referenced_table) { UT_LIST_ADD_LAST(referenced_list, referenced_table->referenced_list, foreign); } goto loop; } Loading Loading @@ -3034,6 +3117,14 @@ dict_print_info_on_foreign_keys_in_create_format( buf2 += sprintf(buf2, ")"); if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { buf2 += sprintf(buf2, " ON DELETE CASCADE"); } if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { buf2 += sprintf(buf2, " ON DELETE SET NULL"); } foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } Loading
innobase/dict/dict0load.c +5 −0 Original line number Diff line number Diff line Loading @@ -947,6 +947,11 @@ dict_load_foreign( ut_a(len == 4); /* We store the type to the bits 24-31 of n_fields */ foreign->type = foreign->n_fields >> 24; foreign->n_fields = foreign->n_fields & 0xFFFFFF; foreign->id = mem_heap_alloc(foreign->heap, ut_strlen(id) + 1); ut_memcpy(foreign->id, id, ut_strlen(id) + 1); Loading
innobase/dict/dict0mem.c +3 −1 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ dict_mem_table_create( table->mem_fix = 0; table->n_mysql_handles_opened = 0; table->n_foreign_key_checks_running = 0; table->cached = FALSE; Loading Loading @@ -235,6 +236,7 @@ dict_mem_foreign_create(void) foreign->id = NULL; foreign->type = 0; foreign->foreign_table_name = NULL; foreign->foreign_table = NULL; foreign->foreign_col_names = NULL; Loading