Loading mysql-test/r/sp-threads.result +15 −0 Original line number Diff line number Diff line Loading @@ -40,3 +40,18 @@ Id User Host db Command Time State Info unlock tables; drop procedure bug9486; drop table t1, t2; drop procedure if exists bug11158; create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id; create table t1 (id int, j int); insert into t1 values (1, 1), (2, 2); create table t2 (id int); insert into t2 values (1); call bug11158(); select * from t1; id j 2 2 lock tables t2 read; call bug11158(); unlock tables; drop procedure bug11158; drop table t1, t2; mysql-test/t/sp-threads.test +26 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,32 @@ reap; drop procedure bug9486; drop table t1, t2; # # BUG#11158: Can't perform multi-delete in stored procedure # --disable_warnings drop procedure if exists bug11158; --enable_warnings create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id; create table t1 (id int, j int); insert into t1 values (1, 1), (2, 2); create table t2 (id int); insert into t2 values (1); # Procedure should work and cause proper effect (delete only first row) call bug11158(); select * from t1; # Also let us test that we obtain only read (and thus non exclusive) lock # for table from which we are not going to delete rows. connection con2root; lock tables t2 read; connection con1root; call bug11158(); connection con2root; unlock tables; connection con1root; # Clean-up drop procedure bug11158; drop table t1, t2; # # BUG#NNNN: New bug synopsis Loading sql/mysql_priv.h +2 −1 Original line number Diff line number Diff line Loading @@ -482,7 +482,7 @@ bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables); bool mysql_multi_update_prepare(THD *thd); bool mysql_multi_delete_prepare(THD *thd); bool mysql_insert_select_prepare(THD *thd); Loading Loading @@ -577,6 +577,7 @@ void mysql_init_query(THD *thd, uchar *buf, uint length); bool mysql_new_select(LEX *lex, bool move_down); void create_select_for_variable(const char *var_name); void mysql_init_multi_delete(LEX *lex); bool multi_delete_set_locks_and_link_aux_tables(LEX *lex); void init_max_user_conn(void); void init_update_queries(void); void free_max_user_conn(void); Loading sql/sql_base.cc +0 −28 Original line number Diff line number Diff line Loading @@ -42,7 +42,6 @@ static my_bool open_new_frm(const char *path, const char *alias, uint db_stat, uint prgflag, uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc, MEM_ROOT *mem_root); static void relink_tables_for_multidelete(THD *thd); extern "C" byte *table_cache_key(const byte *record,uint *length, my_bool not_used __attribute__((unused))) Loading Loading @@ -2089,7 +2088,6 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) (thd->fill_derived_tables() && mysql_handle_derived(thd->lex, &mysql_derived_filling))) DBUG_RETURN(TRUE); /* purecov: inspected */ relink_tables_for_multidelete(thd); DBUG_RETURN(0); } Loading Loading @@ -2119,36 +2117,10 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) if (open_tables(thd, &tables, &counter) || mysql_handle_derived(thd->lex, &mysql_derived_prepare)) DBUG_RETURN(TRUE); /* purecov: inspected */ relink_tables_for_multidelete(thd); // Not really needed, but DBUG_RETURN(0); } /* Let us propagate pointers to open tables from global table list to table lists for multi-delete */ static void relink_tables_for_multidelete(THD *thd) { if (thd->lex->all_selects_list->next_select_in_list()) { for (SELECT_LEX *sl= thd->lex->all_selects_list; sl; sl= sl->next_select_in_list()) { for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first; cursor; cursor=cursor->next_local) { if (cursor->correspondent_table) cursor->table= cursor->correspondent_table->table; } } } } /* Mark all real tables in the list as free for reuse. Loading sql/sql_lex.h +6 −1 Original line number Diff line number Diff line Loading @@ -751,7 +751,12 @@ typedef struct st_lex uint grant, grant_tot_col, which_columns; uint fk_delete_opt, fk_update_opt, fk_match_option; uint slave_thd_opt, start_transaction_opt; uint table_count; /* used when usual update transformed in multiupdate */ /* In LEX representing update which were transformed to multi-update stores total number of tables. For LEX representing multi-delete holds number of tables from which we will delete records. */ uint table_count; uint8 describe; uint8 derived_tables; uint8 create_view_algorithm; Loading Loading
mysql-test/r/sp-threads.result +15 −0 Original line number Diff line number Diff line Loading @@ -40,3 +40,18 @@ Id User Host db Command Time State Info unlock tables; drop procedure bug9486; drop table t1, t2; drop procedure if exists bug11158; create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id; create table t1 (id int, j int); insert into t1 values (1, 1), (2, 2); create table t2 (id int); insert into t2 values (1); call bug11158(); select * from t1; id j 2 2 lock tables t2 read; call bug11158(); unlock tables; drop procedure bug11158; drop table t1, t2;
mysql-test/t/sp-threads.test +26 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,32 @@ reap; drop procedure bug9486; drop table t1, t2; # # BUG#11158: Can't perform multi-delete in stored procedure # --disable_warnings drop procedure if exists bug11158; --enable_warnings create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id; create table t1 (id int, j int); insert into t1 values (1, 1), (2, 2); create table t2 (id int); insert into t2 values (1); # Procedure should work and cause proper effect (delete only first row) call bug11158(); select * from t1; # Also let us test that we obtain only read (and thus non exclusive) lock # for table from which we are not going to delete rows. connection con2root; lock tables t2 read; connection con1root; call bug11158(); connection con2root; unlock tables; connection con1root; # Clean-up drop procedure bug11158; drop table t1, t2; # # BUG#NNNN: New bug synopsis Loading
sql/mysql_priv.h +2 −1 Original line number Diff line number Diff line Loading @@ -482,7 +482,7 @@ bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables); bool mysql_multi_update_prepare(THD *thd); bool mysql_multi_delete_prepare(THD *thd); bool mysql_insert_select_prepare(THD *thd); Loading Loading @@ -577,6 +577,7 @@ void mysql_init_query(THD *thd, uchar *buf, uint length); bool mysql_new_select(LEX *lex, bool move_down); void create_select_for_variable(const char *var_name); void mysql_init_multi_delete(LEX *lex); bool multi_delete_set_locks_and_link_aux_tables(LEX *lex); void init_max_user_conn(void); void init_update_queries(void); void free_max_user_conn(void); Loading
sql/sql_base.cc +0 −28 Original line number Diff line number Diff line Loading @@ -42,7 +42,6 @@ static my_bool open_new_frm(const char *path, const char *alias, uint db_stat, uint prgflag, uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc, MEM_ROOT *mem_root); static void relink_tables_for_multidelete(THD *thd); extern "C" byte *table_cache_key(const byte *record,uint *length, my_bool not_used __attribute__((unused))) Loading Loading @@ -2089,7 +2088,6 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) (thd->fill_derived_tables() && mysql_handle_derived(thd->lex, &mysql_derived_filling))) DBUG_RETURN(TRUE); /* purecov: inspected */ relink_tables_for_multidelete(thd); DBUG_RETURN(0); } Loading Loading @@ -2119,36 +2117,10 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) if (open_tables(thd, &tables, &counter) || mysql_handle_derived(thd->lex, &mysql_derived_prepare)) DBUG_RETURN(TRUE); /* purecov: inspected */ relink_tables_for_multidelete(thd); // Not really needed, but DBUG_RETURN(0); } /* Let us propagate pointers to open tables from global table list to table lists for multi-delete */ static void relink_tables_for_multidelete(THD *thd) { if (thd->lex->all_selects_list->next_select_in_list()) { for (SELECT_LEX *sl= thd->lex->all_selects_list; sl; sl= sl->next_select_in_list()) { for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first; cursor; cursor=cursor->next_local) { if (cursor->correspondent_table) cursor->table= cursor->correspondent_table->table; } } } } /* Mark all real tables in the list as free for reuse. Loading
sql/sql_lex.h +6 −1 Original line number Diff line number Diff line Loading @@ -751,7 +751,12 @@ typedef struct st_lex uint grant, grant_tot_col, which_columns; uint fk_delete_opt, fk_update_opt, fk_match_option; uint slave_thd_opt, start_transaction_opt; uint table_count; /* used when usual update transformed in multiupdate */ /* In LEX representing update which were transformed to multi-update stores total number of tables. For LEX representing multi-delete holds number of tables from which we will delete records. */ uint table_count; uint8 describe; uint8 derived_tables; uint8 create_view_algorithm; Loading