summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0upd.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row/row0upd.c')
-rw-r--r--storage/innobase/row/row0upd.c271
1 files changed, 139 insertions, 132 deletions
diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index ff1ad1dfd05..23be601a17b 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/row/row0upd.c
@@ -130,7 +130,7 @@ row_upd_index_is_referenced(
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
-
+
if (froze_data_dict) {
row_mysql_unfreeze_data_dictionary(trx);
}
@@ -176,16 +176,16 @@ row_upd_check_references_constraints(
entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
- mtr_commit(mtr);
+ mtr_commit(mtr);
+
+ mtr_start(mtr);
- mtr_start(mtr);
-
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
row_mysql_freeze_data_dictionary(trx);
}
-
+
foreign = UT_LIST_GET_FIRST(table->referenced_list);
while (foreign) {
@@ -195,10 +195,11 @@ row_upd_check_references_constraints(
NOT break the constraint. */
if (foreign->referenced_index == index
- && (node->is_delete
- || row_upd_changes_first_fields_binary(entry, index,
- node->update, foreign->n_fields))) {
-
+ && (node->is_delete
+ || row_upd_changes_first_fields_binary(
+ entry, index, node->update,
+ foreign->n_fields))) {
+
if (foreign->foreign_table == NULL) {
dict_table_get(foreign->foreign_table_name,
trx);
@@ -217,7 +218,7 @@ row_upd_check_references_constraints(
we will release dict_operation_lock temporarily!
But the counter on the table protects 'foreign' from
being dropped while the check is running. */
-
+
err = row_ins_check_foreign_constraint(FALSE, foreign,
table, entry, thr);
@@ -253,7 +254,7 @@ row_upd_check_references_constraints(
}
mem_heap_free(heap);
-
+
return(DB_SUCCESS);
}
@@ -279,18 +280,18 @@ upd_node_create(
node->ext_vec = NULL;
node->index = NULL;
node->update = NULL;
-
+
node->foreign = NULL;
node->cascade_heap = NULL;
node->cascade_node = NULL;
-
+
node->select = NULL;
-
+
node->heap = mem_heap_create(128);
- node->magic_n = UPD_NODE_MAGIC_N;
+ node->magic_n = UPD_NODE_MAGIC_N;
node->cmpl_info = 0;
-
+
return(node);
}
@@ -396,7 +397,8 @@ row_upd_changes_field_size_or_external(
old_len = rec_offs_nth_size(offsets, upd_field->field_no);
if (rec_offs_comp(offsets)
- && rec_offs_nth_sql_null(offsets, upd_field->field_no)) {
+ && rec_offs_nth_sql_null(offsets,
+ upd_field->field_no)) {
/* Note that in the compact table format, for a
variable length field, an SQL NULL will use zero
bytes in the offset array at the start of the physical
@@ -411,7 +413,7 @@ row_upd_changes_field_size_or_external(
return(TRUE);
}
-
+
if (rec_offs_nth_extern(offsets, upd_field->field_no)) {
return(TRUE);
@@ -452,7 +454,7 @@ row_upd_rec_in_place(
for (i = 0; i < n_fields; i++) {
upd_field = upd_get_nth_field(update, i);
new_val = &(upd_field->new_val);
-
+
rec_set_nth_field(rec, offsets, upd_field->field_no,
dfield_get_data(new_val),
dfield_get_len(new_val));
@@ -481,7 +483,7 @@ row_upd_write_sys_vals_to_log(
dict_index_get_sys_col_pos(index, DATA_TRX_ID));
trx_write_roll_ptr(log_ptr, roll_ptr);
- log_ptr += DATA_ROLL_PTR_LEN;
+ log_ptr += DATA_ROLL_PTR_LEN;
log_ptr += mach_dulint_write_compressed(log_ptr, trx->id);
@@ -512,9 +514,9 @@ row_upd_parse_sys_vals(
return(NULL);
}
-
+
*roll_ptr = trx_read_roll_ptr(ptr);
- ptr += DATA_ROLL_PTR_LEN;
+ ptr += DATA_ROLL_PTR_LEN;
ptr = mach_dulint_parse_compressed(ptr, end_ptr, trx_id);
@@ -543,18 +545,20 @@ row_upd_index_write_log(
n_fields = upd_get_n_fields(update);
buf_end = log_ptr + MLOG_BUF_MARGIN;
-
+
mach_write_to_1(log_ptr, update->info_bits);
log_ptr++;
log_ptr += mach_write_compressed(log_ptr, n_fields);
-
+
for (i = 0; i < n_fields; i++) {
- ut_ad(MLOG_BUF_MARGIN > 30);
+#if MLOG_BUF_MARGIN <= 30
+# error "MLOG_BUF_MARGIN <= 30"
+#endif
if (log_ptr + 30 > buf_end) {
mlog_close(mtr, log_ptr);
-
+
log_ptr = mlog_open(mtr, MLOG_BUF_MARGIN);
buf_end = log_ptr + MLOG_BUF_MARGIN;
}
@@ -575,7 +579,7 @@ row_upd_index_write_log(
log_ptr += len;
} else {
mlog_close(mtr, log_ptr);
-
+
mlog_catenate_string(mtr, new_val->data, len);
log_ptr = mlog_open(mtr, MLOG_BUF_MARGIN);
@@ -694,7 +698,7 @@ upd_ext_vec_contains(
return(FALSE);
}
-
+
/*******************************************************************
Builds an update vector from those fields which in a secondary index entry
differ from a record that has the equal ordering fields. NOTE: we compare
@@ -828,10 +832,10 @@ row_upd_build_difference_binary(
}
extern_bit = upd_ext_vec_contains(ext_vec, n_ext_vec, i);
-
+
if (UNIV_UNLIKELY(extern_bit ==
- (ibool)!rec_offs_nth_extern(offsets, i))
- || !dfield_data_is_binary_equal(dfield, len, data)) {
+ (ibool)!rec_offs_nth_extern(offsets, i))
+ || !dfield_data_is_binary_equal(dfield, len, data)) {
upd_field = upd_get_nth_field(update, n_diff);
@@ -883,36 +887,36 @@ row_upd_index_replace_new_col_vals_index_pos(
for (j = 0; j < dict_index_get_n_fields(index); j++) {
- field = dict_index_get_nth_field(index, j);
+ field = dict_index_get_nth_field(index, j);
for (i = 0; i < upd_get_n_fields(update); i++) {
- upd_field = upd_get_nth_field(update, i);
+ upd_field = upd_get_nth_field(update, i);
if (upd_field->field_no == j) {
- dfield = dtuple_get_nth_field(entry, j);
+ dfield = dtuple_get_nth_field(entry, j);
new_val = &(upd_field->new_val);
dfield_set_data(dfield, new_val->data,
new_val->len);
if (heap && new_val->len != UNIV_SQL_NULL) {
- dfield->data = mem_heap_alloc(heap,
+ dfield->data = mem_heap_alloc(heap,
new_val->len);
ut_memcpy(dfield->data, new_val->data,
new_val->len);
}
if (field->prefix_len > 0
- && new_val->len != UNIV_SQL_NULL) {
+ && new_val->len != UNIV_SQL_NULL) {
- cur_type = dict_col_get_type(
+ cur_type = dict_col_get_type(
dict_field_get_col(field));
- dfield->len =
- dtype_get_at_most_n_mbchars(
- cur_type,
+ dfield->len =
+ dtype_get_at_most_n_mbchars(
+ cur_type,
field->prefix_len,
new_val->len,
new_val->data);
@@ -953,36 +957,36 @@ row_upd_index_replace_new_col_vals(
for (j = 0; j < dict_index_get_n_fields(index); j++) {
- field = dict_index_get_nth_field(index, j);
+ field = dict_index_get_nth_field(index, j);
for (i = 0; i < upd_get_n_fields(update); i++) {
- upd_field = upd_get_nth_field(update, i);
+ upd_field = upd_get_nth_field(update, i);
if (upd_field->field_no == field->col->clust_pos) {
- dfield = dtuple_get_nth_field(entry, j);
+ dfield = dtuple_get_nth_field(entry, j);
new_val = &(upd_field->new_val);
dfield_set_data(dfield, new_val->data,
new_val->len);
if (heap && new_val->len != UNIV_SQL_NULL) {
- dfield->data = mem_heap_alloc(heap,
+ dfield->data = mem_heap_alloc(heap,
new_val->len);
ut_memcpy(dfield->data, new_val->data,
new_val->len);
}
if (field->prefix_len > 0
- && new_val->len != UNIV_SQL_NULL) {
+ && new_val->len != UNIV_SQL_NULL) {
cur_type = dict_col_get_type(
dict_field_get_col(field));
- dfield->len =
- dtype_get_at_most_n_mbchars(
- cur_type,
+ dfield->len =
+ dtype_get_at_most_n_mbchars(
+ cur_type,
field->prefix_len,
new_val->len,
new_val->data);
@@ -1022,7 +1026,7 @@ row_upd_changes_ord_field_binary(
ulint col_pos;
ulint col_no;
ulint i, j;
-
+
ut_ad(update && index);
n_unique = dict_index_get_n_unique(index);
@@ -1045,10 +1049,11 @@ row_upd_changes_ord_field_binary(
the datas */
if (col_pos == upd_field->field_no
- && (row == NULL
- || ind_field->prefix_len > 0
- || !dfield_datas_are_binary_equal(
- dtuple_get_nth_field(row, col_no),
+ && (row == NULL
+ || ind_field->prefix_len > 0
+ || !dfield_datas_are_binary_equal(
+ dtuple_get_nth_field(row,
+ col_no),
&(upd_field->new_val)))) {
return(TRUE);
}
@@ -1073,21 +1078,21 @@ row_upd_changes_some_index_ord_field_binary(
upd_field_t* upd_field;
dict_index_t* index;
ulint i;
-
+
index = dict_table_get_first_index(table);
-
+
for (i = 0; i < upd_get_n_fields(update); i++) {
upd_field = upd_get_nth_field(update, i);
if (dict_field_get_col(dict_index_get_nth_field(index,
- upd_field->field_no))
- ->ord_part) {
+ upd_field->field_no))
+ ->ord_part) {
- return(TRUE);
+ return(TRUE);
}
}
-
+
return(FALSE);
}
@@ -1111,10 +1116,10 @@ row_upd_changes_first_fields_binary(
ulint n_upd_fields;
ulint col_pos;
ulint i, j;
-
+
ut_a(update && index);
ut_a(n <= dict_index_get_n_fields(index));
-
+
n_upd_fields = upd_get_n_fields(update);
for (i = 0; i < n; i++) {
@@ -1130,9 +1135,10 @@ row_upd_changes_first_fields_binary(
upd_field = upd_get_nth_field(update, j);
if (col_pos == upd_field->field_no
- && !dfield_datas_are_binary_equal(
- dtuple_get_nth_field(entry, i),
- &(upd_field->new_val))) {
+ && !dfield_datas_are_binary_equal(
+ dtuple_get_nth_field(entry, i),
+ &(upd_field->new_val))) {
+
return(TRUE);
}
}
@@ -1214,11 +1220,11 @@ row_upd_store_row(
mem_heap_empty(node->heap);
node->row = NULL;
}
-
+
clust_index = dict_table_get_first_index(node->table);
rec = btr_pcur_get_rec(node->pcur);
-
+
offsets = rec_get_offsets(rec, clust_index, offsets_,
ULINT_UNDEFINED, &heap);
node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
@@ -1230,7 +1236,7 @@ row_upd_store_row(
} else {
update = node->update;
}
-
+
node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec,
offsets, update);
if (UNIV_LIKELY_NULL(heap)) {
@@ -1262,7 +1268,7 @@ row_upd_sec_index_entry(
trx_t* trx = thr_get_trx(thr);
index = node->index;
-
+
check_ref = row_upd_index_is_referenced(index, trx);
heap = mem_heap_create(1024);
@@ -1272,7 +1278,7 @@ row_upd_sec_index_entry(
log_free_check();
mtr_start(&mtr);
-
+
found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
&mtr);
btr_cur = btr_pcur_get_btr_cur(&pcur);
@@ -1296,15 +1302,16 @@ row_upd_sec_index_entry(
fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
} else {
- /* Delete mark the old index record; it can already be
- delete marked if we return after a lock wait in
- row_ins_index_entry below */
+ /* Delete mark the old index record; it can already be
+ delete marked if we return after a lock wait in
+ row_ins_index_entry below */
- if (!rec_get_deleted_flag(rec, index->table->comp)) {
+ if (!rec_get_deleted_flag(rec,
+ dict_table_is_comp(index->table))) {
err = btr_cur_del_mark_set_sec_rec(0, btr_cur, TRUE,
thr, &mtr);
if (err == DB_SUCCESS && check_ref) {
-
+
/* NOTE that the following call loses
the position of pcur ! */
err = row_upd_check_references_constraints(
@@ -1317,7 +1324,7 @@ row_upd_sec_index_entry(
}
}
- }
+ }
}
close_cur:
btr_pcur_close(&pcur);
@@ -1325,9 +1332,9 @@ close_cur:
if (node->is_delete || err != DB_SUCCESS) {
- mem_heap_free(heap);
+ mem_heap_free(heap);
- return(err);
+ return(err);
}
/* Build a new index entry */
@@ -1336,9 +1343,9 @@ close_cur:
/* Insert new index entry */
err = row_ins_index_entry(index, entry, NULL, 0, thr);
- mem_heap_free(heap);
+ mem_heap_free(heap);
- return(err);
+ return(err);
}
/***************************************************************
@@ -1358,10 +1365,10 @@ row_upd_sec_step(
ut_ad((node->state == UPD_NODE_UPDATE_ALL_SEC)
|| (node->state == UPD_NODE_UPDATE_SOME_SEC));
ut_ad(!(node->index->type & DICT_CLUSTERED));
-
+
if (node->state == UPD_NODE_UPDATE_ALL_SEC
- || row_upd_changes_ord_field_binary(node->row, node->index,
- node->update)) {
+ || row_upd_changes_ord_field_binary(node->row, node->index,
+ node->update)) {
err = row_upd_sec_index_entry(node, thr);
return(err);
@@ -1395,7 +1402,7 @@ row_upd_clust_rec_by_insert(
dict_table_t* table;
dtuple_t* entry;
ulint err;
-
+
ut_ad(node);
ut_ad(index->type & DICT_CLUSTERED);
@@ -1403,7 +1410,7 @@ row_upd_clust_rec_by_insert(
table = node->table;
pcur = node->pcur;
btr_cur = btr_pcur_get_btr_cur(pcur);
-
+
if (node->state != UPD_NODE_INSERT_CLUSTERED) {
ulint offsets_[REC_OFFS_NORMAL_SIZE];
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
@@ -1439,7 +1446,7 @@ row_upd_clust_rec_by_insert(
}
}
- }
+ }
mtr_commit(mtr);
@@ -1451,26 +1458,26 @@ row_upd_clust_rec_by_insert(
entry = row_build_index_entry(node->row, index, heap);
row_upd_index_replace_new_col_vals(entry, index, node->update, NULL);
-
+
row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id);
-
+
/* If we return from a lock wait, for example, we may have
extern fields marked as not-owned in entry (marked in the
if-branch above). We must unmark them. */
-
+
btr_cur_unmark_dtuple_extern_fields(entry, node->ext_vec,
node->n_ext_vec);
/* We must mark non-updated extern fields in entry as inherited,
so that a possible rollback will not free them */
-
+
btr_cur_mark_dtuple_inherited_extern(entry, node->ext_vec,
node->n_ext_vec,
node->update);
-
+
err = row_ins_index_entry(index, entry, node->ext_vec,
node->n_ext_vec, thr);
mem_heap_free(heap);
-
+
return(err);
}
@@ -1492,7 +1499,7 @@ row_upd_clust_rec(
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
ulint err;
-
+
ut_ad(node);
ut_ad(index->type & DICT_CLUSTERED);
@@ -1500,8 +1507,8 @@ row_upd_clust_rec(
btr_cur = btr_pcur_get_btr_cur(pcur);
ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
- index->table->comp));
-
+ dict_table_is_comp(index->table)));
+
/* Try optimistic updating of the record, keeping changes within
the page; we do not check locks because we assume the x-lock on the
record to update */
@@ -1517,7 +1524,7 @@ row_upd_clust_rec(
}
mtr_commit(mtr);
-
+
if (err == DB_SUCCESS) {
return(err);
@@ -1527,7 +1534,7 @@ row_upd_clust_rec(
down the index tree */
mtr_start(mtr);
-
+
/* NOTE: this transaction has an s-lock or x-lock on the record and
therefore other transactions cannot modify the record when we have no
latch on the page. In addition, we assume that other query threads of
@@ -1537,8 +1544,8 @@ row_upd_clust_rec(
ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
- index->table->comp));
-
+ dict_table_is_comp(index->table)));
+
err = btr_cur_pessimistic_update(BTR_NO_LOCKING_FLAG, btr_cur,
&big_rec, node->update,
node->cmpl_info, thr, mtr);
@@ -1567,7 +1574,7 @@ row_upd_clust_rec(
if (big_rec) {
dtuple_big_rec_free(big_rec);
}
-
+
return(err);
}
@@ -1589,7 +1596,7 @@ row_upd_del_mark_clust_rec(
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
ulint err;
-
+
ut_ad(node);
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(node->is_delete);
@@ -1599,7 +1606,7 @@ row_upd_del_mark_clust_rec(
/* Store row because we have to build also the secondary index
entries */
-
+
row_upd_store_row(node);
/* Mark the clustered index record deleted; we do not have to check
@@ -1621,7 +1628,7 @@ row_upd_del_mark_clust_rec(
}
mtr_commit(mtr);
-
+
return(err);
}
@@ -1660,7 +1667,7 @@ row_upd_clust_step(
mtr = &mtr_buf;
mtr_start(mtr);
-
+
/* If the restoration does not succeed, then the same
transaction has deleted the record on which the cursor was,
and that is an SQL error. If the restoration succeeds, it may
@@ -1668,7 +1675,7 @@ row_upd_clust_step(
and inserted a record with the same ordering fields, but in
that case we know that the transaction has at least an
implicit x-lock on the record. */
-
+
ut_a(pcur->rel_pos == BTR_PCUR_ON);
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr);
@@ -1686,7 +1693,7 @@ row_upd_clust_step(
with the index */
if (node->is_delete
- && ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
+ && ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
dict_drop_index_tree(btr_pcur_get_rec(pcur), mtr);
@@ -1703,7 +1710,7 @@ row_upd_clust_step(
return(err);
}
- }
+ }
rec = btr_pcur_get_rec(pcur);
offsets = rec_get_offsets(rec, index, offsets_,
@@ -1733,10 +1740,10 @@ row_upd_clust_step(
}
return(err);
}
-
+
/* If the update is made for MySQL, we already have the update vector
ready, else we have to do some evaluation: */
-
+
if (!node->in_mysql_interface) {
/* Copy the necessary columns from clust_rec and calculate the
new values to set */
@@ -1748,13 +1755,13 @@ row_upd_clust_step(
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
-
+
if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) {
err = row_upd_clust_rec(node, index, thr, mtr);
return(err);
}
-
+
row_upd_store_row(node);
if (row_upd_changes_ord_field_binary(node->row, index, node->update)) {
@@ -1808,18 +1815,18 @@ row_upd(
que_thr_t* thr) /* in: query thread */
{
ulint err = DB_SUCCESS;
-
+
ut_ad(node && thr);
if (node->in_mysql_interface) {
-
+
/* We do not get the cmpl_info value from the MySQL
interpreter: we must calculate it on the fly: */
-
+
if (node->is_delete ||
row_upd_changes_some_index_ord_field_binary(
node->table, node->update)) {
- node->cmpl_info = 0;
+ node->cmpl_info = 0;
} else {
node->cmpl_info = UPD_NODE_NO_ORD_CHANGE;
}
@@ -1829,7 +1836,7 @@ row_upd(
|| node->state == UPD_NODE_INSERT_CLUSTERED) {
err = row_upd_clust_step(node, thr);
-
+
if (err != DB_SUCCESS) {
goto function_exit;
@@ -1850,7 +1857,7 @@ row_upd(
}
node->index = dict_table_get_next_index(node->index);
- }
+ }
function_exit:
if (err == DB_SUCCESS) {
@@ -1865,7 +1872,7 @@ function_exit:
node->state = UPD_NODE_UPDATE_CLUSTERED;
}
- return(err);
+ return(err);
}
/***************************************************************
@@ -1885,19 +1892,19 @@ row_upd_step(
trx_t* trx;
ut_ad(thr);
-
+
trx = thr_get_trx(thr);
trx_start_if_not_started(trx);
node = thr->run_node;
-
+
sel_node = node->select;
parent = que_node_get_parent(node);
-
+
ut_ad(que_node_get_type(node) == QUE_NODE_UPDATE);
-
+
if (thr->prev_node == parent) {
node->state = UPD_NODE_SET_IX_LOCK;
}
@@ -1915,23 +1922,23 @@ row_upd_step(
goto error_handling;
}
}
-
+
node->state = UPD_NODE_UPDATE_CLUSTERED;
if (node->searched_update) {
/* Reset the cursor */
sel_node->state = SEL_NODE_OPEN;
-
+
/* Fetch a row to update */
-
+
thr->run_node = sel_node;
-
+
return(thr);
}
}
/* sel_node is NULL if we are in the MySQL interface */
-
+
if (sel_node && (sel_node->state != SEL_NODE_FETCH)) {
if (!node->searched_update) {
@@ -1939,7 +1946,7 @@ row_upd_step(
to update */
ut_error;
-
+
err = DB_ERROR;
goto error_handling;
@@ -1951,12 +1958,12 @@ row_upd_step(
updates directly in-place */
thr->run_node = parent;
-
+
return(thr);
}
/* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
-
+
err = row_upd(node, thr);
error_handling:
@@ -1986,7 +1993,7 @@ error_handling:
node->state = UPD_NODE_UPDATE_CLUSTERED;
return(thr);
-}
+}
/*************************************************************************
Performs an in-place update for the current clustered index record in
@@ -2031,8 +2038,8 @@ row_upd_in_place_in_select(
row_upd_eval_new_vals(node->update);
ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
- btr_cur->index->table->comp));
-
+ dict_table_is_comp(btr_cur->index->table)));
+
ut_ad(node->cmpl_info & UPD_NODE_NO_SIZE_CHANGE);
ut_ad(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE);
ut_ad(node->select_will_do_update);