diff options
-rw-r--r-- | extra/innochecksum.cc | 12 | ||||
-rw-r--r-- | storage/innobase/dict/dict0mem.cc | 32 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 43 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 53 | ||||
-rw-r--r-- | storage/innobase/include/mach0data.h | 3 |
5 files changed, 85 insertions, 58 deletions
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index 0eb2b9aba71..7eb868ef1e6 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -42,22 +42,12 @@ /* Only parts of these files are included from the InnoDB codebase. The parts not included are excluded by #ifndef UNIV_INNOCHECKSUM. */ -typedef void fil_space_t; - -#include "page0size.h" -#include "ut0ut.h" -#include "mtr0types.h" #include "mach0data.h" -#include "fsp0types.h" -#include "rem0rec.h" +#include "page0page.h" #include "buf0checksum.h" /* buf_calc_page_*() */ #include "buf0buf.h" /* buf_page_is_corrupted */ -#include "fil0fil.h" /* FIL_* */ -#include "page0page.h" /* PAGE_* */ #include "page0zip.h" /* page_zip_*() */ #include "trx0undo.h" /* TRX_* */ -#include "fsp0fsp.h" /* fsp_flags_get_page_size() & - fsp_flags_get_zip_size() */ #include "ut0crc32.h" /* ut_crc32_init() */ #include "fsp0pagecompress.h" /* fil_get_compression_alg_name */ #include "fil0crypt.h" /* fil_space_verify_crypt_checksum */ diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 5d2052b1f6f..485c0f22577 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -1216,23 +1216,24 @@ inline void dict_index_t::reconstruct_fields() n_nullable = 0; ulint n_core_null = 0; const bool comp = dict_table_is_comp(table); - const auto* non_pk_col_map = table->instant->non_pk_col_map; + const auto* field_map_it = table->instant->field_map; for (unsigned i = n_first, j = 0; i < n_fields; ) { dict_field_t& f = tfields[i++]; - auto c = *non_pk_col_map++; - if (c & 1U << 15) { + auto c = *field_map_it++; + if (c.is_dropped()) { f.col = &table->instant->dropped[j++]; DBUG_ASSERT(f.col->is_dropped()); f.fixed_len = dict_col_get_fixed_size(f.col, comp); } else { + DBUG_ASSERT(!c.is_not_null()); const auto old = std::find_if( fields + n_first, fields + n_fields, [c](const dict_field_t& o) - { return o.col->ind == c; }); + { return o.col->ind == c.ind(); }); ut_ad(old >= &fields[n_first]); ut_ad(old < &fields[n_fields]); DBUG_ASSERT(!old->prefix_len); - DBUG_ASSERT(old->col == &table->cols[c]); + DBUG_ASSERT(old->col == &table->cols[c.ind()]); f = *old; } @@ -1269,23 +1270,22 @@ bool dict_table_t::deserialise_columns(const byte* metadata, ulint len) return true; } - uint16_t* non_pk_col_map = static_cast<uint16_t*>( + field_map_element_t* field_map = static_cast<field_map_element_t*>( mem_heap_alloc(heap, - num_non_pk_fields * sizeof *non_pk_col_map)); + num_non_pk_fields * sizeof *field_map)); unsigned n_dropped_cols = 0; for (unsigned i = 0; i < num_non_pk_fields; i++) { - non_pk_col_map[i] = mach_read_from_2(metadata); + auto c = field_map[i] = mach_read_from_2(metadata); metadata += 2; - if (non_pk_col_map[i] & 1U << 15) { - if ((non_pk_col_map[i] & ~(3U << 14)) - > DICT_MAX_FIXED_COL_LEN + 1) { + if (field_map[i].is_dropped()) { + if (c.ind() > DICT_MAX_FIXED_COL_LEN + 1) { return true; } n_dropped_cols++; - } else if (non_pk_col_map[i] >= n_cols) { + } else if (c >= n_cols) { return true; } } @@ -1295,14 +1295,14 @@ bool dict_table_t::deserialise_columns(const byte* metadata, ulint len) instant = new (mem_heap_alloc(heap, sizeof *instant)) dict_instant_t(); instant->n_dropped = n_dropped_cols; instant->dropped = dropped_cols; - instant->non_pk_col_map = non_pk_col_map; + instant->field_map = field_map; dict_col_t* col = dropped_cols; for (unsigned i = 0; i < num_non_pk_fields; i++) { - if (non_pk_col_map[i] & 1U << 15) { - auto fixed_len = non_pk_col_map[i] & ~(3U << 14); + if (field_map[i].is_dropped()) { + auto fixed_len = field_map[i].ind(); DBUG_ASSERT(fixed_len <= DICT_MAX_FIXED_COL_LEN + 1); - (col++)->set_dropped(non_pk_col_map[i] & 1U << 14, + (col++)->set_dropped(field_map[i].is_not_null(), fixed_len == 1, fixed_len > 1 ? fixed_len - 1 : 0); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 940e5a55d39..546a79223fd 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -160,7 +160,7 @@ static void instant_metadata_lock(dict_index_t& index, mtr_t& mtr) ut_ad(!buf_block_get_page_zip(btr_cur_get_block(&btr_cur))); } -/** Initialize instant->non_pk_col_map. +/** Initialize instant->field_map. @tparam replace_dropped whether to point clustered index fields to instant->dropped[] @param[in] table table definition to copy from */ @@ -174,10 +174,10 @@ inline void dict_table_t::init_instant(const dict_table_t& table) DBUG_ASSERT(not_redundant() == table.not_redundant()); DBUG_ASSERT(index.n_fields >= oindex.n_fields); - uint16_t* non_pk_col_map = static_cast<uint16_t*>( + field_map_element_t* field_map_it = static_cast<field_map_element_t*>( mem_heap_zalloc(heap, (index.n_fields - u) - * sizeof *non_pk_col_map)); - instant->non_pk_col_map = non_pk_col_map; + * sizeof *field_map_it)); + instant->field_map = field_map_it; ut_d(unsigned n_drop = 0); ut_d(unsigned n_nullable = 0); @@ -185,32 +185,23 @@ inline void dict_table_t::init_instant(const dict_table_t& table) auto& f = index.fields[i]; DBUG_ASSERT(dict_col_get_fixed_size(f.col, not_redundant()) <= DICT_MAX_FIXED_COL_LEN); -#ifdef UNIV_DEBUG - if (!f.col->is_nullable()) { - ut_ad((*non_pk_col_map & 3U << 15) != 1U << 14); - } else if ((*non_pk_col_map & 3U << 15) != 1U << 14) { - n_nullable++; - } -#endif + ut_d(n_nullable += f.col->is_nullable()); + if (!f.col->is_dropped()) { - auto c = *non_pk_col_map & 3U << 14; - DBUG_ASSERT(!(c & 1U << 15)); - if (!c - && f.col->is_nullable() - && !oindex.fields[i].col->is_nullable()) { - c = 1U << 14; - } - *non_pk_col_map++ = c | f.col->ind; + (*field_map_it++).set_ind(f.col->ind); continue; } auto fixed_len = dict_col_get_fixed_size( f.col, not_redundant()); - *non_pk_col_map++ = 1U << 15 - | uint16_t(!f.col->is_nullable()) << 14 - | (fixed_len - ? uint16_t(fixed_len + 1) - : f.col->len > 255); + field_map_it->set_dropped(); + if (!f.col->is_nullable()) { + field_map_it->set_not_null(); + } + field_map_it->set_ind(fixed_len + ? uint16_t(fixed_len + 1) + : f.col->len > 255); + field_map_it++; ut_ad(f.col >= table.instant->dropped); ut_ad(f.col < table.instant->dropped + table.instant->n_dropped); @@ -223,7 +214,7 @@ inline void dict_table_t::init_instant(const dict_table_t& table) } } ut_ad(n_drop == n_dropped()); - ut_ad(non_pk_col_map == &instant->non_pk_col_map[index.n_fields - u]); + ut_ad(field_map_it == &instant->field_map[index.n_fields - u]); ut_ad(index.n_nullable == n_nullable); } @@ -5275,7 +5266,7 @@ void dict_table_t::serialise_columns(mem_heap_t* heap, dfield_t* field) const data += 4; for (ulint i = n_fixed; i < index.n_fields; i++) { - mach_write_to_2(data, instant->non_pk_col_map[i - n_fixed]); + mach_write_to_2(data, instant->field_map[i - n_fixed]); data += 2; } } diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 3ca199b3e60..940680b6100 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1539,6 +1539,52 @@ struct dict_vcol_templ_t { dict_vcol_templ_t() : vtempl(0), mysql_table_query_id(~0ULL) {} }; +/** Metadata on clustered index fields starting from first_user_field() */ +class field_map_element_t +{ + /** Number of bits for representing a column number */ + static constexpr uint16_t IND_BITS = 10; + + /** Set if the column of the field has been instantly dropped */ + static constexpr uint16_t DROPPED = 1U << (IND_BITS + 5); + + /** Set if the column was dropped and originally declared NOT NULL */ + static constexpr uint16_t NOT_NULL = 1U << (IND_BITS + 4); + + /** Column index (if !(data & DROPPED)): table->cols[data & IND], + or field length (if (data & DROPPED)): + (data & IND) = 0 if variable-length with max_len < 256 bytes; + (data & IND) = 1 if variable-length with max_len > 255 bytes; + (data & IND) = 1 + L otherwise, with L=fixed length of the column */ + static constexpr uint16_t IND = (1U << IND_BITS) - 1; + + /** Field metadata */ + uint16_t data; + + void clear_not_null() { data &= ~NOT_NULL; } +public: + bool is_dropped() const { return data & DROPPED; } + void set_dropped() { data |= DROPPED; } + bool is_not_null() const { return data & NOT_NULL; } + void set_not_null() { ut_ad(is_dropped()); data |= NOT_NULL; } + uint16_t ind() const { return data & IND; } + void set_ind(uint16_t i) + { + DBUG_ASSERT(i <= IND); + DBUG_ASSERT(!ind()); + data |= i; + } + field_map_element_t& operator= (uint16_t value) + { + data = value; + return *this; + } + operator uint16_t() { return data; } +}; + +static_assert(sizeof(field_map_element_t) == 2, + "Size mismatch for a persistent data item!"); + /** Instantly dropped or reordered columns */ struct dict_instant_t { @@ -1546,8 +1592,9 @@ struct dict_instant_t unsigned n_dropped; /** Dropped columns */ dict_col_t* dropped; - /** Mapping the non-pk field to column of the table. */ - uint16_t* non_pk_col_map; + /** Map of clustered index non-PK fields[i - first_user_field()] + to table columns */ + field_map_element_t* field_map; }; /** These are used when MySQL FRM and InnoDB data dictionary are @@ -1717,7 +1764,7 @@ struct dict_table_t { } private: - /** Initialize instant->non_pk_col_map. + /** Initialize instant->field_map. @tparam replace_dropped whether to point clustered index fields to instant->dropped[] @param[in] table table definition to copy from */ diff --git a/storage/innobase/include/mach0data.h b/storage/innobase/include/mach0data.h index bcf71ea6b17..96e8d629021 100644 --- a/storage/innobase/include/mach0data.h +++ b/storage/innobase/include/mach0data.h @@ -29,11 +29,10 @@ Created 11/28/1995 Heikki Tuuri #define mach0data_h #include "univ.i" +#include "mtr0types.h" #ifndef UNIV_INNOCHECKSUM -#include "mtr0types.h" - /* The data and all fields are always stored in a database file in the same format: ascii, big-endian, ... . All data in the files MUST be accessed using the functions in this |