diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 0c6b4034e9199996da35b9c2c9d7c78fc2eb1d1c..412f6b94fa2ca832236a71fc5409ebfda7a110ee 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -6860,4 +6860,55 @@ DROP FUNCTION f2;
 DROP VIEW v1;
 DROP VIEW v2;
 
+#
+# - Bug#24923: prepare.
+#
+
+DROP FUNCTION IF EXISTS f1;
+
+#
+# - Bug#24923: create required objects.
+#
+
+CREATE FUNCTION f1(p INT)
+RETURNS ENUM ('Very_long_enum_element_identifier',
+'Another_very_long_enum_element_identifier')
+BEGIN
+CASE p
+WHEN 1 THEN
+RETURN 'Very_long_enum_element_identifier';
+ELSE
+RETURN 'Another_very_long_enum_element_identifier';
+END CASE;
+END|
+
+#
+# - Bug#24923: check.
+#
+
+SELECT f1(1);
+f1(1)
+Very_long_enum_element_identifier
+
+SELECT f1(2);
+f1(2)
+Another_very_long_enum_element_identifier
+
+SHOW CREATE FUNCTION f1;
+Function	sql_mode	Create Function	character_set_client	collation_connection	Database Collation
+f1		CREATE DEFINER=`root`@`localhost` FUNCTION `f1`(p INT) RETURNS enum('Very_long_enum_element_identifier','Another_very_long_enum_element_identifier') CHARSET latin1
+BEGIN
+CASE p
+WHEN 1 THEN
+RETURN 'Very_long_enum_element_identifier';
+ELSE
+RETURN 'Another_very_long_enum_element_identifier';
+END CASE;
+END	latin1	latin1_swedish_ci	latin1_swedish_ci
+#
+# - Bug#24923: cleanup.
+#
+
+DROP FUNCTION f1;
+
 End of 5.1 tests
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 7d0a6a7b2d8ead46d0d0e606835e931c00881ff7..004e1c4ddd23fe2c57dfd9a568ed9bc07741e8e9 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -7986,4 +7986,74 @@ DROP VIEW v2;
 
 ###########################################################################
 
+#
+# Bug#24923: Functions with ENUM issues.
+#
+
+###########################################################################
+
+--echo #
+--echo # - Bug#24923: prepare.
+--echo #
+
+--echo
+
+--disable_warnings
+DROP FUNCTION IF EXISTS f1;
+--enable_warnings
+
+--echo
+
+--echo #
+--echo # - Bug#24923: create required objects.
+--echo #
+
+--echo
+
+delimiter |;
+
+CREATE FUNCTION f1(p INT)
+  RETURNS ENUM ('Very_long_enum_element_identifier',
+                'Another_very_long_enum_element_identifier')
+  BEGIN
+    CASE p
+    WHEN 1 THEN
+      RETURN 'Very_long_enum_element_identifier';
+    ELSE
+      RETURN 'Another_very_long_enum_element_identifier';
+    END CASE;
+  END|
+
+delimiter ;|
+
+--echo
+
+--echo #
+--echo # - Bug#24923: check.
+--echo #
+
+--echo
+
+SELECT f1(1);
+
+--echo
+
+SELECT f1(2);
+
+--echo
+
+SHOW CREATE FUNCTION f1;
+
+--echo #
+--echo # - Bug#24923: cleanup.
+--echo #
+
+--echo
+
+DROP FUNCTION f1;
+
+--echo
+
+###########################################################################
+
 --echo End of 5.1 tests
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index f7b23e4e7ae2c2b73ac0e2c00371972ef5dc9607..927cbe81ff94b7445a4b63833cfef9cf95d97ecc 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -60,7 +60,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type (   Time_zone_id int unsign
 CREATE TABLE IF NOT EXISTS time_zone_leap_second (   Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8   comment='Leap seconds information for time zones';
 
 
-CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns char(64) DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
+CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
 
 CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin   comment='Procedure privileges';
 
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index 78e6a0ceb5782c167de2c00d1b7f074b4ba0c1f2..a43964bf09a3d8fa291c48f62f83a29d6f52135c 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -344,6 +344,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
                              'MODIFIES_SQL_DATA'
                             ) DEFAULT 'CONTAINS_SQL' NOT NULL,
                  MODIFY body longblob NOT NULL,
+                 MODIFY returns longblob NOT NULL,
                  MODIFY sql_mode
                         set('REAL_AS_FLOAT',
                             'PIPES_AS_CONCAT',
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 30cf85f3181271dfb0cd5d0ce54e1de5e63fb0ca..8fad09eb22119bdd60b1c91de1bc928827d8a55e 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -6109,3 +6109,6 @@ ER_EVENT_INVALID_CREATION_CTX
 
 ER_TRG_CANT_OPEN_TABLE
   eng "Cannot open table for trigger `%-.64s`.`%-.64s`"
+
+ER_CANT_CREATE_SROUTINE
+  eng "Cannot create stored routine `%-.64s`. Check warnings"
diff --git a/sql/sp.cc b/sql/sp.cc
index 9077862e2f67936e3894b3c3a67df8b8d07bde9e..1b5d8ca87b8627633393e46760541d6348b01928 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -682,6 +682,10 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
 
   CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
 
+  enum_check_fields saved_count_cuted_fields;
+
+  bool store_failed= FALSE;
+
   DBUG_ENTER("sp_create_routine");
   DBUG_PRINT("enter", ("type: %d  name: %.*s",type, (int) sp->m_name.length,
                        sp->m_name.str));
@@ -696,6 +700,9 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
   */
   thd->clear_current_stmt_binlog_row_based();
 
+  saved_count_cuted_fields= thd->count_cuted_fields;
+  thd->count_cuted_fields= CHECK_FIELD_WARN;
+
   if (!(table= open_proc_table_for_update(thd)))
     ret= SP_OPEN_TABLE_FAILED;
   else
@@ -725,43 +732,77 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
       ret= SP_BODY_TOO_LONG;
       goto done;
     }
-    table->field[MYSQL_PROC_FIELD_DB]->
-      store(sp->m_db.str, sp->m_db.length, system_charset_info);
-    table->field[MYSQL_PROC_FIELD_NAME]->
-      store(sp->m_name.str, sp->m_name.length, system_charset_info);
-    table->field[MYSQL_PROC_MYSQL_TYPE]->
-      store((longlong)type, TRUE);
-    table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
-      store(sp->m_name.str, sp->m_name.length, system_charset_info);
+
+    store_failed=
+      table->field[MYSQL_PROC_FIELD_DB]->
+        store(sp->m_db.str, sp->m_db.length, system_charset_info);
+
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_NAME]->
+        store(sp->m_name.str, sp->m_name.length, system_charset_info);
+
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_MYSQL_TYPE]->
+        store((longlong)type, TRUE);
+
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
+        store(sp->m_name.str, sp->m_name.length, system_charset_info);
+
     if (sp->m_chistics->daccess != SP_DEFAULT_ACCESS)
-      table->field[MYSQL_PROC_FIELD_ACCESS]->
-	store((longlong)sp->m_chistics->daccess, TRUE);
-    table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->
-      store((longlong)(sp->m_chistics->detistic ? 1 : 2), TRUE);
+    {
+      store_failed= store_failed ||
+        table->field[MYSQL_PROC_FIELD_ACCESS]->
+          store((longlong)sp->m_chistics->daccess, TRUE);
+    }
+
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_DETERMINISTIC]->
+        store((longlong)(sp->m_chistics->detistic ? 1 : 2), TRUE);
+
     if (sp->m_chistics->suid != SP_IS_DEFAULT_SUID)
-      table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
-	store((longlong)sp->m_chistics->suid, TRUE);
-    table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
-      store(sp->m_params.str, sp->m_params.length, system_charset_info);
+    {
+      store_failed= store_failed ||
+        table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
+          store((longlong)sp->m_chistics->suid, TRUE);
+    }
+
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
+        store(sp->m_params.str, sp->m_params.length, system_charset_info);
+
     if (sp->m_type == TYPE_ENUM_FUNCTION)
     {
       String retstr(64);
       sp_returns_type(thd, retstr, sp);
-      table->field[MYSQL_PROC_FIELD_RETURNS]->
-	store(retstr.ptr(), retstr.length(), system_charset_info);
+
+      store_failed= store_failed ||
+        table->field[MYSQL_PROC_FIELD_RETURNS]->
+          store(retstr.ptr(), retstr.length(), system_charset_info);
     }
-    table->field[MYSQL_PROC_FIELD_BODY]->
-      store(sp->m_body.str, sp->m_body.length, system_charset_info);
-    table->field[MYSQL_PROC_FIELD_DEFINER]->
-      store(definer, (uint)strlen(definer), system_charset_info);
+
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_BODY]->
+        store(sp->m_body.str, sp->m_body.length, system_charset_info);
+
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_DEFINER]->
+        store(definer, (uint)strlen(definer), system_charset_info);
+
     ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
     ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
-    table->field[MYSQL_PROC_FIELD_SQL_MODE]->
-      store((longlong)thd->variables.sql_mode, TRUE);
+
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_SQL_MODE]->
+        store((longlong)thd->variables.sql_mode, TRUE);
+
     if (sp->m_chistics->comment.str)
-      table->field[MYSQL_PROC_FIELD_COMMENT]->
-	store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
-	      system_charset_info);
+    {
+      store_failed= store_failed ||
+        table->field[MYSQL_PROC_FIELD_COMMENT]->
+          store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
+                system_charset_info);
+    }
 
     if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
         !trust_function_creators && mysql_bin_log.is_open())
@@ -794,24 +835,34 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
     }
 
     table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->set_notnull();
-    table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store(
-      thd->charset()->csname,
-      strlen(thd->charset()->csname),
-      system_charset_info);
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store(
+        thd->charset()->csname,
+        strlen(thd->charset()->csname),
+        system_charset_info);
 
     table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->set_notnull();
-    table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store(
-      thd->variables.collation_connection->name,
-      strlen(thd->variables.collation_connection->name),
-      system_charset_info);
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store(
+        thd->variables.collation_connection->name,
+        strlen(thd->variables.collation_connection->name),
+        system_charset_info);
 
     table->field[MYSQL_PROC_FIELD_DB_COLLATION]->set_notnull();
-    table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store(
-      db_cs->name, strlen(db_cs->name), system_charset_info);
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store(
+        db_cs->name, strlen(db_cs->name), system_charset_info);
 
     table->field[MYSQL_PROC_FIELD_BODY_UTF8]->set_notnull();
-    table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store(
-      sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info);
+    store_failed= store_failed ||
+      table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store(
+        sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info);
+
+    if (store_failed)
+    {
+      ret= SP_FLD_STORE_FAILED;
+      goto done;
+    }
 
     ret= SP_OK;
     if (table->file->ha_write_row(table->record[0]))
@@ -842,6 +893,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
   }
 
 done:
+  thd->count_cuted_fields= saved_count_cuted_fields;
+
   close_thread_tables(thd);
   DBUG_RETURN(ret);
 }
diff --git a/sql/sp.h b/sql/sp.h
index 3797eb289a462a73392cf8cd9646c0b456407ec0..31173e1f90c8e99a85f1d7b934f4f5970b67cbd4 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -29,6 +29,7 @@
 #define SP_NO_DB_ERROR       -8
 #define SP_BAD_IDENTIFIER    -9
 #define SP_BODY_TOO_LONG    -10
+#define SP_FLD_STORE_FAILED -11
 
 /* Drop all routines in database 'db' */
 int
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index b04822c4fc9e772452629ffae257886a936acfae..4856332631ad192b5cf8bc845ad0871a681c48a1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3812,6 +3812,9 @@ mysql_execute_command(THD *thd)
     case SP_BODY_TOO_LONG:
       my_error(ER_TOO_LONG_BODY, MYF(0), name);
     break;
+    case SP_FLD_STORE_FAILED:
+      my_error(ER_CANT_CREATE_SROUTINE, MYF(0), name);
+      break;
     default:
       my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
     break;