=== modified file 'sql/sql_select.cc'
--- sql/sql_select.cc	2013-05-07 11:05:09 +0000
+++ sql/sql_select.cc	2013-05-16 12:59:24 +0000
@@ -2623,7 +2623,7 @@ JOIN::exec()
       curr_join->select_distinct=0;		/* Each row is unique */
     
 
-    curr_join->join_free();			/* Free quick selects */
+    curr_join->join_free(1);			/* Free quick selects */
 
     if (curr_join->select_distinct && ! curr_join->group_list)
     {
@@ -10538,7 +10538,7 @@ bool TABLE_REF::is_access_triggered()
     Unlock tables even if the join isn't top level select in the tree
 */
 
-void JOIN::join_free()
+void JOIN::join_free(bool force_full)
 {
   SELECT_LEX_UNIT *tmp_unit;
   SELECT_LEX *sl;
@@ -10546,7 +10546,8 @@ void JOIN::join_free()
     Optimization: if not EXPLAIN and we are done with the JOIN,
     free all tables.
   */
-  bool full= !(select_lex->uncacheable) &&  !(thd->lex->describe);
+  bool full= force_full ||
+    (!(select_lex->uncacheable) &&  !(thd->lex->describe));
   bool can_unlock= full;
   DBUG_ENTER("JOIN::join_free");
 

=== modified file 'sql/sql_select.h'
--- sql/sql_select.h	2013-05-07 11:05:09 +0000
+++ sql/sql_select.h	2013-05-16 12:28:44 +0000
@@ -1352,7 +1352,7 @@ class JOIN :public Sql_alloc
     the end of execution in order to increase concurrency and reduce
     memory consumption.
   */
-  void join_free();
+  void join_free(bool force_full= 0);
   /** Cleanup this JOIN, possibly for reuse */
   void cleanup(bool full);
   void clear();

