diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 61e931e146c65a009d4b5194a3902eaa124a1ad9..1a061529fb0877b2afc51219500a652f3c5617e9 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -758,3 +758,10 @@ execute stmt;
 ERROR 42000: FUNCTION test.bug11834_1 does not exist
 deallocate prepare stmt;
 drop function bug11834_2;
+DROP FUNCTION IF EXISTS bug12953|
+CREATE FUNCTION bug12953() RETURNS INT
+BEGIN
+OPTIMIZE TABLE t1;
+RETURN 1;
+END|
+ERROR 0A000: OPTIMIZE TABLE is not allowed in stored procedures
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index e289748ba2fbccd253c208610d9e6a8d05dc1c7f..abb927ab3b8b9dc22af52f84a715fa0cfc09f20f 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -1085,6 +1085,21 @@ drop function bug11834_1;
 execute stmt;
 deallocate prepare stmt;
 drop function bug11834_2;
+
+#
+# Bug#12953 "Stored procedures: crash if OPTIMIZE TABLE in function"
+#
+delimiter |;
+--disable_warnings
+DROP FUNCTION IF EXISTS bug12953|
+--enable_warnings
+--error ER_SP_BADSTATEMENT
+CREATE FUNCTION bug12953() RETURNS INT
+BEGIN
+  OPTIMIZE TABLE t1;
+  RETURN 1;
+END|
+
 #
 # BUG#NNNN: New bug synopsis
 #
@@ -1092,5 +1107,3 @@ drop function bug11834_2;
 #drop procedure if exists bugNNNN|
 #--enable_warnings
 #create procedure bugNNNN...
-
-
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c9b41cb495b5c6df2e83ebf548a7ce6c2e204bdc..cc286e4ff45852c81da3fd7a9d1bb096c55c149c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -3826,6 +3826,11 @@ optimize:
 	OPTIMIZE opt_no_write_to_binlog table_or_tables
 	{
 	   LEX *lex=Lex;
+	   if (lex->sphead)
+	   {
+	     my_error(ER_SP_BADSTATEMENT, MYF(0), "OPTIMIZE TABLE");
+	     YYABORT;
+	   }
 	   lex->sql_command = SQLCOM_OPTIMIZE;
            lex->no_write_to_binlog= $2;
 	   lex->check_opt.init();