diff --git a/mysql-test/r/ndb_lock.result b/mysql-test/r/ndb_lock.result index 668c26aad035f50759b768123aa7023cf8f2d9ad..44eb5c8b3f30660fb89b28da95fb5c2301b12d05 100644 --- a/mysql-test/r/ndb_lock.result +++ b/mysql-test/r/ndb_lock.result @@ -87,11 +87,27 @@ x y z rollback; commit; begin; +select * from t1 where y = 'one' or y = 'three' for update; +x y z +# # # +# # # +begin; +select * from t1 where x = 2 for update; +x y z +2 two 2 +select * from t1 where x = 1 for update; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +commit; +begin; select * from t1 where y = 'one' or y = 'three' order by x for update; x y z 1 one 1 3 three 3 begin; +select * from t1 where x = 2 for update; +x y z +2 two 2 select * from t1 where x = 1 for update; ERROR HY000: Lock wait timeout exceeded; try restarting transaction rollback; @@ -124,6 +140,22 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction rollback; commit; begin; +select * from t1 where y = 'one' or y = 'three' lock in share mode; +x y z +# # # +# # # +begin; +select * from t1 where y = 'one' lock in share mode; +x y z +1 one 1 +select * from t1 where x = 2 for update; +x y z +2 two 2 +select * from t1 where x = 1 for update; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +commit; +begin; select * from t1 where y = 'one' or y = 'three' order by x lock in share mode; x y z 1 one 1 @@ -132,6 +164,9 @@ begin; select * from t1 where y = 'one' lock in share mode; x y z 1 one 1 +select * from t1 where x = 2 for update; +x y z +2 two 2 select * from t1 where x = 1 for update; ERROR HY000: Lock wait timeout exceeded; try restarting transaction rollback; diff --git a/mysql-test/t/ndb_lock.test b/mysql-test/t/ndb_lock.test index 474155e06f4ca1ea6d421cbb1673f8679e4982f3..b036522ad157fd2bec9df9c545f742a06dcde9f4 100644 --- a/mysql-test/t/ndb_lock.test +++ b/mysql-test/t/ndb_lock.test @@ -102,16 +102,36 @@ connection con1; commit; # table scan +# +# Note that there are two distinct execution paths in which we unlock +# non-matching rows inspected during table scan - one that is used in +# case of filesort and one that used in rest of cases. Below we cover +# the latter (Bug #20390 "SELECT FOR UPDATE does not release locks of +# untouched rows in full table scans"). connection con1; begin; -select * from t1 where y = 'one' or y = 'three' order by x for update; +# We can't use "order by x" here as it will cause filesort +--replace_column 1 # 2 # 3 # +select * from t1 where y = 'one' or y = 'three' for update; connection con2; begin; # Have to check with pk access here since scans take locks on # all rows and then release them in chunks -# Bug #20390 SELECT FOR UPDATE does not release locks of untouched rows in full table scans -#select * from t1 where x = 2 for update; +select * from t1 where x = 2 for update; +--error 1205 +select * from t1 where x = 1 for update; +rollback; + +connection con1; +commit; + +# And now the test for case with filesort +begin; +select * from t1 where y = 'one' or y = 'three' order by x for update; +connection con2; +begin; +select * from t1 where x = 2 for update; --error 1205 select * from t1 where x = 1 for update; rollback; @@ -157,15 +177,32 @@ commit; # table scan connection con1; begin; -select * from t1 where y = 'one' or y = 'three' order by x lock in share mode; +# We can't use "order by x" here as it will cause filesort +--replace_column 1 # 2 # 3 # +select * from t1 where y = 'one' or y = 'three' lock in share mode; connection con2; begin; select * from t1 where y = 'one' lock in share mode; # Have to check with pk access here since scans take locks on # all rows and then release them in chunks -# Bug #20390 SELECT FOR UPDATE does not release locks of untouched rows in full table scans -#select * from t1 where x = 2 for update; +select * from t1 where x = 2 for update; +--error 1205 +select * from t1 where x = 1 for update; +rollback; + +connection con1; +commit; + +# And the same test for case with filesort +connection con1; +begin; +select * from t1 where y = 'one' or y = 'three' order by x lock in share mode; + +connection con2; +begin; +select * from t1 where y = 'one' lock in share mode; +select * from t1 where x = 2 for update; --error 1205 select * from t1 where x = 1 for update; rollback; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c8830278e425fc246d5c44ffd9e1e24a3759f504..7715575d65b4b5f9fdebad02e9393293c55072d9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10646,6 +10646,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, */ join->examined_rows++; join->thd->row_count++; + join_tab->read_record.file->unlock_row(); } return NESTED_LOOP_OK; }