Skip to content

Commit 6521b41

Browse files
committed
MDEV-37281 incorrect isolation level in update with unique using hash or without overlap
in 11.4 multi_update::prepare() is called both for single and multi update. as it's invoked before lock_tables(), it cannot do prepare_for_insert(), which calls external_lock() and only can be used on an already locked table
1 parent a7d8c97 commit 6521b41

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

mysql-test/main/update_innodb.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,21 @@ update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE
251251
o_custkey = c_custkey and c_nationkey = n_nationkey and n_name='PERU';
252252
DROP DATABASE dbt3_s001;
253253
set default_storage_engine=@save_default_storage_engine;
254+
use test;
255+
#
256+
# MDEV-37281 incorrect isolation level in update with unique using hash or without overlap
257+
#
258+
create table t1 (id int, e varchar(100), a int, unique (e) using hash) engine=innodb;
259+
insert t1 values(10, '2000-01-01', 0);
260+
insert t1 values(20, '2000-01-02', 1);
261+
insert t1 values(30, '2000-01-03', 2);
262+
set transaction isolation level read committed;
263+
start transaction;
264+
update t1 set a=10 where a=0;
265+
connect con1,localhost,root;
266+
set transaction isolation level read committed;
267+
update t1 set a=20 where a=1;
268+
connection default;
269+
drop table t1;
270+
disconnect con1;
271+
# End of 11.4.tests

mysql-test/main/update_innodb.test

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ let $c1=
193193
c_nationkey = n_nationkey and
194194
n_name='PERU';
195195

196-
197196
explain
198197
update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE between '1992-01-01' and '1992-06-30' and
199198
o_custkey = c_custkey and c_nationkey = n_nationkey and n_name='PERU';
@@ -208,4 +207,23 @@ update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE
208207
DROP DATABASE dbt3_s001;
209208

210209
set default_storage_engine=@save_default_storage_engine;
210+
use test;
211+
212+
--echo #
213+
--echo # MDEV-37281 incorrect isolation level in update with unique using hash or without overlap
214+
--echo #
215+
create table t1 (id int, e varchar(100), a int, unique (e) using hash) engine=innodb;
216+
insert t1 values(10, '2000-01-01', 0);
217+
insert t1 values(20, '2000-01-02', 1);
218+
insert t1 values(30, '2000-01-03', 2);
219+
set transaction isolation level read committed;
220+
start transaction;
221+
update t1 set a=10 where a=0;
222+
--connect con1,localhost,root
223+
set transaction isolation level read committed;
224+
update t1 set a=20 where a=1;
225+
--connection default
226+
drop table t1;
227+
--disconnect con1
211228

229+
--echo # End of 11.4.tests

sql/sql_update.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,8 +1842,6 @@ int multi_update::prepare(List<Item> &not_used_values,
18421842
{
18431843
table->read_set= &table->def_read_set;
18441844
bitmap_union(table->read_set, &table->tmp_set);
1845-
if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE))
1846-
table->file->prepare_for_insert(1);
18471845
}
18481846
}
18491847
if (unlikely(error))
@@ -2076,6 +2074,8 @@ multi_update::initialize_tables(JOIN *join)
20762074
ORDER group;
20772075
TMP_TABLE_PARAM *tmp_param;
20782076

2077+
table->file->prepare_for_insert(1);
2078+
20792079
if (ignore)
20802080
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
20812081
if (table == main_table) // First table in join

0 commit comments

Comments
 (0)