51 #define ROW_INS_PREV 1
52 #define ROW_INS_NEXT 2
81 node->ins_type = ins_type;
83 node->
state = INS_NODE_SET_IX_LOCK;
94 node->magic_n = INS_NODE_MAGIC_N;
110 ut_ad(node->entry_sys_heap);
114 index = dict_table_get_first_index(node->
table);
116 while (index != NULL) {
118 node->entry_sys_heap);
121 index = dict_table_get_next_index(index);
129 row_ins_alloc_sys_fields(
142 heap = node->entry_sys_heap;
144 ut_ad(row && table && heap);
149 col = dict_table_get_sys_col(table, DATA_ROW_ID);
157 node->row_id_buf = ptr;
161 col = dict_table_get_sys_col(table, DATA_TRX_ID);
168 node->trx_id_buf = ptr;
172 col = dict_table_get_sys_col(table, DATA_ROLL_PTR);
191 node->
state = INS_NODE_SET_IX_LOCK;
205 row_ins_alloc_sys_fields(node);
220 row_ins_sec_index_entry_by_modify(
256 err = btr_cur_optimistic_update(BTR_KEEP_SYS_FLAG, cursor,
257 update, 0, thr, mtr);
261 case DB_ZIP_OVERFLOW:
266 if (buf_LRU_buf_pool_running_out()) {
268 err = DB_LOCK_TABLE_FULL;
273 err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG, cursor,
274 &heap, &dummy_big_rec, update,
276 ut_ad(!dummy_big_rec);
291 row_ins_clust_index_entry_by_modify(
333 err = btr_cur_optimistic_update(0, cursor, update, 0, thr,
338 case DB_ZIP_OVERFLOW:
343 if (buf_LRU_buf_pool_running_out()) {
345 return(DB_LOCK_TABLE_FULL);
348 err = btr_cur_pessimistic_update(0, cursor,
349 heap, big_rec, update,
362 row_ins_cascade_ancestor_updates_table(
376 if (upd_node->
table == table && upd_node->is_delete == FALSE) {
395 row_ins_cascade_n_ancestors(
400 ulint n_ancestors = 0;
424 row_ins_cascade_calc_update_vec(
440 upd_t* parent_update;
442 ulint n_fields_updated;
443 ulint parent_field_no;
458 parent_table = node->
table;
461 parent_update = node->
update;
468 n_fields_updated = 0;
470 for (i = 0; i < foreign->
n_fields; i++) {
472 parent_field_no = dict_table_get_nth_col_pos(
476 for (j = 0; j < parent_update->
n_fields; j++) {
477 parent_ufield = parent_update->
fields + j;
479 if (parent_ufield->
field_no == parent_field_no) {
491 ufield = update->
fields + n_fields_updated;
494 = dict_table_get_nth_col_pos(
508 && (col->
prtype & DATA_NOT_NULL)) {
510 return(ULINT_UNDEFINED);
517 && dtype_get_at_most_n_mbchars(
521 static_cast<const char *>(dfield_get_data(&ufield->
new_val)))
524 return(ULINT_UNDEFINED);
539 if (min_size > ufield_len) {
549 pad = padded_data + ufield_len;
550 pad_len = min_size - ufield_len;
553 dfield_get_data(&ufield
559 ut_ad(!(ufield_len % mbminlen));
560 ut_ad(!(min_size % mbminlen));
565 == DATA_MYSQL_BINARY_CHARSET_COLL) {
567 return(ULINT_UNDEFINED);
573 padded_data, min_size);
581 update->
n_fields = n_fields_updated;
583 return(n_fields_updated);
591 row_ins_set_detailed(
596 mutex_enter(&srv_misc_tmpfile_mutex);
597 rewind(srv_misc_tmpfile);
602 dict_print_info_on_foreign_key_in_create_format(
603 srv_misc_tmpfile, trx, foreign, FALSE);
609 mutex_exit(&srv_misc_tmpfile_mutex);
617 row_ins_foreign_report_err(
629 FILE* ef = dict_foreign_err_file;
632 row_ins_set_detailed(trx, foreign);
634 mutex_enter(&dict_foreign_err_mutex);
637 fputs(
" Transaction:\n", ef);
640 fputs(
"Foreign key constraint fails for table ", ef);
643 dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
647 fputs(
" in parent table, in index ", ef);
650 fputs(
" tuple:\n", ef);
651 dtuple_print(ef, entry);
653 fputs(
"\nBut in child table ", ef);
655 fputs(
", in index ", ef);
658 fputs(
", there is a record:\n", ef);
661 fputs(
", the record is not available\n", ef);
665 mutex_exit(&dict_foreign_err_mutex);
674 row_ins_foreign_report_add_err(
684 FILE* ef = dict_foreign_err_file;
686 row_ins_set_detailed(trx, foreign);
688 mutex_enter(&dict_foreign_err_mutex);
691 fputs(
" Transaction:\n", ef);
693 fputs(
"Foreign key constraint fails for table ", ef);
696 dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
698 fputs(
"\nTrying to add in child table, in index ", ef);
701 fputs(
" tuple:\n", ef);
704 dtuple_print(ef, entry);
706 fputs(
"\nBut in parent table ", ef);
708 fputs(
", in index ", ef);
710 fputs(
",\nthe closest match we can find is record:\n", ef);
723 mutex_exit(&dict_foreign_err_mutex);
730 row_ins_invalidate_query_cache(
739 ulint len = strlen(name) + 1;
745 ptr = strchr(buf,
'/');
759 row_ins_foreign_check_on_constraint(
780 const rec_t* clust_rec;
802 row_ins_invalidate_query_cache(thr, table->
name);
806 if (node->is_delete && 0 == (foreign->
type
810 row_ins_foreign_report_err(
"Trying to delete",
812 btr_pcur_get_rec(pcur), entry);
814 return(DB_ROW_IS_REFERENCED);
817 if (!node->is_delete && 0 == (foreign->
type
823 row_ins_foreign_report_err(
"Trying to update",
825 btr_pcur_get_rec(pcur), entry);
827 return(DB_ROW_IS_REFERENCED);
830 if (node->cascade_node == NULL) {
837 table, node->cascade_heap);
846 cascade = node->cascade_node;
848 cascade->
table = table;
850 cascade->foreign = foreign;
854 cascade->is_delete = TRUE;
856 cascade->is_delete = FALSE;
858 if (foreign->
n_fields > cascade->update_n_fields) {
863 cascade->update_n_fields = foreign->
n_fields;
875 if (!cascade->is_delete
876 && row_ins_cascade_ancestor_updates_table(cascade, table)) {
881 err = DB_ROW_IS_REFERENCED;
883 row_ins_foreign_report_err(
884 "Trying an update, possibly causing a cyclic"
886 "in the child table,", thr, foreign,
887 btr_pcur_get_rec(pcur), entry);
889 goto nonstandard_exit_func;
892 if (row_ins_cascade_n_ancestors(cascade) >= 15) {
893 err = DB_ROW_IS_REFERENCED;
895 row_ins_foreign_report_err(
896 "Trying a too deep cascaded delete or update\n",
897 thr, foreign, btr_pcur_get_rec(pcur), entry);
899 goto nonstandard_exit_func;
902 index = btr_pcur_get_btr_cur(pcur)->index;
906 rec = btr_pcur_get_rec(pcur);
914 clust_block = btr_pcur_get_block(pcur);
919 clust_index = dict_table_get_first_index(table);
925 btr_pcur_open_with_no_init(clust_index, ref,
927 cascade->
pcur, 0, mtr);
929 clust_rec = btr_pcur_get_rec(cascade->
pcur);
930 clust_block = btr_pcur_get_block(cascade->
pcur);
936 fputs(
"InnoDB: error in cascade of a foreign key op\n"
938 dict_index_name_print(stderr, trx, index);
941 "InnoDB: record ", stderr);
944 "InnoDB: clustered record ", stderr);
945 rec_print(stderr, clust_rec, clust_index);
947 "InnoDB: Submit a detailed bug report to"
948 " http://bugs.mysql.com\n", stderr);
952 goto nonstandard_exit_func;
960 if (err == DB_SUCCESS) {
966 0, clust_block, clust_rec, clust_index,
970 if (err != DB_SUCCESS) {
972 goto nonstandard_exit_func;
981 goto nonstandard_exit_func;
997 for (i = 0; i < foreign->
n_fields; i++) {
1000 ufield->
field_no = dict_table_get_nth_col_pos(
1009 if (!node->is_delete
1017 n_to_update = row_ins_cascade_calc_update_vec(node, foreign,
1019 if (n_to_update == ULINT_UNDEFINED) {
1020 err = DB_ROW_IS_REFERENCED;
1022 row_ins_foreign_report_err(
1023 "Trying a cascaded update where the"
1024 " updated value in the child\n"
1025 "table would not fit in the length"
1026 " of the column, or the value would\n"
1027 "be NULL and the column is"
1028 " declared as not NULL in the child table,",
1029 thr, foreign, btr_pcur_get_rec(pcur), entry);
1031 goto nonstandard_exit_func;
1042 goto nonstandard_exit_func;
1049 btr_pcur_store_position(pcur, mtr);
1051 if (index == clust_index) {
1052 btr_pcur_copy_stored_position(cascade->
pcur, pcur);
1054 btr_pcur_store_position(cascade->
pcur, mtr);
1061 cascade->
state = UPD_NODE_UPDATE_CLUSTERED;
1068 "InnoDB: error: table %s has the counter 0"
1069 " though there is\n"
1070 "InnoDB: a FOREIGN KEY check running on it.\n",
1081 row_mysql_freeze_data_dictionary(
thr_get_trx(thr));
1099 nonstandard_exit_func:
1108 btr_pcur_store_position(pcur, mtr);
1124 row_ins_set_shared_rec_lock(
1131 const ulint* offsets,
1140 0, block, rec, index, offsets, LOCK_S, type, thr);
1143 0, block, rec, index, offsets, LOCK_S, type, thr);
1155 row_ins_set_exclusive_rec_lock(
1162 const ulint* offsets,
1171 0, block, rec, index, offsets, LOCK_X, type, thr);
1174 0, block, rec, index, offsets, LOCK_X, type, thr);
1211 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1212 ulint* offsets = offsets_;
1213 rec_offs_init(offsets_);
1216 #ifdef UNIV_SYNC_DEBUG
1217 ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_SHARED));
1222 if (trx->check_foreigns == FALSE) {
1232 for (i = 0; i < foreign->
n_fields; i++) {
1234 dtuple_get_nth_field(entry, i))) {
1243 if (!(upd_node->is_delete) && upd_node->foreign == foreign) {
1274 FILE* ef = dict_foreign_err_file;
1276 row_ins_set_detailed(trx, foreign);
1278 mutex_enter(&dict_foreign_err_mutex);
1281 fputs(
" Transaction:\n", ef);
1283 fputs(
"Foreign key constraint fails for table ", ef);
1287 dict_print_info_on_foreign_key_in_create_format(
1288 ef, trx, foreign, TRUE);
1289 fputs(
"\nTrying to add to index ", ef);
1292 fputs(
" tuple:\n", ef);
1293 dtuple_print(ef, entry);
1294 fputs(
"\nBut the parent table ", ef);
1297 fputs(
"\nor its .ibd file does"
1298 " not currently exist!\n", ef);
1299 mutex_exit(&dict_foreign_err_mutex);
1301 err = DB_NO_REFERENCED_ROW;
1310 if (check_table != table) {
1314 err =
lock_table(0, check_table, LOCK_IS, thr);
1316 if (err != DB_SUCCESS) {
1318 goto do_possible_lock_wait;
1330 btr_pcur_open(check_index, entry, PAGE_CUR_GE,
1336 const rec_t* rec = btr_pcur_get_rec(&pcur);
1337 const buf_block_t* block = btr_pcur_get_block(&pcur);
1344 offsets = rec_get_offsets(rec, check_index,
1345 offsets, ULINT_UNDEFINED, &heap);
1366 err = row_ins_set_shared_rec_lock(
1368 rec, check_index, offsets, thr);
1381 err = row_ins_set_shared_rec_lock(
1383 rec, check_index, offsets, thr);
1397 }
else if (foreign->
type != 0) {
1402 err = row_ins_foreign_check_on_constraint(
1403 thr, foreign, &pcur, entry,
1405 if (err != DB_SUCCESS) {
1418 if (err == DB_DUPLICATE_KEY) {
1419 err = DB_FOREIGN_DUPLICATE_KEY;
1428 block = btr_pcur_get_block(&pcur);
1430 row_ins_foreign_report_err(
1431 "Trying to delete or update",
1432 thr, foreign, rec, entry);
1434 err = DB_ROW_IS_REFERENCED;
1441 err = row_ins_set_shared_rec_lock(
1443 rec, check_index, offsets, thr);
1449 err = DB_NO_REFERENCED_ROW;
1450 row_ins_foreign_report_add_err(
1451 trx, foreign, rec, entry);
1462 row_ins_foreign_report_add_err(
1463 trx, foreign, btr_pcur_get_rec(&pcur), entry);
1464 err = DB_NO_REFERENCED_ROW;
1477 do_possible_lock_wait:
1478 if (err == DB_LOCK_WAIT) {
1494 if (UNIV_LIKELY_NULL(heap)) {
1509 row_ins_check_foreign_constraints(
1519 ibool got_s_lock = FALSE;
1536 row_mysql_freeze_data_dictionary(trx);
1540 mutex_enter(&(dict_sys->
mutex));
1545 mutex_exit(&(dict_sys->
mutex));
1554 TRUE, foreign, table, entry, thr);
1557 mutex_enter(&(dict_sys->
mutex));
1564 mutex_exit(&(dict_sys->
mutex));
1571 if (err != DB_SUCCESS) {
1588 row_ins_dupl_error_with_rec(
1595 const ulint* offsets)
1597 ulint matched_fields;
1598 ulint matched_bytes;
1610 &matched_fields, &matched_bytes);
1612 if (matched_fields < n_unique) {
1622 for (i = 0; i < n_unique; i++) {
1624 dtuple_get_nth_field(entry, i))) {
1641 row_ins_scan_sec_index_for_duplicate(
1652 ulint err = DB_SUCCESS;
1653 unsigned allow_duplicates;
1656 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1657 ulint* offsets = offsets_;
1658 rec_offs_init(offsets_);
1666 for (i = 0; i < n_unique; i++) {
1668 dtuple_get_nth_field(entry, i))) {
1682 btr_pcur_open(index, entry, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr);
1689 const rec_t* rec = btr_pcur_get_rec(&pcur);
1690 const buf_block_t* block = btr_pcur_get_block(&pcur);
1697 offsets = rec_get_offsets(rec, index, offsets,
1698 ULINT_UNDEFINED, &heap);
1700 if (allow_duplicates) {
1707 err = row_ins_set_exclusive_rec_lock(
1709 rec, index, offsets, thr);
1712 err = row_ins_set_shared_rec_lock(
1714 rec, index, offsets, thr);
1734 if (row_ins_dupl_error_with_rec(rec, entry,
1736 err = DB_DUPLICATE_KEY;
1749 if (UNIV_LIKELY_NULL(heap)) {
1769 row_ins_duplicate_error_in_clust(
1781 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1782 ulint* offsets = offsets_;
1783 rec_offs_init(offsets_);
1810 offsets = rec_get_offsets(rec, cursor->
index, offsets,
1811 ULINT_UNDEFINED, &heap);
1825 err = row_ins_set_exclusive_rec_lock(
1828 rec, cursor->
index, offsets, thr);
1831 err = row_ins_set_shared_rec_lock(
1834 cursor->
index, offsets, thr);
1845 if (row_ins_dupl_error_with_rec(
1846 rec, entry, cursor->
index, offsets)) {
1848 err = DB_DUPLICATE_KEY;
1854 if (cursor->
up_match >= n_unique) {
1859 offsets = rec_get_offsets(rec, cursor->
index, offsets,
1860 ULINT_UNDEFINED, &heap);
1869 err = row_ins_set_exclusive_rec_lock(
1872 rec, cursor->
index, offsets, thr);
1875 err = row_ins_set_shared_rec_lock(
1878 rec, cursor->
index, offsets, thr);
1889 if (row_ins_dupl_error_with_rec(
1890 rec, entry, cursor->
index, offsets)) {
1892 err = DB_DUPLICATE_KEY;
1903 if (UNIV_LIKELY_NULL(heap)) {
1920 row_ins_must_modify(
1936 if (cursor->
low_match >= enough_match) {
1942 return(ROW_INS_PREV);
1962 row_ins_index_entry_low(
1995 }
else if (!(
thr_get_trx(thr)->check_unique_secondary)) {
2001 btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
2003 &cursor, 0, __FILE__, __LINE__, &mtr);
2019 page_get_infimum_rec(page));
2036 err = row_ins_duplicate_error_in_clust(
2037 &cursor, entry, thr, &mtr);
2038 if (err != DB_SUCCESS) {
2044 err = row_ins_scan_sec_index_for_duplicate(
2048 if (err != DB_SUCCESS) {
2059 btr_cur_search_to_nth_level(index, 0, entry,
2063 __FILE__, __LINE__, &mtr);
2067 modify = row_ins_must_modify(&cursor);
2074 if (modify == ROW_INS_NEXT) {
2082 err = row_ins_clust_index_entry_by_modify(
2083 mode, &cursor, &heap, &big_rec, entry,
2087 err = row_ins_sec_index_entry_by_modify(
2088 mode, &cursor, entry, thr, &mtr);
2092 err = btr_cur_optimistic_insert(
2093 0, &cursor, entry, &insert_rec, &big_rec,
2097 if (buf_LRU_buf_pool_running_out()) {
2099 err = DB_LOCK_TABLE_FULL;
2103 err = btr_cur_pessimistic_insert(
2104 0, &cursor, entry, &insert_rec, &big_rec,
2112 if (UNIV_LIKELY_NULL(big_rec)) {
2117 btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
2119 __FILE__, __LINE__, &mtr);
2121 offsets = rec_get_offsets(exit_rec, index, NULL,
2122 ULINT_UNDEFINED, &heap);
2126 exit_rec, offsets, &mtr, FALSE, big_rec);
2131 dtuple_convert_back_big_rec(index, entry, big_rec);
2137 if (UNIV_LIKELY_NULL(heap)) {
2163 err =
static_cast<db_err>(row_ins_check_foreign_constraints(index->
table, index,
2165 if (err != DB_SUCCESS) {
2175 if (err != DB_FAIL) {
2192 row_ins_index_entry_set_vals(
2201 ut_ad(entry && row);
2205 for (i = 0; i < n_fields; i++) {
2211 field = dtuple_get_nth_field(entry, i);
2212 ind_field = dict_index_get_nth_field(index, i);
2213 row_field = dtuple_get_nth_field(row, ind_field->
col->
ind);
2223 len = dtype_get_at_most_n_mbchars(
2226 len, static_cast<const char *>(dfield_get_data(row_field)));
2245 row_ins_index_entry_step(
2254 row_ins_index_entry_set_vals(node->
index, node->
entry, node->
row);
2267 row_ins_alloc_row_id_step(
2293 row_ins_get_row_from_values(
2297 que_node_t* list_node;
2309 list_node = node->values_list;
2314 dfield = dtuple_get_nth_field(row, i);
2326 row_ins_get_row_from_select(
2330 que_node_t* list_node;
2345 dfield = dtuple_get_nth_field(row, i);
2368 if (node->
state == INS_NODE_ALLOC_ROW_ID) {
2370 row_ins_alloc_row_id_step(node);
2372 node->
index = dict_table_get_first_index(node->
table);
2375 if (node->ins_type == INS_SEARCHED) {
2377 row_ins_get_row_from_select(node);
2379 }
else if (node->ins_type == INS_VALUES) {
2381 row_ins_get_row_from_values(node);
2384 node->
state = INS_NODE_INSERT_ENTRIES;
2387 ut_ad(node->
state == INS_NODE_INSERT_ENTRIES);
2389 while (node->
index != NULL) {
2390 err = row_ins_index_entry_step(node, thr);
2392 if (err != DB_SUCCESS) {
2397 node->
index = dict_table_get_next_index(node->
index);
2403 node->
state = INS_NODE_ALLOC_ROW_ID;
2438 node->
state = INS_NODE_SET_IX_LOCK;
2453 if (node->
state == INS_NODE_SET_IX_LOCK) {
2466 if (err != DB_SUCCESS) {
2468 goto error_handling;
2473 node->
state = INS_NODE_ALLOC_ROW_ID;
2475 if (node->ins_type == INS_SEARCHED) {
2487 if ((node->ins_type == INS_SEARCHED)
2500 err = row_ins(node, thr);
2505 if (err != DB_SUCCESS) {
2512 if (node->ins_type == INS_SEARCHED) {