Loading mysql-test/r/sp-threads.result +17 −0 Original line number Diff line number Diff line Loading @@ -23,3 +23,20 @@ select * from t1; s1 s2 s3 drop table t1; drop procedure bug4934; drop procedure if exists bug9486; drop table if exists t1, t2; create table t1 (id1 int, val int); create table t2 (id2 int); create procedure bug9486() update t1, t2 set val= 1 where id1=id2; call bug9486(); lock tables t2 write; call bug9486(); show processlist; Id User Host db Command Time State Info # root localhost test Sleep # NULL # root localhost test Query # Locked call bug9486() # root localhost test Query # NULL show processlist unlock tables; drop procedure bug9486; drop table t1, t2; mysql-test/t/sp-threads.test +31 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,37 @@ drop table t1; drop procedure bug4934; # # BUG #9486 "Can't perform multi-update in stored procedure" # --disable_warnings drop procedure if exists bug9486; drop table if exists t1, t2; --enable_warnings create table t1 (id1 int, val int); create table t2 (id2 int); create procedure bug9486() update t1, t2 set val= 1 where id1=id2; call bug9486(); # Let us check that SP invocation requires write lock for t2. connection con2root; lock tables t2 write; connection con1root; send call bug9486(); connection con2root; --sleep 2 # There should be call statement in locked state. --replace_column 1 # 6 # show processlist; unlock tables; connection con1root; reap; drop procedure bug9486; drop table t1, t2; # # BUG#NNNN: New bug synopsis # Loading sql/sp_head.cc +10 −3 Original line number Diff line number Diff line Loading @@ -2060,6 +2060,12 @@ typedef struct st_sp_table LEX_STRING qname; bool temp; TABLE_LIST *table; /* We can't use table->lock_type as lock type for table in multi-set since it can be changed by statement during its execution (e.g. as this happens for multi-update). */ thr_lock_type lock_type; uint lock_count; uint query_lock_count; } SP_TABLE; Loading Loading @@ -2131,8 +2137,8 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) */ if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen))) { if (tab->table->lock_type < table->lock_type) tab->table= table; // Use the table with the highest lock type if (tab->lock_type < table->lock_type) tab->lock_type= table->lock_type; // Use the table with the highest lock type tab->query_lock_count++; if (tab->query_lock_count > tab->lock_count) tab->lock_count++; Loading @@ -2150,6 +2156,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE) tab->temp= TRUE; tab->table= table; tab->lock_type= table->lock_type; tab->lock_count= tab->query_lock_count= 1; my_hash_insert(&m_sptabs, (byte *)tab); } Loading Loading @@ -2222,7 +2229,7 @@ sp_head::add_used_tables_to_table_list(THD *thd, table->alias= otable->alias; table->table_name= otable->table_name; table->table_name_length= otable->table_name_length; table->lock_type= otable->lock_type; table->lock_type= stab->lock_type; table->cacheable_table= 1; table->prelocking_placeholder= 1; Loading sql/sql_lex.h +1 −1 Original line number Diff line number Diff line Loading @@ -732,7 +732,7 @@ typedef struct st_lex USER_RESOURCES mqh; ulong type; enum_sql_command sql_command, orig_sql_command; thr_lock_type lock_option, multi_lock_option; thr_lock_type lock_option; enum SSL_type ssl_type; /* defined in violite.h */ enum my_lex_states next_state; enum enum_duplicates duplicates; Loading sql/sql_prepare.cc +0 −5 Original line number Diff line number Diff line Loading @@ -1012,11 +1012,6 @@ static int mysql_test_update(Prepared_statement *stmt, DBUG_PRINT("info", ("Switch to multi-update")); /* pass counter value */ thd->lex->table_count= table_count; /* give correct value to multi_lock_option, because it will be used in multiupdate */ thd->lex->multi_lock_option= table_list->lock_type; /* convert to multiupdate */ return 2; } Loading Loading
mysql-test/r/sp-threads.result +17 −0 Original line number Diff line number Diff line Loading @@ -23,3 +23,20 @@ select * from t1; s1 s2 s3 drop table t1; drop procedure bug4934; drop procedure if exists bug9486; drop table if exists t1, t2; create table t1 (id1 int, val int); create table t2 (id2 int); create procedure bug9486() update t1, t2 set val= 1 where id1=id2; call bug9486(); lock tables t2 write; call bug9486(); show processlist; Id User Host db Command Time State Info # root localhost test Sleep # NULL # root localhost test Query # Locked call bug9486() # root localhost test Query # NULL show processlist unlock tables; drop procedure bug9486; drop table t1, t2;
mysql-test/t/sp-threads.test +31 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,37 @@ drop table t1; drop procedure bug4934; # # BUG #9486 "Can't perform multi-update in stored procedure" # --disable_warnings drop procedure if exists bug9486; drop table if exists t1, t2; --enable_warnings create table t1 (id1 int, val int); create table t2 (id2 int); create procedure bug9486() update t1, t2 set val= 1 where id1=id2; call bug9486(); # Let us check that SP invocation requires write lock for t2. connection con2root; lock tables t2 write; connection con1root; send call bug9486(); connection con2root; --sleep 2 # There should be call statement in locked state. --replace_column 1 # 6 # show processlist; unlock tables; connection con1root; reap; drop procedure bug9486; drop table t1, t2; # # BUG#NNNN: New bug synopsis # Loading
sql/sp_head.cc +10 −3 Original line number Diff line number Diff line Loading @@ -2060,6 +2060,12 @@ typedef struct st_sp_table LEX_STRING qname; bool temp; TABLE_LIST *table; /* We can't use table->lock_type as lock type for table in multi-set since it can be changed by statement during its execution (e.g. as this happens for multi-update). */ thr_lock_type lock_type; uint lock_count; uint query_lock_count; } SP_TABLE; Loading Loading @@ -2131,8 +2137,8 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) */ if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen))) { if (tab->table->lock_type < table->lock_type) tab->table= table; // Use the table with the highest lock type if (tab->lock_type < table->lock_type) tab->lock_type= table->lock_type; // Use the table with the highest lock type tab->query_lock_count++; if (tab->query_lock_count > tab->lock_count) tab->lock_count++; Loading @@ -2150,6 +2156,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE) tab->temp= TRUE; tab->table= table; tab->lock_type= table->lock_type; tab->lock_count= tab->query_lock_count= 1; my_hash_insert(&m_sptabs, (byte *)tab); } Loading Loading @@ -2222,7 +2229,7 @@ sp_head::add_used_tables_to_table_list(THD *thd, table->alias= otable->alias; table->table_name= otable->table_name; table->table_name_length= otable->table_name_length; table->lock_type= otable->lock_type; table->lock_type= stab->lock_type; table->cacheable_table= 1; table->prelocking_placeholder= 1; Loading
sql/sql_lex.h +1 −1 Original line number Diff line number Diff line Loading @@ -732,7 +732,7 @@ typedef struct st_lex USER_RESOURCES mqh; ulong type; enum_sql_command sql_command, orig_sql_command; thr_lock_type lock_option, multi_lock_option; thr_lock_type lock_option; enum SSL_type ssl_type; /* defined in violite.h */ enum my_lex_states next_state; enum enum_duplicates duplicates; Loading
sql/sql_prepare.cc +0 −5 Original line number Diff line number Diff line Loading @@ -1012,11 +1012,6 @@ static int mysql_test_update(Prepared_statement *stmt, DBUG_PRINT("info", ("Switch to multi-update")); /* pass counter value */ thd->lex->table_count= table_count; /* give correct value to multi_lock_option, because it will be used in multiupdate */ thd->lex->multi_lock_option= table_list->lock_type; /* convert to multiupdate */ return 2; } Loading