diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 29206393b045db78a1387e036196e7c2c1a1add6..bf36b4796b988d15e6f33c8a7b766015c28b597b 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -754,7 +754,7 @@ bug11834_2()
 10
 drop function bug11834_1;
 execute stmt;
-ERROR 42000: FUNCTION test.bug11834_1 does not exist
+ERROR 42000: FUNCTION test.bug11834_2 does not exist
 deallocate prepare stmt;
 drop function bug11834_2;
 DROP FUNCTION IF EXISTS bug12953|
diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result
index d2a958e8f0c420f99f4b3070f57269314422ac1e..a15f5013ef60ec6e8eb2b4a6d64a0bc598316448 100644
--- a/mysql-test/r/sp_notembedded.result
+++ b/mysql-test/r/sp_notembedded.result
@@ -25,17 +25,6 @@ Id	User	Host	db	Command	Time	State	Info
 #	event_scheduler	localhost	NULL	Connect	#	Suspended	NULL
 #	root	localhost	test	Query	#	NULL	show processlist
 drop procedure bug4902_2|
-drop function if exists bug5278|
-create function bug5278 () returns char
-begin
-SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
-return 'okay';
-end|
-select bug5278()|
-ERROR 42000: Can't find any matching row in the user table
-select bug5278()|
-ERROR 42000: Can't find any matching row in the user table
-drop function bug5278|
 drop table if exists t1|
 create table t1 (
 id   char(16) not null default '',
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index 24b0d4674c5fb53f5bcc61a1b3346bd84c9eeee5..d370cb3037c55e8e94c7698640e8dd4e21369203 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -1075,6 +1075,10 @@ execute stmt;
 drop function bug11834_1;
 # Attempt to execute statement should return proper error and 
 # should not crash server.
+
+# NOTE! The error we get from the below query indicates that the sp bug11834_2
+# does not exist(this is wrong but can be accepted)
+# This behaviour has been reported as bug#21294
 --error ER_SP_DOES_NOT_EXIST
 execute stmt;
 deallocate prepare stmt;
diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test
index b087f699f86112974c7d47e70aa79c4c815e3594..28abf448089a46e581e17048553626a32f565107 100644
--- a/mysql-test/t/sp_notembedded.test
+++ b/mysql-test/t/sp_notembedded.test
@@ -46,6 +46,8 @@ call bug4902_2()|
 drop procedure bug4902_2|
 
 
+# Disable until bug#17244 is fixed
+--disable_parsing
 #
 # BUG#5278: Stored procedure packets out of order if SET PASSWORD.
 #
@@ -63,7 +65,7 @@ select bug5278()|
 --error 1133
 select bug5278()|
 drop function bug5278|
-
+--enable_parsing
 
 --disable_warnings
 drop table if exists t1|
diff --git a/sql/sp.cc b/sql/sp.cc
index 4c8cc6156b74c6cbf10d42648ee318822726ee60..e794a46140221b9f31dbececeb641377da4392fb 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1537,7 +1537,6 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src,
       first_no_prelock - If true, don't add tables or cache routines used by
                          the body of the first routine (i.e. *start)
                          will be executed in non-prelocked mode.
-      tabs_changed     - Set to TRUE some tables were added, FALSE otherwise
   NOTE
     If some function is missing this won't be reported here.
     Instead this fact will be discovered during query execution.
@@ -1550,10 +1549,9 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src,
 static int
 sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
                                      Sroutine_hash_entry *start, 
-                                     bool first_no_prelock, bool *tabs_changed)
+                                     bool first_no_prelock)
 {
   int ret= 0;
-  bool tabschnd= 0;             /* Set if tables changed */
   bool first= TRUE;
   DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
 
@@ -1626,16 +1624,13 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
       {
         sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines,
                                      rt->belong_to_view);
-        tabschnd|=
-          sp->add_used_tables_to_table_list(thd, &lex->query_tables_last,
-                                            rt->belong_to_view);
+        (void)sp->add_used_tables_to_table_list(thd, &lex->query_tables_last,
+                                                rt->belong_to_view);
       }
       sp->propagate_attributes(lex);
     }
     first= FALSE;
   }
-  if (tabs_changed)             /* it can be NULL  */
-    *tabs_changed= tabschnd;
   DBUG_RETURN(ret);
 }
 
@@ -1651,20 +1646,18 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
       lex              - LEX representing statement
       first_no_prelock - If true, don't add tables or cache routines used by
                          the body of the first routine (i.e. *start)
-      tabs_changed     - Set to TRUE some tables were added, FALSE otherwise
-                         
+
   RETURN VALUE
      0     - success
      non-0 - failure
 */
 
 int
-sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock,
-                                 bool *tabs_changed)
+sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
 {
   return sp_cache_routines_and_add_tables_aux(thd, lex,
            (Sroutine_hash_entry *)lex->sroutines_list.first,
-           first_no_prelock, tabs_changed);
+           first_no_prelock);
 }
 
 
@@ -1691,9 +1684,8 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, TABLE_LIST *view)
                           (Sroutine_hash_entry **)lex->sroutines_list.next;
   sp_update_stmt_used_routines(thd, lex, &view->view->sroutines_list,
                                view->top_table());
-  return sp_cache_routines_and_add_tables_aux(thd, lex, 
-                                              *last_cached_routine_ptr, FALSE,
-                                              NULL);
+  return sp_cache_routines_and_add_tables_aux(thd, lex,
+                                              *last_cached_routine_ptr, FALSE);
 }
 
 
@@ -1742,8 +1734,7 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
       }
     }
     ret= sp_cache_routines_and_add_tables_aux(thd, lex,
-                                              *last_cached_routine_ptr, 
-                                              FALSE, NULL);
+                                              *last_cached_routine_ptr, FALSE);
   }
   return ret;
 }
diff --git a/sql/sp.h b/sql/sp.h
index 631b8a87aa238c75a972848ab6bc7fd64c857f60..80430791a5ae5c0bc511c3c00625022c49bb92ae 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -88,8 +88,7 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
 void sp_remove_not_own_routines(LEX *lex);
 void sp_update_sp_used_routines(HASH *dst, HASH *src);
 int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
-                                     bool first_no_prelock,
-                                     bool *tabs_changed);
+                                     bool first_no_prelock);
 int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
                                               TABLE_LIST *view);
 int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 28393e4b96468e6db934ae5fae7825bbb2e673d8..db11a3442c26ca41d160828bffa018e9aa481712 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2855,25 +2855,18 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
     statement for which table list for prelocking is already built, let
     us cache routines and try to build such table list.
 
-    NOTE: We will mark statement as requiring prelocking only if we will
-    have non empty table list. But this does not guarantee that in prelocked
-    mode we will have some locked tables, because queries which use only
-    derived/information schema tables and views possible. Thus "counter"
-    may be still zero for prelocked statement...
   */
 
   if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
       thd->lex->sroutines_list.elements)
   {
-    bool first_no_prelocking, need_prelocking, tabs_changed;
+    bool first_no_prelocking, need_prelocking;
     TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
 
     DBUG_ASSERT(thd->lex->query_tables == *start);
     sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
 
-    if (sp_cache_routines_and_add_tables(thd, thd->lex,
-                                         first_no_prelocking,
-                                         &tabs_changed))
+    if (sp_cache_routines_and_add_tables(thd, thd->lex, first_no_prelocking))
     {
       /*
         Serious error during reading stored routines from mysql.proc table.
@@ -2883,7 +2876,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
       result= -1;
       goto err;
     }
-    else if ((tabs_changed || *start) && need_prelocking)
+    else if (need_prelocking)
     {
       query_tables_last_own= save_query_tables_last;
       *start= thd->lex->query_tables;
@@ -3310,11 +3303,6 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
     in prelocked mode.
   */
   DBUG_ASSERT(!thd->prelocked_mode || !thd->lex->requires_prelocking());
-  /*
-    If statement requires prelocking then it has non-empty table list.
-    So it is safe to shortcut.
-  */
-  DBUG_ASSERT(!thd->lex->requires_prelocking() || tables);
 
   *need_reopen= FALSE;
 
@@ -3326,7 +3314,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
     thd->set_current_stmt_binlog_row_based_if_mixed();
 #endif /*HAVE_ROW_BASED_REPLICATION*/
 
-  if (!tables)
+  if (!tables && !thd->lex->requires_prelocking())
     DBUG_RETURN(0);
 
   /*