1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

[2/2] MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols

Several different test cases were failing under the same reason: the
fields in a vcol expression were not marked during marking columns of a key
contatining virtual column for read.

Fix: make marking columns of a key for read a special case where
register_field_in_read_map() is done instead of plain bitmap_set_bit().

Some test cases are only reproducible in 10.4+, but the fix is applicable
to 10.2+
This commit is contained in:
Nikita Malyavin
2021-06-22 18:30:53 +03:00
parent 7d9ba57da4
commit 0f6a5b4390
8 changed files with 152 additions and 13 deletions

View File

@@ -6329,7 +6329,7 @@ void TABLE::prepare_for_position()
if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
s->primary_key < MAX_KEY)
{
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
mark_columns_used_by_index_for_read_no_reset(s->primary_key);
/* signal change */
file->column_bitmaps_signal();
}
@@ -6385,23 +6385,36 @@ void TABLE::restore_column_maps_after_keyread(MY_BITMAP *backup)
DBUG_VOID_RETURN;
}
static void mark_index_columns(TABLE *table, uint index,
MY_BITMAP *bitmap, bool read)
{
KEY_PART_INFO *key_part= table->key_info[index].key_part;
uint key_parts= table->key_info[index].user_defined_key_parts;
for (uint k= 0; k < key_parts; k++)
if (read)
key_part[k].field->register_field_in_read_map();
else
bitmap_set_bit(bitmap, key_part[k].fieldnr-1);
if (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
table->s->primary_key != MAX_KEY && table->s->primary_key != index)
mark_index_columns(table, table->s->primary_key, bitmap, read);
}
/*
mark columns used by key, but don't reset other fields
*/
void TABLE::mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *bitmap)
inline void TABLE::mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *bitmap)
{
KEY_PART_INFO *key_part= key_info[index].key_part;
KEY_PART_INFO *key_part_end= (key_part + key_info[index].user_defined_key_parts);
for (;key_part != key_part_end; key_part++)
bitmap_set_bit(bitmap, key_part->fieldnr-1);
if (file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
s->primary_key != MAX_KEY && s->primary_key != index)
mark_columns_used_by_index_no_reset(s->primary_key, bitmap);
mark_index_columns(this, index, bitmap, false);
}
inline void TABLE::mark_columns_used_by_index_for_read_no_reset(uint index)
{
mark_index_columns(this, index, read_set, true);
}
/*
Mark auto-increment fields as used fields in both read and write maps
@@ -6420,7 +6433,7 @@ void TABLE::mark_auto_increment_column()
bitmap_set_bit(read_set, found_next_number_field->field_index);
bitmap_set_bit(write_set, found_next_number_field->field_index);
if (s->next_number_keypart)
mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
mark_columns_used_by_index_for_read_no_reset(s->next_number_index);
file->column_bitmaps_signal();
}
@@ -6476,7 +6489,7 @@ void TABLE::mark_columns_needed_for_delete()
file->use_hidden_primary_key();
else
{
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
mark_columns_used_by_index_for_read_no_reset(s->primary_key);
need_signal= true;
}
}
@@ -6566,7 +6579,7 @@ void TABLE::mark_columns_needed_for_update()
file->use_hidden_primary_key();
else
{
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
mark_columns_used_by_index_for_read_no_reset(s->primary_key);
need_signal= true;
}
}
@@ -6729,7 +6742,7 @@ void TABLE::mark_columns_per_binlog_row_image()
We don't need to mark the primary key in the rpl_write_set as the
binary log will include all columns read anyway.
*/
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
mark_columns_used_by_index_for_read_no_reset(s->primary_key);
/* Only write columns that have changed */
rpl_write_set= write_set;
break;