Skip to content

Commit

Permalink
MDEV-13623 Assertion `!table || (!table->read_set || bitmap_is_set(ta…
Browse files Browse the repository at this point in the history
…ble->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.
  • Loading branch information
vuvova committed Sep 18, 2017
1 parent 4c6c352 commit 16b1cb6
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
10 changes: 10 additions & 0 deletions mysql-test/suite/vcol/r/update.result
Original file line number Diff line number Diff line change
Expand Up @@ -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;
14 changes: 14 additions & 0 deletions mysql-test/suite/vcol/t/update.test
Original file line number Diff line number Diff line change
Expand Up @@ -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;
20 changes: 20 additions & 0 deletions sql/sql_update.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 16b1cb6

Please sign in to comment.