Commit 16b1cb65 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-13623 Assertion `!table || (!table->read_set ||...

MDEV-13623 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in virtual longlong Field_long::val_int

multi-update first runs a select to find affected rows, then performs
a separate update step. On the second step WITH CHECK OPTION rows
are read with rnd_read, but the first step might've been done with
keyread.

keyread over indexed virtual columns only reads the column's value, not
dependent base columns. This is reflected in the read_set too.  But on
the rnd_read step base columns must be read - thus we need to update the
read_set before doing updates.
parent 4c6c3521
......@@ -155,3 +155,13 @@ select * from t;
a b c d e
11 11 11 11 11
drop table t, t1, t2;
create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
insert into t (f1,f2) values (1,1),(2,2);
create view v as
select a2.f1, a2.f2, a1.f3
from t a1, t a2
where a2.f3 <> 0
with local check option;
update v set f3 = 52;
drop view v;
drop table t;
......@@ -111,3 +111,17 @@ check table t; select * from t;
update t, t tt set t.b=11, tt.d=11 where t.a=tt.a;
check table t; select * from t;
drop table t, t1, t2;
#
# MDEV-13623 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in virtual longlong Field_long::val_int
#
create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
insert into t (f1,f2) values (1,1),(2,2);
create view v as
select a2.f1, a2.f2, a1.f3
from t a1, t a2
where a2.f3 <> 0
with local check option;
update v set f3 = 52;
drop view v;
drop table t;
......@@ -2308,6 +2308,26 @@ int multi_update::do_updates()
do_update= 0; // Don't retry this function
if (!found)
DBUG_RETURN(0);
/*
Update read_set to include all fields that virtual columns may depend on.
Usually they're already in the read_set, but if the previous access
method was keyread, only the virtual column itself will be in read_set,
not its dependencies
*/
while(TABLE *tbl= check_opt_it++)
{
if (tbl->vcol_set)
{
bitmap_clear_all(tbl->vcol_set);
for (Field **vf= tbl->vfield; *vf; vf++)
{
if (bitmap_is_set(tbl->read_set, (*vf)->field_index))
tbl->mark_virtual_col(*vf);
}
}
}
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
{
bool can_compare_record;
......
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