Skip to content

Commit 16b1cb6

Browse files
committed
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.
1 parent 4c6c352 commit 16b1cb6

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

mysql-test/suite/vcol/r/update.result

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,13 @@ select * from t;
155155
a b c d e
156156
11 11 11 11 11
157157
drop table t, t1, t2;
158+
create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
159+
insert into t (f1,f2) values (1,1),(2,2);
160+
create view v as
161+
select a2.f1, a2.f2, a1.f3
162+
from t a1, t a2
163+
where a2.f3 <> 0
164+
with local check option;
165+
update v set f3 = 52;
166+
drop view v;
167+
drop table t;

mysql-test/suite/vcol/t/update.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,17 @@ check table t; select * from t;
111111
update t, t tt set t.b=11, tt.d=11 where t.a=tt.a;
112112
check table t; select * from t;
113113
drop table t, t1, t2;
114+
115+
#
116+
# MDEV-13623 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in virtual longlong Field_long::val_int
117+
#
118+
create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
119+
insert into t (f1,f2) values (1,1),(2,2);
120+
create view v as
121+
select a2.f1, a2.f2, a1.f3
122+
from t a1, t a2
123+
where a2.f3 <> 0
124+
with local check option;
125+
update v set f3 = 52;
126+
drop view v;
127+
drop table t;

sql/sql_update.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,6 +2308,26 @@ int multi_update::do_updates()
23082308
do_update= 0; // Don't retry this function
23092309
if (!found)
23102310
DBUG_RETURN(0);
2311+
2312+
/*
2313+
Update read_set to include all fields that virtual columns may depend on.
2314+
Usually they're already in the read_set, but if the previous access
2315+
method was keyread, only the virtual column itself will be in read_set,
2316+
not its dependencies
2317+
*/
2318+
while(TABLE *tbl= check_opt_it++)
2319+
{
2320+
if (tbl->vcol_set)
2321+
{
2322+
bitmap_clear_all(tbl->vcol_set);
2323+
for (Field **vf= tbl->vfield; *vf; vf++)
2324+
{
2325+
if (bitmap_is_set(tbl->read_set, (*vf)->field_index))
2326+
tbl->mark_virtual_col(*vf);
2327+
}
2328+
}
2329+
}
2330+
23112331
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
23122332
{
23132333
bool can_compare_record;

0 commit comments

Comments
 (0)