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());