summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extra/innochecksum.cc12
-rw-r--r--storage/innobase/dict/dict0mem.cc32
-rw-r--r--storage/innobase/handler/handler0alter.cc43
-rw-r--r--storage/innobase/include/dict0mem.h53
-rw-r--r--storage/innobase/include/mach0data.h3
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