📄 row0upd.c
字号:
return(NULL); } *roll_ptr = trx_read_roll_ptr(ptr); ptr += DATA_ROLL_PTR_LEN; ptr = mach_dulint_parse_compressed(ptr, end_ptr, trx_id); return(ptr);}/***************************************************************Writes to the redo log the new values of the fields occurring in the index. */voidrow_upd_index_write_log(/*====================*/ upd_t* update, /* in: update vector */ byte* log_ptr,/* in: pointer to mlog buffer: must contain at least MLOG_BUF_MARGIN bytes of free space; the buffer is closed within this function */ mtr_t* mtr) /* in: mtr into whose log to write */{ upd_field_t* upd_field; dfield_t* new_val; ulint len; ulint n_fields; byte* buf_end; ulint i; 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 (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; } upd_field = upd_get_nth_field(update, i); new_val = &(upd_field->new_val); len = new_val->len; log_ptr += mach_write_compressed(log_ptr, upd_field->field_no); log_ptr += mach_write_compressed(log_ptr, len); if (len != UNIV_SQL_NULL) { if (log_ptr + len < buf_end) { ut_memcpy(log_ptr, new_val->data, len); 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); buf_end = log_ptr + MLOG_BUF_MARGIN; } } } mlog_close(mtr, log_ptr);}/*************************************************************************Parses the log data written by row_upd_index_write_log. */byte*row_upd_index_parse(/*================*/ /* out: log data end or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ mem_heap_t* heap, /* in: memory heap where update vector is built */ upd_t** update_out)/* out: update vector */{ upd_t* update; upd_field_t* upd_field; dfield_t* new_val; ulint len; ulint n_fields; byte* buf; ulint info_bits; ulint i; if (end_ptr < ptr + 1) { return(NULL); } info_bits = mach_read_from_1(ptr); ptr++; ptr = mach_parse_compressed(ptr, end_ptr, &n_fields); if (ptr == NULL) { return(NULL); } update = upd_create(n_fields, heap); update->info_bits = info_bits; for (i = 0; i < n_fields; i++) { upd_field = upd_get_nth_field(update, i); new_val = &(upd_field->new_val); ptr = mach_parse_compressed(ptr, end_ptr, &(upd_field->field_no)); if (ptr == NULL) { return(NULL); } ptr = mach_parse_compressed(ptr, end_ptr, &len); if (ptr == NULL) { return(NULL); } new_val->len = len; if (len != UNIV_SQL_NULL) { if (end_ptr < ptr + len) { return(NULL); } else { buf = mem_heap_alloc(heap, len); ut_memcpy(buf, ptr, len); ptr += len; new_val->data = buf; } } } *update_out = update; return(ptr);}/*******************************************************************Returns TRUE if ext_vec contains i. */staticiboolupd_ext_vec_contains(/*=================*/ /* out: TRUE if i is in ext_vec */ ulint* ext_vec, /* in: array of indexes or NULL */ ulint n_ext_vec, /* in: number of numbers in ext_vec */ ulint i) /* in: a number */{ ulint j; if (ext_vec == NULL) { return(FALSE); } for (j = 0; j < n_ext_vec; j++) { if (ext_vec[j] == i) { return(TRUE); } } return(FALSE);} /*******************************************************************Builds an update vector from those fields which in a secondary index entrydiffer from a record that has the equal ordering fields. NOTE: we comparethe fields as binary strings! */upd_t*row_upd_build_sec_rec_difference_binary(/*====================================*/ /* out, own: update vector of differing fields */ dict_index_t* index, /* in: index */ dtuple_t* entry, /* in: entry to insert */ rec_t* rec, /* in: secondary index record */ trx_t* trx, /* in: transaction */ mem_heap_t* heap) /* in: memory heap from which allocated */{ upd_field_t* upd_field; dfield_t* dfield; byte* data; ulint len; upd_t* update; ulint n_diff; ulint i; ulint offsets_[REC_OFFS_SMALL_SIZE]; const ulint* offsets; *offsets_ = (sizeof offsets_) / sizeof *offsets_; /* This function is used only for a secondary index */ ut_a(0 == (index->type & DICT_CLUSTERED)); update = upd_create(dtuple_get_n_fields(entry), heap); n_diff = 0; offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); for (i = 0; i < dtuple_get_n_fields(entry); i++) { data = rec_get_nth_field(rec, offsets, i, &len); dfield = dtuple_get_nth_field(entry, i); /* NOTE that it may be that len != dfield_get_len(dfield) if we are updating in a character set and collation where strings of different length can be equal in an alphabetical comparison, and also in the case where we have a column prefix index and the last characters in the index field are spaces; the latter case probably caused the assertion failures reported at row0upd.c line 713 in versions 4.0.14 - 4.0.16. */ /* NOTE: we compare the fields as binary strings! (No collation) */ if (!dfield_data_is_binary_equal(dfield, len, data)) { upd_field = upd_get_nth_field(update, n_diff); dfield_copy(&(upd_field->new_val), dfield); upd_field_set_field_no(upd_field, i, index, trx); upd_field->extern_storage = FALSE; n_diff++; } } update->n_fields = n_diff; return(update);}/*******************************************************************Builds an update vector from those fields, excluding the roll ptr andtrx id fields, which in an index entry differ from a record that hasthe equal ordering fields. NOTE: we compare the fields as binary strings! */upd_t*row_upd_build_difference_binary(/*============================*/ /* out, own: update vector of differing fields, excluding roll ptr and trx id */ dict_index_t* index, /* in: clustered index */ dtuple_t* entry, /* in: entry to insert */ ulint* ext_vec,/* in: array containing field numbers of externally stored fields in entry, or NULL */ ulint n_ext_vec,/* in: number of fields in ext_vec */ rec_t* rec, /* in: clustered index record */ trx_t* trx, /* in: transaction */ mem_heap_t* heap) /* in: memory heap from which allocated */{ upd_field_t* upd_field; dfield_t* dfield; byte* data; ulint len; upd_t* update; ulint n_diff; ulint roll_ptr_pos; ulint trx_id_pos; ibool extern_bit; ulint i; ulint offsets_[REC_OFFS_NORMAL_SIZE]; const ulint* offsets; *offsets_ = (sizeof offsets_) / sizeof *offsets_; /* This function is used only for a clustered index */ ut_a(index->type & DICT_CLUSTERED); update = upd_create(dtuple_get_n_fields(entry), heap); n_diff = 0; roll_ptr_pos = dict_index_get_sys_col_pos(index, DATA_ROLL_PTR); trx_id_pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); for (i = 0; i < dtuple_get_n_fields(entry); i++) { data = rec_get_nth_field(rec, offsets, i, &len); dfield = dtuple_get_nth_field(entry, i); /* NOTE: we compare the fields as binary strings! (No collation) */ if (i == trx_id_pos || i == roll_ptr_pos) { goto skip_compare; } 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)) { upd_field = upd_get_nth_field(update, n_diff); dfield_copy(&(upd_field->new_val), dfield); upd_field_set_field_no(upd_field, i, index, trx); upd_field->extern_storage = extern_bit; n_diff++; }skip_compare: ; } update->n_fields = n_diff; return(update);}/***************************************************************Replaces the new column values stored in the update vector to the index entrygiven. */voidrow_upd_index_replace_new_col_vals_index_pos(/*=========================================*/ dtuple_t* entry, /* in/out: index entry where replaced */ dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ upd_t* update, /* in: an update vector built for the index so that the field number in an upd_field is the index position */ mem_heap_t* heap) /* in: memory heap to which we allocate and copy the new values, set this as NULL if you do not want allocation */{ dict_field_t* field; upd_field_t* upd_field; dfield_t* dfield; dfield_t* new_val; ulint j; ulint i; dtype_t* cur_type; ut_ad(index); dtuple_set_info_bits(entry, update->info_bits); for (j = 0; j < dict_index_get_n_fields(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); if (upd_field->field_no == 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, new_val->len); ut_memcpy(dfield->data, new_val->data, new_val->len); } if (field->prefix_len > 0 && 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, field->prefix_len, new_val->len, new_val->data); } } } }}/***************************************************************Replaces the new column values stored in the update vector to the index entrygiven. */voidrow_upd_index_replace_new_col_vals(/*===============================*/ dtuple_t* entry, /* in/out: index entry where replaced */ dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ upd_t* update, /* in: an update vector built for the CLUSTERED index so that the field number in an upd_field is the clustered index position */ mem_heap_t* heap) /* in: memory heap to which we allocate and copy the new values, set this as NULL if you do not want allocation */{ dict_field_t* field; upd_field_t* upd_field; dfield_t* dfield; dfield_t* new_val; ulint j; ulint i; dtype_t* cur_type; ut_ad(index); dtuple_set_info_bits(entry, update->info_bits); for (j = 0; j < dict_index_get_n_fields(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); if (upd_field->field_no == field->col->clust_pos) { 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, new_val->len); ut_memcpy(dfield->data, new_val->data, new_val->len); } if (field->prefix_len > 0 && 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, field->prefix_len, new_val->len, new_val->data); } } } }}/***************************************************************Checks if an update vector changes an ordering field of an index record.This function is fast if the update vector is short or the number of orderingfields in the index is small. Otherwise, this can be quadratic.NOTE: we compare the fields as binary strings! */iboolrow_upd_changes_ord_field_binary(/*=============================*/ /* out: TRUE if update vector changes an ordering field in the index record; NOTE: the fields are compared as binary strings */ dtuple_t* row, /* in: old value of row, or NULL if the row and the data values in update are not known when this function is called, e.g., at compile time */ dict_index_t* index, /* in: index of the record */ upd_t* update) /* in: update vector for the row; NOTE: the field numbers in this MUST be clustered index positions! */{ upd_field_t* upd_field; dict_field_t* ind_field; dict_col_t* col; ulint n_unique; ulint n_upd_fields; ulint col_pos; ulint col_no; ulint i, j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -