Commit 807ecdf4 authored by unknown's avatar unknown

Fix for bug#21416 SP: Recursion level higher than zero needed for non-recursive call

The following procedure was not possible if max_sp_recursion_depth is 0
create procedure show_proc() show create procedure show_proc;
  
Actually there is no recursive call but the limit is checked.
  
Solved by temporarily increasing the thread's limit just before the fetch from cache
and decreasing after that.


mysql-test/r/sp.result:
  update result
mysql-test/t/sp.test:
  Test for bug #21416 SP: Recursion level higher than zero needed for non-recursive call
sql/sp.cc:
  Increase the max_sp_recursion_depth temporarily for SHOW CREATE PROCEDURE call.
  This call is in fact not recursive but is counted as such. Outcome, it will work
  always but if max_sp_recursion_depth is reached we are going to cache one more
  sp_head instance.
parent 965a3970
...@@ -5387,4 +5387,11 @@ BEGIN ...@@ -5387,4 +5387,11 @@ BEGIN
RETURN 1; RETURN 1;
END| END|
ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
drop procedure if exists bug21416|
create procedure bug21416() show create procedure bug21416|
call bug21416()|
Procedure sql_mode Create Procedure
bug21416 CREATE DEFINER=`root`@`localhost` PROCEDURE `bug21416`()
show create procedure bug21416
drop procedure bug21416|
drop table t1,t2; drop table t1,t2;
...@@ -6312,6 +6312,16 @@ BEGIN ...@@ -6312,6 +6312,16 @@ BEGIN
END| END|
#
# BUG#21416: SP: Recursion level higher than zero needed for non-recursive call
#
--disable_warnings
drop procedure if exists bug21416|
--enable_warnings
create procedure bug21416() show create procedure bug21416|
call bug21416()|
drop procedure bug21416|
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
......
...@@ -1006,6 +1006,12 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, ...@@ -1006,6 +1006,12 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
} }
DBUG_RETURN(sp->m_first_free_instance); DBUG_RETURN(sp->m_first_free_instance);
} }
/*
Actually depth could be +1 than the actual value in case a SP calls
SHOW CREATE PROCEDURE. Hence, the linked list could hold up to one more
instance.
*/
level= sp->m_last_cached_sp->m_recursion_level + 1; level= sp->m_last_cached_sp->m_recursion_level + 1;
if (level > depth) if (level > depth)
{ {
...@@ -1175,19 +1181,22 @@ sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics) ...@@ -1175,19 +1181,22 @@ sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics)
int int
sp_show_create_procedure(THD *thd, sp_name *name) sp_show_create_procedure(THD *thd, sp_name *name)
{ {
int ret= SP_KEY_NOT_FOUND;
sp_head *sp; sp_head *sp;
DBUG_ENTER("sp_show_create_procedure"); DBUG_ENTER("sp_show_create_procedure");
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
/*
Increase the recursion limit for this statement. SHOW CREATE PROCEDURE
does not do actual recursion.
*/
thd->variables.max_sp_recursion_depth++;
if ((sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name, if ((sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
&thd->sp_proc_cache, FALSE))) &thd->sp_proc_cache, FALSE)))
{ ret= sp->show_create_procedure(thd);
int ret= sp->show_create_procedure(thd);
DBUG_RETURN(ret); thd->variables.max_sp_recursion_depth--;
} DBUG_RETURN(ret);
DBUG_RETURN(SP_KEY_NOT_FOUND);
} }
......
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