diff --git a/sql/sp.cc b/sql/sp.cc
index c8dc328ced147373ca5eb1a253ef5097713d5580..2d7e38b47bd777ef00c0e7ed21d010cbb601bbd0 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -373,13 +373,11 @@ sp_cache_functions(THD *thd, LEX *lex)
 void
 sp_clear_function_cache(THD *thd)
 {
-  //QQ This doesn't work for some completely mysterious reason, but since this
-  //QQ is tempoarary code anyway, we just ignore it for now.
-  //QQ List_iterator_fast<sp_head> li(thd->spfuns);
-  //QQ  sp_head *sp;
+  List_iterator_fast<sp_head> li(thd->spfuns);
+  sp_head *sp;
 
-  //QQ  while ((sp= li++))
-  //QQ    sp->destroy();
+  while ((sp= li++))
+    sp->destroy();
   thd->spfuns.empty();
 }
 
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index ed6e07aa0a80c4b904468e19bdd88a875706a279..758345f764af9c3afdbfdc70cdcba388e83d4b3f 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -94,8 +94,10 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type)
 sp_head::sp_head(LEX_STRING *name, LEX *lex)
   : Sql_alloc(), m_simple_case(FALSE)
 {
+  DBUG_ENTER("sp_head::sp_head");
   const char *dstr = (const char*)lex->buf;
 
+  DBUG_PRINT("info", ("name: %s", name->str));
   m_name.length= name->length;
   m_name.str= name->str;
   m_defstr.length= lex->end_of_query - lex->buf;
@@ -103,6 +105,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex)
   m_pcont= lex->spcont;
   my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8);
   m_backpatch.empty();
+  DBUG_VOID_RETURN;
 }
 
 int
@@ -128,8 +131,11 @@ sp_head::create(THD *thd)
 void
 sp_head::destroy()
 {
+  DBUG_ENTER("sp_head::destroy");
+  DBUG_PRINT("info", ("name: %s", m_name.str));
   delete_dynamic(&m_instr);
   m_pcont->destroy();
+  DBUG_VOID_RETURN;
 }
 
 int
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4d9cb0729324c1d351e68403b6a9c573ebbef2ad..5d98d95a130aa9a2b1ca729edc082547891e2e6f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1523,6 +1523,14 @@ restore_user:
   thread_running--;
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
   thd->packet.shrink(thd->variables.net_buffer_length);	// Reclaim some memory
+
+  /*
+    Clear the SP function cache after each statement (QQ this is a temporary
+    solution; caching will be rehacked later).
+    Note: Must do this before we free_root.
+  */
+  sp_clear_function_cache(thd);
+
   free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
   DBUG_RETURN(error);
 }
@@ -1587,11 +1595,6 @@ mysql_execute_command(THD *thd)
   SELECT_LEX_UNIT *unit= &lex->unit;
   DBUG_ENTER("mysql_execute_command");
 
-  /*
-    Clear the SP function cache before each statement (QQ this is a temporary
-    solution; caching will be rehacked later), and the new ones.
-  */
-  sp_clear_function_cache(thd);
   if (lex->sql_command != SQLCOM_CREATE_PROCEDURE &&
       lex->sql_command != SQLCOM_CREATE_SPFUNCTION)
   {
@@ -3009,6 +3012,9 @@ mysql_execute_command(THD *thd)
       }
 #endif
       res= lex->sphead->create(thd);
+
+      lex->sphead->destroy();	// QQ Free memory. Remove this when caching!!!
+
       switch (res)
       {
       case SP_OK: