From 807ecdf43ae2c5f35c2f350e67242580618ff9a8 Mon Sep 17 00:00:00 2001 From: unknown <andrey@example.com> Date: Thu, 24 Aug 2006 19:36:26 +0200 Subject: [PATCH 1/2] 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. --- mysql-test/r/sp.result | 7 +++++++ mysql-test/t/sp.test | 10 ++++++++++ sql/sp.cc | 21 +++++++++++++++------ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index d4c77bc47e5..854935b071b 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5387,4 +5387,11 @@ BEGIN RETURN 1; END| 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; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index bf255bf631a..4b0f463a9e3 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -6312,6 +6312,16 @@ BEGIN 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 # diff --git a/sql/sp.cc b/sql/sp.cc index b7bf049cb1d..fc72822c15e 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1006,6 +1006,12 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, } 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; if (level > depth) { @@ -1175,19 +1181,22 @@ sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics) int sp_show_create_procedure(THD *thd, sp_name *name) { + int ret= SP_KEY_NOT_FOUND; sp_head *sp; DBUG_ENTER("sp_show_create_procedure"); 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, &thd->sp_proc_cache, FALSE))) - { - int ret= sp->show_create_procedure(thd); + ret= sp->show_create_procedure(thd); - DBUG_RETURN(ret); - } - - DBUG_RETURN(SP_KEY_NOT_FOUND); + thd->variables.max_sp_recursion_depth--; + DBUG_RETURN(ret); } From 5d37fce9e84d5efc669306bddc156849aeaade87 Mon Sep 17 00:00:00 2001 From: unknown <kroki/tomash@moonlight.intranet> Date: Fri, 25 Aug 2006 11:34:13 +0400 Subject: [PATCH 2/2] Comment cleanup after push of bug#21166. --- sql/item.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index ac0658224b3..007b3ee600f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -421,11 +421,10 @@ void Item::rename(char *new_name) /* - transform() - traverse item tree possibly transforming it (replacing - items) + Traverse item tree possibly transforming it (replacing items). SYNOPSIS - transform() + Item::transform() transformer functor that performs transformation of a subtree arg opaque argument passed to the functor @@ -450,9 +449,9 @@ void Item::rename(char *new_name) it, please use Item::walk() instead. - RETURN + RETURN VALUE Returns pointer to the new subtree root. THD::change_item_tree() - should be called for it if transformation took place, i.e. if + should be called for it if transformation took place, i.e. if a pointer to newly allocated item is returned. */ @@ -5339,9 +5338,10 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) /* - This method like the walk method traverses the item tree, but at - the same time it can replace some nodes in the tree + This method like the walk method traverses the item tree, but at the + same time it can replace some nodes in the tree */ + Item *Item_default_value::transform(Item_transformer transformer, byte *args) { DBUG_ASSERT(!current_thd->is_stmt_prepare());