Commit f055da9b authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-19085 Assertion failures due to virtual columns after upgrading from 10.1

MariaDB before MDEV-5800 in version 10.2.2 did not support
indexed virtual columns. Non-persistent virtual columns were
hidden from storage engines. Only starting with MDEV-5800, InnoDB
would create internal metadata on virtual columns.

Similar to what was done in MDEV-18084, MDEV-18090, MDEV-18960, we adjust
one more code path for the old tables.

innobase_build_col_map(): Allocate space for virtual columns in col_map[]
but leave the entries at ULINT_UNDEFINED, noting that the virtual columns
were missing before the table was being rebuilt.
parent 833071b8
...@@ -3022,10 +3022,17 @@ innobase_build_col_map( ...@@ -3022,10 +3022,17 @@ innobase_build_col_map(
& Alter_inplace_info::ADD_COLUMN)); & Alter_inplace_info::ADD_COLUMN));
DBUG_ASSERT(!add_cols || dtuple_get_n_fields(add_cols) DBUG_ASSERT(!add_cols || dtuple_get_n_fields(add_cols)
== dict_table_get_n_cols(new_table)); == dict_table_get_n_cols(new_table));
DBUG_ASSERT(table->s->stored_fields > 0);
size_t old_n_v_cols = old_n_v_cols = table->s->fields
- table->s->stored_fields;
DBUG_ASSERT(old_n_v_cols == old_table->n_v_cols
|| table->s->frm_version < FRM_VER_EXPRESSSIONS);
DBUG_ASSERT(!old_n_v_cols || table->s->virtual_fields);
ulint* col_map = static_cast<ulint*>( ulint* col_map = static_cast<ulint*>(
mem_heap_alloc( mem_heap_alloc(
heap, (old_table->n_cols + old_table->n_v_cols) heap, (size_t(old_table->n_cols) + old_n_v_cols)
* sizeof *col_map)); * sizeof *col_map));
List_iterator_fast<Create_field> cf_it( List_iterator_fast<Create_field> cf_it(
...@@ -3039,10 +3046,12 @@ innobase_build_col_map( ...@@ -3039,10 +3046,12 @@ innobase_build_col_map(
col_map[old_i] = ULINT_UNDEFINED; col_map[old_i] = ULINT_UNDEFINED;
} }
for (uint old_i = 0; old_i < old_table->n_v_cols; old_i++) { for (uint old_i = 0; old_i < old_n_v_cols; old_i++) {
col_map[old_i + old_table->n_cols] = ULINT_UNDEFINED; col_map[old_i + old_table->n_cols] = ULINT_UNDEFINED;
} }
const bool omits_virtual = ha_innobase::omits_virtual_cols(*table->s);
while (const Create_field* new_field = cf_it++) { while (const Create_field* new_field = cf_it++) {
bool is_v = !new_field->stored_in_db(); bool is_v = !new_field->stored_in_db();
ulint num_old_v = 0; ulint num_old_v = 0;
...@@ -3051,8 +3060,11 @@ innobase_build_col_map( ...@@ -3051,8 +3060,11 @@ innobase_build_col_map(
const Field* field = table->field[old_i]; const Field* field = table->field[old_i];
if (!field->stored_in_db()) { if (!field->stored_in_db()) {
if (is_v && new_field->field == field) { if (is_v && new_field->field == field) {
col_map[old_table->n_cols + num_v] if (!omits_virtual) {
col_map[old_table->n_cols
+ num_v]
= num_old_v; = num_old_v;
}
num_old_v++; num_old_v++;
goto found_col; goto found_col;
} }
...@@ -3081,7 +3093,7 @@ innobase_build_col_map( ...@@ -3081,7 +3093,7 @@ innobase_build_col_map(
DBUG_ASSERT(i == altered_table->s->fields - num_v); DBUG_ASSERT(i == altered_table->s->fields - num_v);
i = table->s->fields - old_table->n_v_cols; i = table->s->fields - old_n_v_cols;
/* Add the InnoDB hidden FTS_DOC_ID column, if any. */ /* Add the InnoDB hidden FTS_DOC_ID column, if any. */
if (i + DATA_N_SYS_COLS < old_table->n_cols) { if (i + DATA_N_SYS_COLS < old_table->n_cols) {
......
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