diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor-decl.result b/mysql-test/suite/compat/oracle/r/sp-cursor-decl.result
new file mode 100644
index 0000000..1e185f7
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/sp-cursor-decl.result
@@ -0,0 +1,265 @@
+SET sql_mode=ORACLE;
+#
+# MDEV-10598 sql_mode=ORACLE: Variable declarations can go after cursor declarations
+#
+#
+# Variable after cursor declaration
+#
+CREATE OR REPLACE TABLE t1 (a INT);
+insert into t1 values (1);
+insert into t1 values (2);
+CREATE or replace PROCEDURE p1
+AS
+CURSOR c IS SELECT a FROM t1;
+var1 varchar(10);
+BEGIN
+OPEN c;
+fetch c into var1;
+SELECT c%ROWCOUNT,var1;
+close c;
+END;
+$$
+CALL p1;
+c%ROWCOUNT	var1
+1	1
+DROP PROCEDURE p1;
+drop table t1;
+#
+# Variable after condition declaration
+#
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+CREATE or replace PROCEDURE p1
+AS
+dup_key CONDITION FOR SQLSTATE '23000';
+var1 varchar(40);
+CONTINUE HANDLER FOR dup_key
+BEGIN
+var1:='duplicate key in index';
+END;
+BEGIN
+var1:='';
+insert into t1 values (1);
+select var1;
+END;
+$$
+CALL p1;
+var1
+duplicate key in index
+DROP PROCEDURE p1;
+drop table t1;
+#
+# Condition after cursor declaration
+#
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+CREATE or replace PROCEDURE p1
+AS
+var1 varchar(40);
+var2 integer;
+CURSOR c IS SELECT col1 FROM t1;
+dup_key CONDITION FOR SQLSTATE '23000';
+CONTINUE HANDLER FOR dup_key
+BEGIN
+var1:='duplicate key in index';
+END;
+BEGIN
+var1:='';
+insert into t1 values (1);
+SELECT var1;
+END;
+$$
+CALL p1;
+var1
+duplicate key in index
+DROP PROCEDURE p1;
+drop table t1;
+#
+# Cursor after handler declaration
+#
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+CREATE or replace PROCEDURE p1
+AS
+var1 varchar(40);
+var2 integer;
+dup_key CONDITION FOR SQLSTATE '23000';
+CONTINUE HANDLER FOR dup_key
+BEGIN
+var1:='duplicate key in index';
+END;
+CURSOR c IS SELECT col1 FROM t1;
+BEGIN
+var1:='';
+insert into t1 values (1);
+SELECT var1;
+END;
+$$
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CURSOR c IS SELECT col1 FROM t1;
+BEGIN
+var1:='';
+insert into t1 values (1);
+SELE' at line 6
+drop table t1;
+#
+# Condition after handler declaration
+#
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+CREATE or replace PROCEDURE p1
+AS
+var1 varchar(40);
+var2 integer;
+dup_key CONDITION FOR SQLSTATE '23000';
+CURSOR c IS SELECT col1 FROM t1;
+CONTINUE HANDLER FOR dup_key
+BEGIN
+var1:='duplicate key in index';
+END;
+divide_by_zero CONDITION FOR SQLSTATE '22012';
+BEGIN
+var1:='';
+insert into t1 values (1);
+SELECT var1;
+END;
+$$
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'divide_by_zero CONDITION FOR SQLSTATE '22012';
+BEGIN
+var1:='';
+insert into t1 va' at line 7
+drop table t1;
+#
+# Variable after handler declaration
+#
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+CREATE or replace PROCEDURE p1
+AS
+var1 varchar(40);
+var2 integer;
+dup_key CONDITION FOR SQLSTATE '23000';
+CURSOR c IS SELECT col1 FROM t1;
+CONTINUE HANDLER FOR dup_key
+BEGIN
+var1:='duplicate key in index';
+END;
+divide_by_zero CONDITION FOR SQLSTATE '22012';
+BEGIN
+var1:='';
+insert into t1 values (1);
+SELECT var1;
+END;
+$$
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'divide_by_zero CONDITION FOR SQLSTATE '22012';
+BEGIN
+var1:='';
+insert into t1 va' at line 7
+drop table t1;
+#
+# Variable after cursor (inner block)
+#
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+insert into t1 values (2);
+create unique index t1_col1 on t1 (col1);
+CREATE or replace PROCEDURE p1
+AS
+CURSOR c IS SELECT col1 FROM t1;
+var1 varchar(40);
+BEGIN
+OPEN c;
+begin
+declare
+CURSOR c IS SELECT col1 FROM t1 where col1=2;
+var2 integer;
+dup_key CONDITION FOR SQLSTATE '23000';
+CONTINUE HANDLER FOR dup_key
+BEGIN
+var1:='duplicate key in index';
+END;
+begin
+OPEN c;
+fetch c into var1;
+SELECT 'inner cursor',var1;
+insert into t1 values (2);
+close c;
+end;
+end;
+SELECT var1;
+fetch c into var1;
+SELECT c%ROWCOUNT,var1;
+begin
+insert into t1 values (2);
+exception when 1062 then
+begin
+SELECT 'dup key caugth';
+end;
+end;
+close c;
+END;
+$$
+CALL p1;
+inner cursor	var1
+inner cursor	2
+var1
+duplicate key in index
+c%ROWCOUNT	var1
+1	1
+dup key caugth
+dup key caugth
+DROP PROCEDURE p1;
+drop table t1;
+#
+# Cursor declaration and row type declaration in same block
+#
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+insert into t1 values(1,'a');
+CREATE or replace PROCEDURE p1()
+AS
+CURSOR cur1 IS SELECT a FROM t1;
+rec1 cur1%ROWTYPE;
+BEGIN
+rec1.a:= 10;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos	Instruction
+0	cursor_copy_struct cur1 rec1@0
+1	set rec1@0 NULL
+2	cpush cur1@0
+3	set rec1.a@0["a"] 10
+4	cpop 1
+currentlty generate error ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
+call p1;
+DROP PROCEDURE p1;
+drop table t1;
+CREATE or replace PROCEDURE p1
+AS
+a INT:=10;
+CURSOR cur1 IS SELECT a;
+rec1 cur1%ROWTYPE;
+CURSOR cur2 IS SELECT rec1.a + 1  "a";
+rec2 cur2%ROWTYPE;
+BEGIN
+OPEN cur1;
+FETCH cur1 INTO rec1;
+CLOSE cur1;
+SELECT rec1.a;
+open cur2;
+FETCH cur2 INTO rec2;
+CLOSE cur2;
+SELECT rec2.a;
+END;
+$$
+currentlty generate error ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
+CALL p1();
+rec1.a
+10
+rec2.a
+11
+DROP PROCEDURE p1;
diff --git a/mysql-test/suite/compat/oracle/t/sp-cursor-decl.test b/mysql-test/suite/compat/oracle/t/sp-cursor-decl.test
new file mode 100644
index 0000000..0afbd66
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/sp-cursor-decl.test
@@ -0,0 +1,269 @@
+SET sql_mode=ORACLE;
+
+--echo #
+--echo # MDEV-10598 sql_mode=ORACLE: Variable declarations can go after cursor declarations
+--echo #
+
+--echo #
+--echo # Variable after cursor declaration
+--echo #
+
+CREATE OR REPLACE TABLE t1 (a INT);
+insert into t1 values (1);
+insert into t1 values (2);
+DELIMITER $$;
+CREATE or replace PROCEDURE p1
+AS
+  CURSOR c IS SELECT a FROM t1;
+  var1 varchar(10);
+BEGIN
+  OPEN c;
+  fetch c into var1;
+  SELECT c%ROWCOUNT,var1;
+  close c;
+END;
+$$
+DELIMITER ;$$
+CALL p1;
+DROP PROCEDURE p1;
+drop table t1;
+
+--echo #
+--echo # Variable after condition declaration
+--echo #
+
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+DELIMITER $$;
+CREATE or replace PROCEDURE p1
+AS
+  dup_key CONDITION FOR SQLSTATE '23000';
+  var1 varchar(40);
+  CONTINUE HANDLER FOR dup_key
+  BEGIN
+    var1:='duplicate key in index';
+  END;
+BEGIN
+  var1:='';
+  insert into t1 values (1);
+  select var1;
+END;
+$$
+DELIMITER ;$$
+CALL p1;
+DROP PROCEDURE p1;
+drop table t1;
+
+--echo #
+--echo # Condition after cursor declaration
+--echo #
+
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+DELIMITER $$;
+CREATE or replace PROCEDURE p1
+AS
+  var1 varchar(40);
+  var2 integer;
+  CURSOR c IS SELECT col1 FROM t1;
+  dup_key CONDITION FOR SQLSTATE '23000';
+  CONTINUE HANDLER FOR dup_key
+  BEGIN
+    var1:='duplicate key in index';
+  END;
+BEGIN
+  var1:='';
+  insert into t1 values (1);
+  SELECT var1;
+END;
+$$
+DELIMITER ;$$
+CALL p1;
+DROP PROCEDURE p1;
+drop table t1;
+
+--echo #
+--echo # Cursor after handler declaration
+--echo #
+
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+DELIMITER $$;
+--error ER_PARSE_ERROR
+CREATE or replace PROCEDURE p1
+AS
+  var1 varchar(40);
+  var2 integer;
+  dup_key CONDITION FOR SQLSTATE '23000';
+  CONTINUE HANDLER FOR dup_key
+  BEGIN
+    var1:='duplicate key in index';
+  END;
+  CURSOR c IS SELECT col1 FROM t1;
+BEGIN
+  var1:='';
+  insert into t1 values (1);
+  SELECT var1;
+END;
+$$
+DELIMITER ;$$
+drop table t1;
+
+--echo #
+--echo # Condition after handler declaration
+--echo #
+
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+DELIMITER $$;
+--error ER_PARSE_ERROR
+CREATE or replace PROCEDURE p1
+AS
+  var1 varchar(40);
+  var2 integer;
+  dup_key CONDITION FOR SQLSTATE '23000';
+  CURSOR c IS SELECT col1 FROM t1;
+  CONTINUE HANDLER FOR dup_key
+  BEGIN
+    var1:='duplicate key in index';
+  END;
+  divide_by_zero CONDITION FOR SQLSTATE '22012';
+BEGIN
+  var1:='';
+  insert into t1 values (1);
+  SELECT var1;
+END;
+$$
+DELIMITER ;$$
+drop table t1;
+
+--echo #
+--echo # Variable after handler declaration
+--echo #
+
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+create unique index t1_col1 on t1 (col1);
+DELIMITER $$;
+--error ER_PARSE_ERROR
+CREATE or replace PROCEDURE p1
+AS
+  var1 varchar(40);
+  var2 integer;
+  dup_key CONDITION FOR SQLSTATE '23000';
+  CURSOR c IS SELECT col1 FROM t1;
+  CONTINUE HANDLER FOR dup_key
+  BEGIN
+    var1:='duplicate key in index';
+  END;
+  divide_by_zero CONDITION FOR SQLSTATE '22012';
+BEGIN
+  var1:='';
+  insert into t1 values (1);
+  SELECT var1;
+END;
+$$
+DELIMITER ;$$
+drop table t1;
+
+--echo #
+--echo # Variable after cursor (inner block)
+--echo #
+
+CREATE OR REPLACE TABLE t1 (col1 INT);
+insert into t1 values (1);
+insert into t1 values (2);
+create unique index t1_col1 on t1 (col1);
+DELIMITER $$;
+CREATE or replace PROCEDURE p1
+AS
+  CURSOR c IS SELECT col1 FROM t1;
+  var1 varchar(40);
+BEGIN
+  OPEN c;
+  begin
+    declare
+      CURSOR c IS SELECT col1 FROM t1 where col1=2;
+      var2 integer;
+      dup_key CONDITION FOR SQLSTATE '23000';
+      CONTINUE HANDLER FOR dup_key
+      BEGIN
+        var1:='duplicate key in index';
+      END;
+    begin
+      OPEN c;
+      fetch c into var1;
+      SELECT 'inner cursor',var1;
+      insert into t1 values (2);
+      close c;
+    end;
+  end;
+  SELECT var1;
+  fetch c into var1;
+  SELECT c%ROWCOUNT,var1;
+  begin
+    insert into t1 values (2);
+  exception when 1062 then
+    begin
+      SELECT 'dup key caugth';
+    end;
+  end;
+  close c;
+END;
+$$
+DELIMITER ;$$
+CALL p1;
+DROP PROCEDURE p1;
+drop table t1;
+
+--echo #
+--echo # Cursor declaration and row type declaration in same block
+--echo #
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+insert into t1 values(1,'a');
+delimiter $$;
+CREATE or replace PROCEDURE p1()
+AS
+CURSOR cur1 IS SELECT a FROM t1;
+rec1 cur1%ROWTYPE;
+BEGIN
+rec1.a:= 10;
+END;
+$$
+delimiter ;$$
+SHOW PROCEDURE CODE p1;
+--echo currentlty generate error ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
+--disable_warnings
+call p1;
+--enable_warnings
+DROP PROCEDURE p1;
+drop table t1;
+delimiter $$;
+CREATE or replace PROCEDURE p1
+AS
+  a INT:=10;
+  CURSOR cur1 IS SELECT a;
+  rec1 cur1%ROWTYPE;
+  CURSOR cur2 IS SELECT rec1.a + 1  "a";
+  rec2 cur2%ROWTYPE;
+BEGIN
+  OPEN cur1;
+  FETCH cur1 INTO rec1;
+  CLOSE cur1;
+  SELECT rec1.a;
+  open cur2;
+  FETCH cur2 INTO rec2;
+  CLOSE cur2;
+  SELECT rec2.a;
+END;
+$$
+DELIMITER ;$$
+--echo currentlty generate error ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
+--disable_warnings
+CALL p1();
+--enable_warnings
+DROP PROCEDURE p1;
\ No newline at end of file
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 745f982..453cf4c 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -595,6 +595,7 @@ sp_head::sp_head()
   m_backpatch.empty();
   m_backpatch_goto.empty();
   m_cont_backpatch.empty();
+  m_delayed_cpush.empty();
   m_lex.empty();
   my_hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0);
   my_hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key,
@@ -2459,6 +2460,49 @@ sp_head::do_cont_backpatch()
   }
 }
 
+
+bool
+sp_head::store_cursor_infos(THD *thd, sp_pcontext *spcont,
+                            const LEX_STRING name,
+                            sp_lex_cursor *cursor_stmt,
+                            sp_pcontext *param_ctx, uint ccount)
+{
+    ddc_t *ddc=(ddc_t *) thd->alloc(sizeof(ddc_t));
+    if (!ddc)
+      return true;
+
+    ddc->spcont= spcont;
+    ddc->param_ctx= param_ctx;
+    ddc->cursor_stmt= cursor_stmt;
+    ddc->current_cursor_count= ccount;
+    return m_delayed_cpush.push_back(ddc);
+}
+
+
+int
+sp_head::sp_push_cursors_declaration_instr(THD *thd)
+{
+  if (m_delayed_cpush.is_empty())
+    return 0;
+
+  List_iterator<ddc_t> li(m_delayed_cpush);
+  ddc_t *c;
+  sp_instr_cpush *i;
+  while ((c= li++))
+  {
+    i= new (thd->mem_root)
+         sp_instr_cpush(instructions(), c->spcont, c->cursor_stmt,
+                        c->current_cursor_count);
+    if (i == NULL || add_instr(i))
+    {
+      return 1;
+    }
+    li.remove();
+  }
+  return 0;
+}
+
+
 void
 sp_head::set_info(longlong created, longlong modified,
                   st_sp_chistics *chistics, sql_mode_t sql_mode)
diff --git a/sql/sp_head.h b/sql/sp_head.h
index ee11974..3337ce5 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -560,6 +560,13 @@ class sp_head :private Query_arena
   void
   do_cont_backpatch();
 
+  bool
+  store_cursor_infos(THD *thd, sp_pcontext *spcont, const LEX_STRING name,
+                     sp_lex_cursor *cursor_stmt, sp_pcontext *param_ctx,
+                     uint ccount);
+  int
+  sp_push_cursors_declaration_instr(THD *thd);
+
   char *name(uint *lenp = 0) const
   {
     if (lenp)
@@ -755,6 +762,19 @@ class sp_head :private Query_arena
   */
   HASH m_sptabs;
 
+  /**
+    We need a special list to add cursor declaration (cpush) after variables
+    and conditions declaration and before handler declaration
+  */
+  typedef struct
+  {
+    sp_pcontext *spcont;
+    sp_pcontext *param_ctx;
+    sp_lex_cursor *cursor_stmt;
+    uint current_cursor_count;
+  } ddc_t;
+  List<ddc_t> m_delayed_cpush;
+
   bool
   execute(THD *thd, bool merge_da_on_success);
 
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 27d0d4d..b01dd4a 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -5687,23 +5687,30 @@ bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop)
 
 bool LEX::sp_declare_cursor(THD *thd, const LEX_STRING name,
                             sp_lex_cursor *cursor_stmt,
-                            sp_pcontext *param_ctx)
+                            sp_pcontext *param_ctx, bool delay_instr)
 {
   uint offp;
   sp_instr_cpush *i;
-
   if (spcont->find_cursor(name, &offp, true))
   {
     my_error(ER_SP_DUP_CURS, MYF(0), name.str);
     return true;
   }
   cursor_stmt->set_cursor_name(name);
-  i= new (thd->mem_root)
-       sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt,
-                      spcont->current_cursor_count());
-  return i == NULL ||
-         sphead->add_instr(i) ||
-         spcont->add_cursor(name, param_ctx, cursor_stmt);
+  uint ccount=spcont->current_cursor_count();
+
+  if (spcont->add_cursor(name, param_ctx, cursor_stmt))
+    return true;
+
+  if (delay_instr)
+    return sphead->store_cursor_infos(thd, spcont, name, cursor_stmt,
+                                      param_ctx, ccount);
+  else
+  {
+    i= new (thd->mem_root)
+         sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt, ccount);
+    return i == NULL || sphead->add_instr(i);
+  }
 }
 
 
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index f18a0a4..44befd1 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3154,7 +3154,14 @@ struct LEX: public Query_tables_list
 
   bool sp_declare_cursor(THD *thd, const LEX_STRING name,
                          class sp_lex_cursor *cursor_stmt,
-                         sp_pcontext *param_ctx);
+                         sp_pcontext *param_ctx, bool delay_instr);
+  bool sp_declare_cursor(THD *thd, const LEX_STRING name,
+                         class sp_lex_cursor *cursor_stmt,
+                         sp_pcontext *param_ctx)
+  {
+    return sp_declare_cursor(thd, name, cursor_stmt, param_ctx, false);
+  }
+
   bool sp_open_cursor(THD *thd, const LEX_STRING name,
                       List<sp_assignment_lex> *parameters);
   Item_splocal *create_item_for_sp_var(LEX_STRING name, sp_variable *spvar,
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index f6fc323..32b7fcc 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -1334,7 +1334,9 @@ END_OF_INPUT
 
 %type <num>  sp_decl_idents sp_handler_type sp_hcond_list
 %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
-%type <spblock> sp_decl_body sp_decl_body_list opt_sp_decl_body_list
+%type <spblock> sp_decl_body_list opt_sp_decl_body_list
+%type <spblock> sp_decl_non_handler sp_decl_non_handler_list
+%type <spblock> sp_decl_handler sp_decl_handler_list opt_sp_decl_handler_list
 %type <spblock_handlers> sp_block_statements_and_exceptions
 %type <sp_instr_addr> sp_instr_addr
 %type <sp_cursor_name_and_offset> sp_cursor_name_and_offset
@@ -2572,12 +2574,37 @@ opt_sp_decl_body_list:
         ;
 
 sp_decl_body_list:
-          sp_decl_body ';' { $$= $1; }
-        | sp_decl_body_list sp_decl_body ';'
+          sp_decl_non_handler_list
           {
-            if (Lex->sp_declarations_join(&$$, $1, $2))
+            if (Lex->sphead->sp_push_cursors_declaration_instr(thd))
               MYSQL_YYABORT;
           }
+          opt_sp_decl_handler_list
+          {
+            $$.join($1, $3);
+          }
+        | sp_decl_handler_list
+        ;
+
+sp_decl_non_handler_list:
+          sp_decl_non_handler ';' { $$= $1; }
+        | sp_decl_non_handler_list sp_decl_non_handler ';'
+          {
+            $$.join($1, $2);
+          }
+        ;
+
+sp_decl_handler_list:
+          sp_decl_handler ';' { $$= $1; }
+        | sp_decl_handler_list sp_decl_handler ';'
+          {
+            $$.join($1, $2);
+          }
+        ;
+
+opt_sp_decl_handler_list:
+          /* Empty*/ { $$.init(); }
+        | sp_decl_handler_list
         ;
 
 qualified_column_ident:
@@ -2655,7 +2682,7 @@ type_or_rowtype:
         | ROWTYPE_SYM  { $$= 1; }
         ;
 
-sp_decl_body:
+sp_decl_non_handler:
           sp_decl_idents
           {
             Lex->sp_variable_declarations_init(thd, $1);
@@ -2709,18 +2736,6 @@ sp_decl_body:
             $$.vars= $$.hndlrs= $$.curs= 0;
             $$.conds= 1;
           }
-        | sp_handler_type HANDLER_SYM FOR_SYM
-          {
-            if (Lex->sp_handler_declaration_init(thd, $1))
-              MYSQL_YYABORT;
-          }
-          sp_hcond_list sp_proc_stmt
-          {
-            if (Lex->sp_handler_declaration_finalize(thd, $1))
-              MYSQL_YYABORT;
-            $$.vars= $$.conds= $$.curs= 0;
-            $$.hndlrs= 1;
-          }
         | CURSOR_SYM ident_directly_assignable
           {
             Lex->sp_block_init(thd);
@@ -2731,13 +2746,28 @@ sp_decl_body:
             sp_pcontext *param_ctx= Lex->spcont;
             if (Lex->sp_block_finalize(thd))
               MYSQL_YYABORT;
-            if (Lex->sp_declare_cursor(thd, $2, $6, param_ctx))
+            if (Lex->sp_declare_cursor(thd, $2, $6, param_ctx, true))
               MYSQL_YYABORT;
             $$.vars= $$.conds= $$.hndlrs= 0;
             $$.curs= 1;
           }
         ;
 
+sp_decl_handler:
+          sp_handler_type HANDLER_SYM FOR_SYM
+          {
+            if (Lex->sp_handler_declaration_init(thd, $1))
+              MYSQL_YYABORT;
+          }
+          sp_hcond_list sp_proc_stmt
+          {
+            if (Lex->sp_handler_declaration_finalize(thd, $1))
+              MYSQL_YYABORT;
+            $$.vars= $$.conds= $$.curs= 0;
+            $$.hndlrs= 1;
+          }
+        ;
+
 opt_parenthesized_cursor_formal_parameters:
           /* Empty */
         | '(' sp_fdparams ')'
@@ -3983,7 +4013,7 @@ sp_for_loop_bounds:
           {
             DBUG_ASSERT(Lex->sphead);
             LEX_STRING name= {C_STRING_WITH_LEN("[implicit_cursor]") };
-            if (Lex->sp_declare_cursor(thd, name, $4, NULL))
+            if (Lex->sp_declare_cursor(thd, name, $4, NULL, false))
               MYSQL_YYABORT;
             $$.m_direction= 1;
             if (!($$.m_index= new (thd->mem_root) sp_assignment_lex(thd, thd->lex)))
