diff --git a/sql/sp.cc b/sql/sp.cc
index af86737..7851bb3 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -908,6 +908,38 @@ Bad_db_error_handler::handle_condition(THD *thd,
 }
 
 
+int Sp_handler::set_routine_defstr(THD *thd, sp_head *sp) const
+{
+  if (sp->m_defstr.length > 0)
+    return SP_OK;
+
+  LEX_CSTRING returns;
+  String retstr(64);
+  String defstr;
+  defstr.set_charset(sp->get_creation_ctx()->get_client_cs());
+  retstr.set_charset(system_charset_info);
+  returns.length= 0;
+  if (type() == TYPE_ENUM_FUNCTION)
+  {
+    sp_returns_type(thd, retstr, sp);
+    returns= retstr.lex_cstring();
+  }
+  if (show_create_sp(thd, &defstr,
+                     sp->m_explicit_name ? sp->m_db : null_clex_str,
+                     sp->m_name,
+                     sp->m_params, returns, sp->m_body,
+                     sp->chistics(), sp->m_definer, DDL_options(),
+                     sp->m_sql_mode))
+  {
+    return SP_INTERNAL_ERROR;
+  }
+  sp->m_defstr.length= defstr.length();
+  sp->m_defstr.str= strmake_root(sp->get_main_mem_root(), defstr.c_ptr_safe(),
+                                 defstr.length());
+  trim_whitespace(thd->charset(), &sp->m_defstr);
+  return SP_OK;
+}
+
 int
 Sp_handler::db_load_routine(THD *thd, const Database_qualified_name *name,
                             sp_head **sphp,
@@ -1911,7 +1943,8 @@ Sp_handler::sp_show_create_routine(THD *thd,
   if (sp_cache_routine(thd, name, false, &sp))
     DBUG_RETURN(TRUE);
 
-  if (sp == NULL || sp->show_create_routine(thd, this))
+  if (sp == NULL || set_routine_defstr(thd, sp) ||
+      sp->show_create_routine(thd, this))
   {
     /*
       If we have insufficient privileges, pretend the routine
diff --git a/sql/sp.h b/sql/sp.h
index 380dd69..3f88e57 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -91,6 +91,7 @@ class Sp_handler
                       longlong created, longlong modified,
                       sp_package *parent,
                       Stored_program_creation_ctx *creation_ctx) const;
+  int set_routine_defstr(THD *thd, sp_head *sphp) const;
   int sp_drop_routine_internal(THD *thd,
                                const Database_qualified_name *name,
                                TABLE *table) const;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index c1c938d..7869611 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -796,17 +796,11 @@ sp_head::set_stmt_end(THD *thd)
   lip->body_utf8_append(end_ptr);
 
   m_body_utf8.length= lip->get_body_utf8_length();
-  m_body_utf8.str= thd->strmake(lip->get_body_utf8_str(), m_body_utf8.length);
+  m_body_utf8.str= strmake_root(m_thd_root, lip->get_body_utf8_str(), m_body_utf8.length);
   trim_whitespace(thd->charset(), &m_body_utf8);
 
-  /*
-    Make the string of whole stored-program-definition query (in the
-    original character set).
-  */
 
-  m_defstr.length= end_ptr - lip->get_cpp_buf();
-  m_defstr.str= thd->strmake(lip->get_cpp_buf(), m_defstr.length);
-  trim_whitespace(thd->charset(), &m_defstr);
+  m_defstr.length=0;
 }
 
 
