36 #ifndef UNIV_HOTBACKUP
114 row_upd_changes_first_fields_binary(
133 row_upd_index_is_referenced(
140 ibool froze_data_dict = FALSE;
141 ibool is_referenced = FALSE;
149 row_mysql_freeze_data_dictionary(trx);
150 froze_data_dict = TRUE;
158 is_referenced = TRUE;
166 if (froze_data_dict) {
170 return(is_referenced);
181 static __attribute__((nonnull, warn_unused_result))
183 row_upd_check_references_constraints(
201 ibool got_s_lock = FALSE;
210 rec = btr_pcur_get_rec(pcur);
211 ut_ad(rec_offs_validate(rec, index, offsets));
219 DEBUG_SYNC_C(
"foreign_constraint_check_for_update");
226 row_mysql_freeze_data_dictionary(trx);
240 || row_upd_changes_first_fields_binary(
241 entry, index, node->update,
247 if (foreign_table == NULL) {
266 FALSE, foreign, table, entry, thr);
274 if (ref_table != NULL) {
281 }
else if (err != DB_SUCCESS) {
298 DEBUG_SYNC_C(
"foreign_constraint_check_for_update_done");
319 node->
state = UPD_NODE_UPDATE_CLUSTERED;
320 node->in_mysql_interface = FALSE;
324 node->upd_row = NULL;
325 node->upd_ext = NULL;
329 node->foreign = NULL;
330 node->cascade_heap = NULL;
331 node->cascade_node = NULL;
336 node->magic_n = UPD_NODE_MAGIC_N;
353 const ulint* offsets,
358 ut_ad(rec_offs_validate(rec, NULL, offsets));
362 page_zip, rec, offsets, pos, trx_id, roll_ptr);
367 field = rec_get_nth_field(rec, offsets, pos, &len);
368 ut_ad(len == DATA_TRX_ID_LEN);
369 #if DATA_TRX_ID + 1 != DATA_ROLL_PTR
370 # error "DATA_TRX_ID + 1 != DATA_ROLL_PTR"
377 #ifndef UNIV_HOTBACKUP
400 dfield = dtuple_get_nth_field(entry, pos);
401 field =
static_cast<byte*
>(dfield_get_data(dfield));
403 if (type == DATA_TRX_ID) {
406 ut_ad(type == DATA_ROLL_PTR);
421 const ulint* offsets,
431 ut_ad(rec_offs_validate(NULL, index, offsets));
434 for (i = 0; i < n_fields; i++) {
435 upd_field = upd_get_nth_field(update, i);
437 new_val = &(upd_field->
new_val);
464 old_len = UNIV_SQL_NULL;
494 for (i = 0; i < n_fields; i++) {
495 const byte* field_ref;
497 upd_field = upd_get_nth_field(update, i);
498 new_val = &(upd_field->
new_val);
507 field_ref =
static_cast<const byte*
>(dfield_get_data(new_val))
531 const ulint* offsets,
541 ut_ad(rec_offs_validate(rec, index, offsets));
551 for (i = 0; i < n_fields; i++) {
552 #ifdef UNIV_BLOB_DEBUG
554 const byte* field_ref = NULL;
557 upd_field = upd_get_nth_field(update, i);
558 new_val = &(upd_field->
new_val);
561 #ifdef UNIV_BLOB_DEBUG
564 field_ref = rec_get_nth_field(rec, offsets, i, &len);
565 ut_a(len != UNIV_SQL_NULL);
575 btr_blob_dbg_rbt_delete(index, &b,
"upd_in_place");
580 dfield_get_data(new_val),
583 #ifdef UNIV_BLOB_DEBUG
592 btr_blob_dbg_rbt_insert(index, &b,
"upd_in_place");
602 #ifndef UNIV_HOTBACKUP
616 mtr_t* mtr __attribute__((unused)))
623 index, DATA_TRX_ID));
626 log_ptr += DATA_ROLL_PTR_LEN;
654 if (end_ptr < ptr + DATA_ROLL_PTR_LEN) {
660 ptr += DATA_ROLL_PTR_LEN;
667 #ifndef UNIV_HOTBACKUP
690 buf_end = log_ptr + MLOG_BUF_MARGIN;
696 for (i = 0; i < n_fields; i++) {
698 #if MLOG_BUF_MARGIN <= 30
699 # error "MLOG_BUF_MARGIN <= 30"
702 if (log_ptr + 30 > buf_end) {
705 log_ptr =
mlog_open(mtr, MLOG_BUF_MARGIN);
706 buf_end = log_ptr + MLOG_BUF_MARGIN;
709 upd_field = upd_get_nth_field(update, i);
711 new_val = &(upd_field->
new_val);
718 if (len != UNIV_SQL_NULL) {
719 if (log_ptr + len < buf_end) {
720 memcpy(log_ptr, dfield_get_data(new_val), len);
729 dfield_get_data(new_val)),
732 log_ptr =
mlog_open(mtr, MLOG_BUF_MARGIN);
733 buf_end = log_ptr + MLOG_BUF_MARGIN;
763 if (end_ptr < ptr + 1) {
780 for (i = 0; i < n_fields; i++) {
782 upd_field = upd_get_nth_field(update, i);
783 new_val = &(upd_field->
new_val);
801 if (len != UNIV_SQL_NULL) {
803 if (end_ptr < ptr + len) {
816 *update_out = update;
821 #ifndef UNIV_HOTBACKUP
833 const ulint* offsets,
847 ut_ad(rec_offs_validate(rec, index, offsets));
857 data = rec_get_nth_field(rec, offsets, i, &len);
859 dfield = dtuple_get_nth_field(entry, i);
874 upd_field = upd_get_nth_field(update, n_diff);
902 const ulint* offsets,
916 ulint offsets_[REC_OFFS_NORMAL_SIZE];
917 rec_offs_init(offsets_);
931 offsets = rec_get_offsets(rec, index, offsets_,
932 ULINT_UNDEFINED, &heap);
934 ut_ad(rec_offs_validate(rec, index, offsets));
939 data = rec_get_nth_field(rec, offsets, i, &len);
941 dfield = dtuple_get_nth_field(entry, i);
946 if (no_sys && (i == trx_id_pos || i == trx_id_pos + 1)) {
955 upd_field = upd_get_nth_field(update, n_diff);
993 buf, *len, zip_size, data, local_len);
1006 row_upd_index_replace_new_col_val(
1028 data =
static_cast<const byte*
>(dfield_get_data(dfield));
1033 + BTR_EXTERN_FIELD_REF_SIZE;
1040 data = row_upd_ext_fetch(data, l, zip_size,
1047 (
const char*) data);
1060 case BTR_EXTERN_FIELD_REF_SIZE:
1067 data + len - BTR_EXTERN_FIELD_REF_SIZE,
1068 BTR_EXTERN_FIELD_REF_SIZE);
1083 uf->
orig_len - BTR_EXTERN_FIELD_REF_SIZE);
1086 memcpy(buf + uf->
orig_len - BTR_EXTERN_FIELD_REF_SIZE,
1087 data + len - BTR_EXTERN_FIELD_REF_SIZE,
1088 BTR_EXTERN_FIELD_REF_SIZE);
1109 const upd_t* update,
1133 for (i = 0; i < n_fields; i++) {
1138 field = dict_index_get_nth_field(index, i);
1143 row_upd_index_replace_new_col_val(
1144 dtuple_get_nth_field(entry, i),
1145 field, col, uf, heap, zip_size);
1163 const upd_t* update,
1171 = dict_table_get_first_index(index->
table);
1172 const ulint zip_size
1182 field = dict_index_get_nth_field(index, i);
1188 row_upd_index_replace_new_col_val(
1189 dtuple_get_nth_field(entry, i),
1190 field, col, uf, heap, zip_size);
1209 const upd_t* update,
1228 table = index->
table;
1231 ext_cols =
static_cast<ulint*
>(
1238 for (col_no = 0; col_no < n_cols; col_no++) {
1241 = dict_table_get_nth_col(table, col_no);
1242 const ulint clust_pos
1246 if (UNIV_UNLIKELY(clust_pos == ULINT_UNDEFINED)) {
1251 dfield = dtuple_get_nth_field(row, col_no);
1256 = upd_get_nth_field(update, i);
1258 if (upd_field->
field_no != clust_pos) {
1268 ext_cols[n_ext_cols++] = col_no;
1292 const upd_t* update,
1313 ut_ad(thr->graph->trx);
1317 clust_index = dict_table_get_first_index(index->
table);
1319 for (i = 0; i < n_unique; i++) {
1330 ind_field = dict_index_get_nth_field(index, i);
1337 if (upd_field == NULL) {
1346 dfield = dtuple_get_nth_field(row, col_no);
1358 UNIV_MEM_INVALID(&dfield_len,
sizeof dfield_len);
1364 if (UNIV_LIKELY_NULL(buf)) {
1372 ut_ad(thr->graph->trx->is_recovered);
1381 ut_a(dfield_len > BTR_EXTERN_FIELD_REF_SIZE);
1386 buf =
static_cast<byte*
>(dfield_get_data(dfield));
1388 ut_a(dfield_len > 0);
1391 dfield = &dfield_ext;
1415 const upd_t* update)
1421 index = dict_table_get_first_index(table);
1425 upd_field = upd_get_nth_field(update, i);
1450 fts_t* fts = table->fts;
1452 clust_index = dict_table_get_first_index(table);
1458 return(col_no == fts->
doc_col);
1473 fts_t* fts = table->fts;
1475 clust_index = dict_table_get_first_index(table);
1481 return(dict_table_is_fts_column(fts->
indexes, col_no));
1491 row_upd_changes_first_fields_binary(
1495 const upd_t* update,
1502 ut_ad(update && index);
1506 clust_index = dict_table_get_first_index(index->
table);
1508 for (i = 0; i <
n; i++) {
1514 ind_field = dict_index_get_nth_field(index, i);
1520 for (j = 0; j < n_upd_fields; j++) {
1523 = upd_get_nth_field(update, j);
1527 dtuple_get_nth_field(entry, i),
1542 row_upd_copy_columns(
1545 const ulint* offsets,
1553 data = rec_get_nth_field(rec, offsets,
1567 row_upd_eval_new_vals(
1578 for (i = 0; i < n_fields; i++) {
1579 upd_field = upd_get_nth_field(update, i);
1581 exp = upd_field->
exp;
1601 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1603 rec_offs_init(offsets_);
1607 if (node->
row != NULL) {
1611 clust_index = dict_table_get_first_index(node->
table);
1613 rec = btr_pcur_get_rec(node->
pcur);
1615 offsets = rec_get_offsets(rec, clust_index, offsets_,
1616 ULINT_UNDEFINED, &heap);
1631 node->
row =
row_build(ROW_COPY_DATA, clust_index, rec, offsets,
1632 NULL, NULL, NULL, ext, node->
heap);
1633 if (node->is_delete) {
1634 node->upd_row = NULL;
1635 node->upd_ext = NULL;
1642 if (UNIV_LIKELY_NULL(heap)) {
1651 static __attribute__((nonnull, warn_unused_result))
1653 row_upd_sec_index_entry(
1673 index = node->index;
1675 referenced = row_upd_index_is_referenced(index, trx);
1690 "before_row_upd_sec_index_entry");
1713 if (!node->is_delete) {
1716 node->upd_row, node->upd_ext,
1749 btr_pcur_get_btr_cur(&pcur)->thr =
thr;
1754 btr_cur = btr_pcur_get_btr_cur(&pcur);
1756 rec = btr_cur_get_rec(btr_cur);
1758 switch (search_result) {
1781 fputs(
"InnoDB: error in sec index entry update in\n"
1782 "InnoDB: ", stderr);
1785 "InnoDB: tuple ", stderr);
1788 "InnoDB: record ", stderr);
1793 "InnoDB: Submit a detailed bug report"
1794 " to http://bugs.mysql.com\n", stderr);
1804 0, btr_cur, TRUE, thr, &mtr);
1806 if (err == DB_SUCCESS && referenced) {
1810 offsets = rec_get_offsets(
1811 rec, index, NULL, ULINT_UNDEFINED,
1816 err = row_upd_check_references_constraints(
1817 node, &pcur, index->
table,
1818 index, offsets, thr, &mtr);
1827 if (node->is_delete || err != DB_SUCCESS) {
1853 static __attribute__((nonnull, warn_unused_result))
1860 ut_ad((node->state == UPD_NODE_UPDATE_ALL_SEC)
1861 || (node->state == UPD_NODE_UPDATE_SOME_SEC));
1864 if (node->state == UPD_NODE_UPDATE_ALL_SEC
1865 || row_upd_changes_ord_field_binary(node->index, node->update,
1866 thr, node->row, node->ext)) {
1867 return(row_upd_sec_index_entry(node, thr));
1874 # define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \
1875 row_upd_clust_rec_by_insert_inherit_func(rec,offsets,entry,update)
1877 # define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \
1878 row_upd_clust_rec_by_insert_inherit_func(entry,update)
1886 static __attribute__((warn_unused_result))
1888 row_upd_clust_rec_by_insert_inherit_func(
1896 const upd_t* update)
1898 ibool inherit = FALSE;
1901 ut_ad(!rec == !offsets);
1905 dfield_t* dfield = dtuple_get_nth_field(entry, i);
1919 if (UNIV_LIKELY(rec != NULL)) {
1920 const byte* rec_data
1921 = rec_get_nth_field(rec, offsets, i, &len);
1923 ut_ad(len != UNIV_SQL_NULL);
1924 ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE);
1930 BTR_EXTERN_FIELD_REF_SIZE));
1933 & BTR_EXTERN_OWNER_FLAG));
1938 ut_a(len != UNIV_SQL_NULL);
1939 ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
1941 data =
static_cast<byte*
>(dfield_get_data(dfield));
1967 static __attribute__((nonnull, warn_unused_result))
1969 row_upd_clust_rec_by_insert(
1985 ibool change_ownership = FALSE;
1987 ulint* offsets = NULL;
1993 table = node->table;
1995 btr_cur = btr_pcur_get_btr_cur(pcur);
2005 switch (node->state) {
2008 case UPD_NODE_INSERT_BLOB:
2013 change_ownership = row_upd_clust_rec_by_insert_inherit(
2014 NULL, NULL, entry, node->update);
2015 ut_a(change_ownership);
2017 case UPD_NODE_INSERT_CLUSTERED:
2021 case UPD_NODE_UPDATE_CLUSTERED:
2025 rec = btr_cur_get_rec(btr_cur);
2026 offsets = rec_get_offsets(rec, index, NULL,
2027 ULINT_UNDEFINED, &heap);
2031 btr_cur_get_block(btr_cur), rec, index, offsets,
2033 if (err != DB_SUCCESS) {
2046 change_ownership = row_upd_clust_rec_by_insert_inherit(
2047 rec, offsets, entry, node->update);
2049 if (change_ownership) {
2058 err = row_upd_check_references_constraints(
2059 node, pcur, table, index, offsets, thr, mtr);
2061 if (err != DB_SUCCESS) {
2071 node->upd_ext ? node->upd_ext->n_ext : 0);
2072 node->state = change_ownership
2073 ? UPD_NODE_INSERT_BLOB
2074 : UPD_NODE_INSERT_CLUSTERED;
2076 if (err == DB_SUCCESS && change_ownership) {
2093 rec = btr_cur_get_rec(btr_cur);
2094 offsets = rec_get_offsets(rec, index, offsets,
2095 ULINT_UNDEFINED, &heap);
2101 rec, index, offsets, node->update, mtr);
2121 static __attribute__((nonnull, warn_unused_result))
2144 btr_cur = btr_pcur_get_btr_cur(pcur);
2149 ut_ad(rec_offs_validate(btr_cur_get_rec(btr_cur), index, offsets));
2153 btr_cur_get_rec(btr_cur), index, offsets, &heap);
2160 if (node->cmpl_info & UPD_NODE_NO_SIZE_CHANGE) {
2163 offsets, node->update,
2168 &offsets, offsets_heap, node->update,
2174 index, offsets, rebuilt_old_pk);
2179 if (UNIV_LIKELY(err == DB_SUCCESS)) {
2211 &offsets, offsets_heap, heap, &big_rec,
2212 node->update, node->cmpl_info,
2215 ut_a(err == DB_SUCCESS);
2237 DEBUG_SYNC_C(
"before_row_upd_extern");
2239 index, btr_cur_get_block(btr_cur),
2240 btr_cur_get_rec(btr_cur), offsets,
2242 DEBUG_SYNC_C(
"after_row_upd_extern");
2256 ut_a(err == DB_SUCCESS);
2261 index, offsets, rebuilt_old_pk);
2280 static __attribute__((nonnull, warn_unused_result))
2282 row_upd_del_mark_clust_rec(
2300 ut_ad(node->is_delete);
2303 btr_cur = btr_pcur_get_btr_cur(pcur);
2308 row_upd_store_row(node);
2314 btr_cur_get_block(btr_cur), btr_cur_get_rec(btr_cur),
2315 index, offsets, thr, mtr);
2316 if (err == DB_SUCCESS && referenced) {
2319 err = row_upd_check_references_constraints(
2320 node, pcur, index->table, index, offsets, thr, mtr);
2332 static __attribute__((nonnull, warn_unused_result))
2346 ulint offsets_[REC_OFFS_NORMAL_SIZE];
2349 rec_offs_init(offsets_);
2351 index = dict_table_get_first_index(node->table);
2353 referenced = row_upd_index_is_referenced(index,
thr_get_trx(thr));
2377 DEBUG_SYNC_C_IF_THD(
2379 "innodb_row_upd_clust_step_enter");
2384 ut_ad(node->table->id != DICT_INDEXES_ID);
2391 success = btr_pcur_restore_position(mode, pcur, &mtr);
2394 err = DB_RECORD_NOT_FOUND;
2405 if (node->is_delete && node->table->id == DICT_INDEXES_ID) {
2426 rec = btr_pcur_get_rec(pcur);
2427 offsets = rec_get_offsets(rec, index, offsets_,
2428 ULINT_UNDEFINED, &heap);
2430 if (!node->has_clust_rec_x_lock) {
2432 0, btr_pcur_get_block(pcur),
2433 rec, index, offsets, thr);
2434 if (err != DB_SUCCESS) {
2441 btr_pcur_get_block(pcur),
2446 if (node->is_delete) {
2447 err = row_upd_del_mark_clust_rec(
2448 node, index, offsets, thr, referenced, &mtr);
2450 if (err == DB_SUCCESS) {
2451 node->state = UPD_NODE_UPDATE_ALL_SEC;
2452 node->index = dict_table_get_next_index(index);
2461 if (UNIV_UNLIKELY(!node->in_mysql_interface)) {
2464 row_upd_copy_columns(rec, offsets,
2466 row_upd_eval_new_vals(node->update);
2469 if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) {
2471 err = row_upd_clust_rec(
2472 node, index, offsets, &heap, thr, &mtr);
2476 row_upd_store_row(node);
2478 if (row_upd_changes_ord_field_binary(index, node->update, thr,
2479 node->row, node->ext)) {
2492 err = row_upd_clust_rec_by_insert(
2493 node, index, thr, referenced, &mtr);
2495 if (err != DB_SUCCESS) {
2500 node->state = UPD_NODE_UPDATE_ALL_SEC;
2502 err = row_upd_clust_rec(
2503 node, index, offsets, &heap, thr, &mtr);
2505 if (err != DB_SUCCESS) {
2510 node->state = UPD_NODE_UPDATE_SOME_SEC;
2513 node->index = dict_table_get_next_index(index);
2528 static __attribute__((nonnull, warn_unused_result))
2539 if (UNIV_LIKELY(node->in_mysql_interface)) {
2546 node->table, node->update)) {
2547 node->cmpl_info = 0;
2549 node->cmpl_info = UPD_NODE_NO_ORD_CHANGE;
2553 switch (node->state) {
2554 case UPD_NODE_UPDATE_CLUSTERED:
2555 case UPD_NODE_INSERT_CLUSTERED:
2556 case UPD_NODE_INSERT_BLOB:
2558 err = row_upd_clust_step(node, thr);
2560 if (err != DB_SUCCESS) {
2566 if (node->index == NULL
2567 || (!node->is_delete
2568 && (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE))) {
2578 "after_row_upd_clust");
2582 DBUG_EXECUTE_IF(
"row_upd_skip_sec", node->index = NULL;);
2586 dict_table_skip_corrupt_index(node->index);
2592 if (node->index->type != DICT_FTS) {
2593 err = row_upd_sec_step(node, thr);
2595 if (err != DB_SUCCESS) {
2601 node->index = dict_table_get_next_index(node->index);
2602 }
while (node->index != NULL);
2604 ut_ad(err == DB_SUCCESS);
2608 if (node->row != NULL) {
2611 node->upd_row = NULL;
2612 node->upd_ext = NULL;
2616 node->state = UPD_NODE_UPDATE_CLUSTERED;
2641 trx_start_if_not_started_xa(trx);
2652 node->
state = UPD_NODE_SET_IX_LOCK;
2655 if (node->
state == UPD_NODE_SET_IX_LOCK) {
2657 if (!node->has_clust_rec_x_lock) {
2663 if (err != DB_SUCCESS) {
2665 goto error_handling;
2669 node->
state = UPD_NODE_UPDATE_CLUSTERED;
2671 if (node->searched_update) {
2687 if (!node->searched_update) {
2695 goto error_handling;
2710 err = row_upd(node, thr);
2715 if (err != DB_SUCCESS) {
2721 if (node->searched_update) {
2731 node->
state = UPD_NODE_UPDATE_CLUSTERED;