ibool row_upd_changes_field_size( /*=======================*/ /* out: TRUE if the update changes the size of some field in index */ rec_t* rec, /* in: record in clustered index */ dict_index_t* index, /* in: clustered index */ upd_t* update) /* in: update vector */ { upd_field_t* upd_field; dfield_t* new_val; ulint old_len; ulint new_len; ulint n_fields; ulint i; ut_ad(index->type & DICT_CLUSTERED); n_fields = upd_get_n_fields(update); for (i = 0; i < n_fields; i++) { upd_field = upd_get_nth_field(update, i); new_val = &(upd_field->new_val); new_len = new_val->len; if (new_len == UNIV_SQL_NULL) { new_len = dtype_get_sql_null_size( dict_index_get_nth_type(index, i)); } old_len = rec_get_nth_field_size(rec, upd_field->field_no); if (old_len != new_len) { return(TRUE); } if (rec_get_nth_field_extern_bit(rec, upd_field->field_no)) { return(TRUE); } if (upd_field->extern_storage) { return(TRUE); } } return(FALSE); }
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 */ 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; ulint i; /* 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); for (i = 0; i < dtuple_get_n_fields(entry); i++) { data = rec_get_nth_field(rec, 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; } if (rec_get_nth_field_extern_bit(rec, i) != upd_ext_vec_contains(ext_vec, n_ext_vec, 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); if (upd_ext_vec_contains(ext_vec, n_ext_vec, i)) { upd_field->extern_storage = TRUE; } else { upd_field->extern_storage = FALSE; } n_diff++; } skip_compare: ; } update->n_fields = n_diff; return(update); }
dtuple_t* row_build( /*======*/ /* out, own: row built; see the NOTE below! */ ulint type, /* in: ROW_COPY_POINTERS, ROW_COPY_DATA, or ROW_COPY_ALSO_EXTERNALS, the two last copy also the data fields to heap as the first only places pointers to data fields on the index page, and thus is more efficient */ dict_index_t* index, /* in: clustered index */ rec_t* rec, /* in: record in the clustered index; NOTE: in the case ROW_COPY_POINTERS the data fields in the row will point directly into this record, therefore, the buffer page of this record must be at least s-latched and the latch held as long as the row dtuple is used! */ mem_heap_t* heap) /* in: memory heap from which the memory needed is allocated */ { dtuple_t* row; dict_table_t* table; dict_field_t* ind_field; dict_col_t* col; dfield_t* dfield; ulint n_fields; byte* field; ulint len; ulint row_len; byte* buf; ulint i; ut_ad(index && rec && heap); ut_ad(index->type & DICT_CLUSTERED); if (type != ROW_COPY_POINTERS) { /* Take a copy of rec to heap */ buf = mem_heap_alloc(heap, rec_get_size(rec)); rec = rec_copy(buf, rec); } table = index->table; row_len = dict_table_get_n_cols(table); row = dtuple_create(heap, row_len); dtuple_set_info_bits(row, rec_get_info_bits(rec)); n_fields = dict_index_get_n_fields(index); ut_ad(n_fields == rec_get_n_fields(rec)); dict_table_copy_types(row, table); for (i = 0; i < n_fields; i++) { ind_field = dict_index_get_nth_field(index, i); if (ind_field->prefix_len == 0) { col = dict_field_get_col(ind_field); dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); field = rec_get_nth_field(rec, i, &len); if (type == ROW_COPY_ALSO_EXTERNALS && rec_get_nth_field_extern_bit(rec, i)) { field = btr_rec_copy_externally_stored_field( rec, i, &len, heap); } dfield_set_data(dfield, field, len); } } ut_ad(dtuple_check_typed(row)); return(row); }