diff options
Diffstat (limited to 'storage/innobase/data/data0data.cc')
-rw-r--r-- | storage/innobase/data/data0data.cc | 72 |
1 files changed, 46 insertions, 26 deletions
diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc index ccfb992b850..02f921f716c 100644 --- a/storage/innobase/data/data0data.cc +++ b/storage/innobase/data/data0data.cc @@ -58,7 +58,12 @@ void dtuple_t::trim(const dict_index_t& index) for (; i > index.n_core_fields; i--) { const dfield_t* dfield = dtuple_get_nth_field(this, i - 1); const dict_col_t* col = dict_index_get_nth_col(&index, i - 1); - ut_ad(col->is_instant()); + + if (col->is_dropped()) { + continue; + } + + ut_ad(col->is_added()); ulint len = dfield_get_len(dfield); if (len != col->def_val.len) { break; @@ -594,7 +599,6 @@ dtuple_convert_big_rec( mem_heap_t* heap; big_rec_t* vector; dfield_t* dfield; - dict_field_t* ifield; ulint size; ulint n_fields; ulint local_len; @@ -604,15 +608,14 @@ dtuple_convert_big_rec( return(NULL); } - if (!dict_table_has_atomic_blobs(index->table)) { - /* up to MySQL 5.1: store a 768-byte prefix locally */ - local_len = BTR_EXTERN_FIELD_REF_SIZE - + DICT_ANTELOPE_MAX_INDEX_COL_LEN; - } else { - /* new-format table: do not store any BLOB prefix locally */ - local_len = BTR_EXTERN_FIELD_REF_SIZE; + if (!index->table->space) { + return NULL; } + const auto zip_size = index->table->space->zip_size(); + + ut_ad(index->n_uniq > 0); + ut_a(dtuple_check_typed_no_assert(entry)); size = rec_get_converted_size(index, entry, *n_ext); @@ -634,24 +637,42 @@ dtuple_convert_big_rec( stored externally */ n_fields = 0; + ulint longest_i; + + const bool mblob = entry->is_alter_metadata(); + ut_ad(entry->n_fields >= index->first_user_field() + mblob); + ut_ad(entry->n_fields - mblob <= index->n_fields); + + if (mblob) { + longest_i = index->first_user_field(); + dfield = dtuple_get_nth_field(entry, longest_i); + local_len = BTR_EXTERN_FIELD_REF_SIZE; + ut_ad(!dfield_is_ext(dfield)); + goto ext_write; + } + + if (!dict_table_has_atomic_blobs(index->table)) { + /* up to MySQL 5.1: store a 768-byte prefix locally */ + local_len = BTR_EXTERN_FIELD_REF_SIZE + + DICT_ANTELOPE_MAX_INDEX_COL_LEN; + } else { + /* new-format table: do not store any BLOB prefix locally */ + local_len = BTR_EXTERN_FIELD_REF_SIZE; + } while (page_zip_rec_needs_ext(rec_get_converted_size(index, entry, *n_ext), - dict_table_is_comp(index->table), + index->table->not_redundant(), dict_index_get_n_fields(index), - dict_table_page_size(index->table))) { - - ulint i; - ulint longest = 0; - ulint longest_i = ULINT_MAX; - byte* data; - - for (i = dict_index_get_n_unique_in_tree(index); - i < dtuple_get_n_fields(entry); i++) { + zip_size)) { + longest_i = 0; + for (ulint i = index->first_user_field(), longest = 0; + i + mblob < entry->n_fields; i++) { ulint savings; + dfield = dtuple_get_nth_field(entry, i + mblob); - dfield = dtuple_get_nth_field(entry, i); - ifield = dict_index_get_nth_field(index, i); + const dict_field_t* ifield = dict_index_get_nth_field( + index, i); /* Skip fixed-length, NULL, externally stored, or short columns */ @@ -693,7 +714,7 @@ skip_field: continue; } - if (!longest) { + if (!longest_i) { /* Cannot shorten more */ mem_heap_free(heap); @@ -706,9 +727,8 @@ skip_field: We store the first bytes locally to the record. Then we can calculate all ordering fields in all indexes from locally stored data. */ - dfield = dtuple_get_nth_field(entry, longest_i); - ifield = dict_index_get_nth_field(index, longest_i); +ext_write: local_prefix_len = local_len - BTR_EXTERN_FIELD_REF_SIZE; vector->append( @@ -719,7 +739,8 @@ skip_field: + local_prefix_len)); /* Allocate the locally stored part of the column. */ - data = static_cast<byte*>(mem_heap_alloc(heap, local_len)); + byte* data = static_cast<byte*>( + mem_heap_alloc(heap, local_len)); /* Copy the local prefix. */ memcpy(data, dfield_get_data(dfield), local_prefix_len); @@ -733,7 +754,6 @@ skip_field: UNIV_MEM_ALLOC(data + local_prefix_len, BTR_EXTERN_FIELD_REF_SIZE); #endif - dfield_set_data(dfield, data, local_len); dfield_set_ext(dfield); |