Commit 330c6218 authored by Aleksey Midenkov's avatar Aleksey Midenkov Committed by Marko Mäkelä

Replace dict_instant_t::non_pk_col_map with field_map

parent a044e326
......@@ -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 */
......
......@@ -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);
......
......@@ -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;
}
}
......
......@@ -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 */
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment