Bug#21039 Transaction cache not flushed after SELECT CREATE

 - Add prelocking for stored procedures that uses sp or sf
 - Update test result for sp_error(reported as bug#21294)
 - Make note about new error message from sp-error(bug#17244)
parent 420d40d3
......@@ -754,7 +754,7 @@ bug11834_2()
10
drop function bug11834_1;
execute stmt;
ERROR 42000: FUNCTION test.bug11834_1 does not exist
ERROR 42000: FUNCTION test.bug11834_2 does not exist
deallocate prepare stmt;
drop function bug11834_2;
DROP FUNCTION IF EXISTS bug12953|
......
......@@ -25,17 +25,6 @@ Id User Host db Command Time State Info
# event_scheduler localhost NULL Connect # Suspended NULL
# root localhost test Query # NULL show processlist
drop procedure bug4902_2|
drop function if exists bug5278|
create function bug5278 () returns char
begin
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
return 'okay';
end|
select bug5278()|
ERROR 42000: Can't find any matching row in the user table
select bug5278()|
ERROR 42000: Can't find any matching row in the user table
drop function bug5278|
drop table if exists t1|
create table t1 (
id char(16) not null default '',
......
......@@ -1075,6 +1075,10 @@ execute stmt;
drop function bug11834_1;
# Attempt to execute statement should return proper error and
# should not crash server.
# NOTE! The error we get from the below query indicates that the sp bug11834_2
# does not exist(this is wrong but can be accepted)
# This behaviour has been reported as bug#21294
--error ER_SP_DOES_NOT_EXIST
execute stmt;
deallocate prepare stmt;
......
......@@ -46,6 +46,8 @@ call bug4902_2()|
drop procedure bug4902_2|
# Disable until bug#17244 is fixed
--disable_parsing
#
# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
#
......@@ -63,7 +65,7 @@ select bug5278()|
--error 1133
select bug5278()|
drop function bug5278|
--enable_parsing
--disable_warnings
drop table if exists t1|
......
......@@ -1537,7 +1537,6 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src,
first_no_prelock - If true, don't add tables or cache routines used by
the body of the first routine (i.e. *start)
will be executed in non-prelocked mode.
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
NOTE
If some function is missing this won't be reported here.
Instead this fact will be discovered during query execution.
......@@ -1550,10 +1549,9 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src,
static int
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
Sroutine_hash_entry *start,
bool first_no_prelock, bool *tabs_changed)
bool first_no_prelock)
{
int ret= 0;
bool tabschnd= 0; /* Set if tables changed */
bool first= TRUE;
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
......@@ -1626,16 +1624,13 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
{
sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines,
rt->belong_to_view);
tabschnd|=
sp->add_used_tables_to_table_list(thd, &lex->query_tables_last,
rt->belong_to_view);
(void)sp->add_used_tables_to_table_list(thd, &lex->query_tables_last,
rt->belong_to_view);
}
sp->propagate_attributes(lex);
}
first= FALSE;
}
if (tabs_changed) /* it can be NULL */
*tabs_changed= tabschnd;
DBUG_RETURN(ret);
}
......@@ -1651,20 +1646,18 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
lex - LEX representing statement
first_no_prelock - If true, don't add tables or cache routines used by
the body of the first routine (i.e. *start)
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
RETURN VALUE
0 - success
non-0 - failure
*/
int
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock,
bool *tabs_changed)
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
{
return sp_cache_routines_and_add_tables_aux(thd, lex,
(Sroutine_hash_entry *)lex->sroutines_list.first,
first_no_prelock, tabs_changed);
first_no_prelock);
}
......@@ -1691,9 +1684,8 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, TABLE_LIST *view)
(Sroutine_hash_entry **)lex->sroutines_list.next;
sp_update_stmt_used_routines(thd, lex, &view->view->sroutines_list,
view->top_table());
return sp_cache_routines_and_add_tables_aux(thd, lex,
*last_cached_routine_ptr, FALSE,
NULL);
return sp_cache_routines_and_add_tables_aux(thd, lex,
*last_cached_routine_ptr, FALSE);
}
......@@ -1742,8 +1734,7 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
}
}
ret= sp_cache_routines_and_add_tables_aux(thd, lex,
*last_cached_routine_ptr,
FALSE, NULL);
*last_cached_routine_ptr, FALSE);
}
return ret;
}
......
......@@ -88,8 +88,7 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
void sp_remove_not_own_routines(LEX *lex);
void sp_update_sp_used_routines(HASH *dst, HASH *src);
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
bool first_no_prelock,
bool *tabs_changed);
bool first_no_prelock);
int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
TABLE_LIST *view);
int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
......
......@@ -2855,25 +2855,18 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
statement for which table list for prelocking is already built, let
us cache routines and try to build such table list.
NOTE: We will mark statement as requiring prelocking only if we will
have non empty table list. But this does not guarantee that in prelocked
mode we will have some locked tables, because queries which use only
derived/information schema tables and views possible. Thus "counter"
may be still zero for prelocked statement...
*/
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
thd->lex->sroutines_list.elements)
{
bool first_no_prelocking, need_prelocking, tabs_changed;
bool first_no_prelocking, need_prelocking;
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
DBUG_ASSERT(thd->lex->query_tables == *start);
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
if (sp_cache_routines_and_add_tables(thd, thd->lex,
first_no_prelocking,
&tabs_changed))
if (sp_cache_routines_and_add_tables(thd, thd->lex, first_no_prelocking))
{
/*
Serious error during reading stored routines from mysql.proc table.
......@@ -2883,7 +2876,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
result= -1;
goto err;
}
else if ((tabs_changed || *start) && need_prelocking)
else if (need_prelocking)
{
query_tables_last_own= save_query_tables_last;
*start= thd->lex->query_tables;
......@@ -3310,11 +3303,6 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
in prelocked mode.
*/
DBUG_ASSERT(!thd->prelocked_mode || !thd->lex->requires_prelocking());
/*
If statement requires prelocking then it has non-empty table list.
So it is safe to shortcut.
*/
DBUG_ASSERT(!thd->lex->requires_prelocking() || tables);
*need_reopen= FALSE;
......@@ -3326,7 +3314,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
thd->set_current_stmt_binlog_row_based_if_mixed();
#endif /*HAVE_ROW_BASED_REPLICATION*/
if (!tables)
if (!tables && !thd->lex->requires_prelocking())
DBUG_RETURN(0);
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment