Commit 5ebc663d authored by Aleksey Midenkov's avatar Aleksey Midenkov

MDEV-30926 Segfault after MyISAM repair of vcol-indexed table

mi_repair_by_sort() allocates record and creates index which does
compute_vcols() which does move_fields() into allocated record but
does not restore fields back. Then record is freed by
mi_repair_by_sort() and the table fields still point to it.

The fix restores back field pointers in compute_vcols().
parent f4ee7c11
......@@ -455,3 +455,19 @@ ERROR 21S01: Column count doesn't match value count at row 1
drop table t1;
set sql_mode= @old_mode;
set myisam_repair_threads= @old_myisam_repair_threads;
#
# MDEV-30926 Segfault after MyISAM repair of vcol-indexed table
#
set sql_mode='';
create table t (a int generated always as (1) virtual, key(a)) engine=myisam;
insert into t select 1;
Warnings:
Warning 1906 The value specified for generated column 'a' in table 't' has been ignored
select * from non_existing_tbl;
ERROR 42S02: Table 'test.non_existing_tbl' doesn't exist
select * from t;
a
1
show open tables like '';
Database Table In_use Name_locked
drop table t;
......@@ -342,3 +342,15 @@ insert into t1 select 'qux';
drop table t1;
set sql_mode= @old_mode;
set myisam_repair_threads= @old_myisam_repair_threads;
--echo #
--echo # MDEV-30926 Segfault after MyISAM repair of vcol-indexed table
--echo #
set sql_mode='';
create table t (a int generated always as (1) virtual, key(a)) engine=myisam;
insert into t select 1;
--error ER_NO_SUCH_TABLE
select * from non_existing_tbl;
select * from t;
show open tables like '';
drop table t;
......@@ -724,12 +724,14 @@ static int compute_vcols(MI_INFO *info, uchar *record, int keynum)
/* This mutex is needed for parallel repair */
mysql_mutex_lock(&info->s->intern_lock);
TABLE *table= (TABLE*)(info->external_ref);
table->move_fields(table->field, record, table->field[0]->record_ptr());
uchar *old_record= table->field[0]->record_ptr();
table->move_fields(table->field, record, old_record);
if (keynum == -1) // update all vcols
{
int error= table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ);
if (table->update_virtual_fields(table->file, VCOL_UPDATE_INDEXED))
error= 1;
table->move_fields(table->field, old_record, record);
mysql_mutex_unlock(&info->s->intern_lock);
return error;
}
......@@ -742,6 +744,7 @@ static int compute_vcols(MI_INFO *info, uchar *record, int keynum)
if (f->vcol_info && !f->vcol_info->stored_in_db)
table->update_virtual_field(f, false);
}
table->move_fields(table->field, old_record, record);
mysql_mutex_unlock(&info->s->intern_lock);
return 0;
}
......
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