From 46047f277bba8dbb4534fb339761dcf95b04ef17 Mon Sep 17 00:00:00 2001
From: halfspawn <j.brauge@qualiac.com>
Date: Thu, 30 Mar 2017 11:26:02 +0200
Subject: [PATCH] Show callstack as notes on error.

---
 mysql-test/r/commit_1innodb.result                 |   1 +
 mysql-test/r/get_diagnostics.result                |   2 +-
 mysql-test/r/signal.result                         |  16 ++
 mysql-test/r/signal_demo3.result                   |   1 +
 mysql-test/r/sp-error.result                       |   2 +
 mysql-test/r/sp.result                             |   1 +
 mysql-test/r/warnings.result                       |   1 +
 .../suite/compat/oracle/r/sp-stacktrace.result     | 175 +++++++++++++++++++++
 .../suite/compat/oracle/t/sp-stacktrace.test       | 152 ++++++++++++++++++
 mysql-test/suite/rpl/r/rpl_slave_grp_exec.result   |   1 +
 mysql-test/suite/rpl/r/rpl_sp.result               |   2 +
 mysql-test/suite/rpl/t/rpl_slave_grp_exec.test     |   1 +
 sql/share/errmsg-utf8.txt                          |   2 +
 sql/sp_head.cc                                     |  11 +-
 sql/sp_head.h                                      |   1 +
 sql/sql_error.cc                                   |  24 +++
 sql/sql_error.h                                    |   6 +
 sql/sql_parse.cc                                   |  12 +-
 sql/sql_signal.cc                                  |   3 +
 19 files changed, 408 insertions(+), 6 deletions(-)
 create mode 100644 mysql-test/suite/compat/oracle/r/sp-stacktrace.result
 create mode 100644 mysql-test/suite/compat/oracle/t/sp-stacktrace.test

diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result
index 1adba7b..0529342 100644
--- a/mysql-test/r/commit_1innodb.result
+++ b/mysql-test/r/commit_1innodb.result
@@ -230,6 +230,7 @@ insert into t2 (a) values (1023);
 do (f2(23));
 Warnings:
 Error	1062	Duplicate entry '23' for key 'a'
+Note	1982	At line 4 in test.f2
 select * from t2;
 a
 1023
diff --git a/mysql-test/r/get_diagnostics.result b/mysql-test/r/get_diagnostics.result
index fbe3a02..000f55c 100644
--- a/mysql-test/r/get_diagnostics.result
+++ b/mysql-test/r/get_diagnostics.result
@@ -595,7 +595,7 @@ SELECT var, @var;
 END|
 CALL p1();
 var	@var
-1	1
+2	2
 DROP PROCEDURE p1;
 
 # Setting TABLE_NAME is currently not implemented.
diff --git a/mysql-test/r/signal.result b/mysql-test/r/signal.result
index f05e357..6667085 100644
--- a/mysql-test/r/signal.result
+++ b/mysql-test/r/signal.result
@@ -1715,6 +1715,7 @@ show warnings $$
 Level	Code	Message
 Warning	1012	Raising a warning
 Error	5555	RESIGNAL to not found
+Note	4059	At line 9 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -1739,6 +1740,7 @@ show warnings $$
 Level	Code	Message
 Warning	1012	Raising a warning
 Error	5555	RESIGNAL to error
+Note	4059	At line 9 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -1787,6 +1789,7 @@ show warnings $$
 Level	Code	Message
 Error	1012	Raising a not found
 Error	5555	RESIGNAL to not found
+Note	4059	At line 9 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -1811,6 +1814,7 @@ show warnings $$
 Level	Code	Message
 Error	1012	Raising a not found
 Error	5555	RESIGNAL to error
+Note	4059	At line 9 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -1859,6 +1863,7 @@ show warnings $$
 Level	Code	Message
 Error	1012	Raising an error
 Error	5555	RESIGNAL to not found
+Note	4059	At line 9 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -1883,6 +1888,7 @@ show warnings $$
 Level	Code	Message
 Error	1012	Raising an error
 Error	5555	RESIGNAL to error
+Note	4059	At line 9 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -1925,6 +1931,7 @@ show warnings $$
 Level	Code	Message
 Warning	1264	Out of range value for column 'a' at row 1
 Error	5555	RESIGNAL to a not found
+Note	4059	At line 8 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -1946,6 +1953,7 @@ show warnings $$
 Level	Code	Message
 Warning	1264	Out of range value for column 'a' at row 1
 Error	5555	RESIGNAL to an error
+Note	4059	At line 8 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -1996,6 +2004,7 @@ show warnings $$
 Level	Code	Message
 Error	1329	No data - zero rows fetched, selected, or processed
 Error	5555	RESIGNAL to a not found
+Note	4059	At line 10 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -2021,6 +2030,7 @@ show warnings $$
 Level	Code	Message
 Error	1329	No data - zero rows fetched, selected, or processed
 Error	5555	RESIGNAL to an error
+Note	4059	At line 10 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -2063,6 +2073,7 @@ show warnings $$
 Level	Code	Message
 Error	1051	Unknown table 'test.no_such_table'
 Error	5555	RESIGNAL to a not found
+Note	4059	At line 8 in test.test_resignal
 drop procedure test_resignal $$
 create procedure test_resignal()
 begin
@@ -2084,6 +2095,7 @@ show warnings $$
 Level	Code	Message
 Error	1051	Unknown table 'test.no_such_table'
 Error	5555	RESIGNAL to an error
+Note	4059	At line 8 in test.test_resignal
 drop procedure test_resignal $$
 #
 # More complex cases
@@ -2130,6 +2142,7 @@ ERROR 42000: Hi, I am a useless error message
 show warnings $$
 Level	Code	Message
 Error	9999	Hi, I am a useless error message
+Note	4059	At line 7 in test.peter_p2
 drop procedure peter_p1 $$
 drop procedure peter_p2 $$
 CREATE PROCEDURE peter_p1 ()
@@ -2185,6 +2198,7 @@ Level	Code	Message
 Error	1231	Variable 'sql_mode' can't be set to the value of 'NULL'
 Error	1232	Variable 'sql_mode' can't be set to the value of 'NULL'
 Error	9999	Variable 'sql_mode' can't be set to the value of 'NULL'
+Note	4059	At line 8 in test.peter_p1
 ERROR 42000: Hi, I am a useless error message
 show warnings $$
 Level	Code	Message
@@ -2192,6 +2206,7 @@ Error	1231	Variable 'sql_mode' can't be set to the value of 'NULL'
 Error	1232	Variable 'sql_mode' can't be set to the value of 'NULL'
 Error	9999	Variable 'sql_mode' can't be set to the value of 'NULL'
 Error	9999	Hi, I am a useless error message
+Note	4059	At line 10 in test.peter_p2
 drop procedure peter_p1 $$
 drop procedure peter_p2 $$
 drop procedure if exists peter_p3 $$
@@ -2209,6 +2224,7 @@ show warnings $$
 Level	Code	Message
 Error	1	Original
 Error	2	Original
+Note	4059	At line 4 in test.peter_p3
 drop procedure peter_p3 $$
 drop table t_warn;
 drop table t_cursor;
diff --git a/mysql-test/r/signal_demo3.result b/mysql-test/r/signal_demo3.result
index cc70422..2c29958 100644
--- a/mysql-test/r/signal_demo3.result
+++ b/mysql-test/r/signal_demo3.result
@@ -87,6 +87,7 @@ Error	1644	Oops in proc_4
 Error	1644	Oops in proc_3
 Error	1644	Oops in proc_2
 Error	1644	Oops in proc_1
+Note	4059	At line 4 in demo.proc_1
 SET @@session.max_error_count = 5;
 SELECT @@session.max_error_count;
 @@session.max_error_count
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index aee3a61..0e2a4b4 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1990,6 +1990,8 @@ Warning	1264	Out of range value for column 'a' at row 1
 Note	1292	Truncated incorrect INTEGER value: '222222 '
 Warning	1264	Out of range value for column 'b' at row 1
 Error	1048	Column 'c' cannot be null
+Note	4059	At line 6 in test.t1_bi
+Note	4059	At line 2 in test.p1
 
 DROP TABLE t1;
 DROP TABLE t2;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 85a04df..01efa6e 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -7823,6 +7823,7 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
 show warnings;
 Level	Code	Message
 Error	1062	Duplicate entry '2' for key 'PRIMARY'
+Note	4059	At line 5 in test.p1
 select * from t1;
 id
 1
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 3f4f62d..a2c68ad 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -353,6 +353,7 @@ ERROR 23000: Duplicate entry '11' for key 'a'
 
 SHOW WARNINGS;
 Level	Code	Message
+Note	4059	At line 4 in test.f1
 Error	1062	Duplicate entry '11' for key 'a'
 
 DROP TABLE t1;
diff --git a/mysql-test/suite/compat/oracle/r/sp-stacktrace.result b/mysql-test/suite/compat/oracle/r/sp-stacktrace.result
new file mode 100644
index 0000000..3f55b88
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/sp-stacktrace.result
@@ -0,0 +1,175 @@
+SET sql_mode=ORACLE;
+set max_sp_recursion_depth=5;
+#
+# MDEV- ???? - add stacktrace as note when an error occured in SP
+#
+# Error in anonymous block
+BEGIN NOT ATOMIC
+SIGNAL SQLSTATE '02000';
+END
+$$
+ERROR 02000: Unhandled user-defined not found condition
+show warnings;
+Level	Code	Message
+Error	1643	Unhandled user-defined not found condition
+Note	4059	At line 2 in anonymous block
+# Warning in anonymous block
+BEGIN NOT ATOMIC
+SIGNAL SQLSTATE '01000';
+END
+$$
+Warnings:
+Warning	1642	Unhandled user-defined warning condition
+show warnings;
+Level	Code	Message
+Warning	1642	Unhandled user-defined warning condition
+# Warning and error in anonymous block
+BEGIN NOT ATOMIC
+SIGNAL SQLSTATE '01000';
+SIGNAL SQLSTATE '02000';
+END
+$$
+ERROR 02000: Unhandled user-defined not found condition
+show warnings;
+Level	Code	Message
+Error	1643	Unhandled user-defined not found condition
+Note	4059	At line 3 in anonymous block
+create or replace table t1(c1 integer not null);
+create trigger trg1 before insert on t1
+for each row
+begin
+if :new.c1 = 1 then
+:new.c1:=null;
+end if;
+if :new.c1 = 2 then
+call f2(0);
+end if;
+end;
+$$
+CREATE or replace procedure P1(lim INT)
+AS
+a INT;
+BEGIN
+P2(lim);
+return ;
+END;
+$$
+CREATE or replace procedure P2(lim INT)
+AS
+a INT;
+b INT;
+BEGIN
+a:=10;
+-- comment
+if (lim = 2) then
+-- error on insert values
+insert into t1 values (null);
+end if;
+if (lim = 4) then
+-- error in trigger
+insert into t1 values (1);
+end if;
+if (lim = 5) then
+-- error sp called by a trigger
+insert into t1 values (2);
+end if;
+/*
+** Multi line comment
+*/
+if (lim = 3) then
+a:=11;
+SIGNAL SQLSTATE '02000';
+return ;
+end if;
+if (lim = 1) then
+declare
+c int;
+begin
+-- unknow procedure
+call P3();
+end;
+end if;
+-- max recursion depth
+P2(lim);
+return ;
+END;
+$$
+CREATE or replace function F1(val INT) return integer
+AS
+a INT;
+BEGIN
+if (val = 3) then
+SIGNAL SQLSTATE '02000';
+end if;
+return  val;
+END;
+$$
+bad insert values
+CALL P1(2);
+ERROR 23000: Column 'c1' cannot be null
+show warnings;
+Level	Code	Message
+Error	1048	Column 'c1' cannot be null
+Note	4059	At line 10 in test.P2
+Note	4059	At line 5 in test.P1
+call unknow function
+CALL P1(1);
+ERROR 42000: PROCEDURE test.P3 does not exist
+show warnings;
+Level	Code	Message
+Error	1305	PROCEDURE test.P3 does not exist
+Note	4059	At line 33 in test.P2
+Note	4059	At line 5 in test.P1
+max recursion
+CALL P1(0);
+ERROR HY000: Recursive limit 5 (as set by the max_sp_recursion_depth variable) was exceeded for routine P2
+show warnings;
+Level	Code	Message
+Error	1456	Recursive limit 5 (as set by the max_sp_recursion_depth variable) was exceeded for routine P2
+Note	4059	At line 37 in test.P2
+Note	4059	At line 37 in test.P2
+Note	4059	At line 37 in test.P2
+Note	4059	At line 37 in test.P2
+Note	4059	At line 37 in test.P2
+Note	4059	At line 37 in test.P2
+Note	4059	At line 5 in test.P1
+signal error
+CALL P2(3);
+ERROR 02000: Unhandled user-defined not found condition
+show warnings;
+Level	Code	Message
+Error	1643	Unhandled user-defined not found condition
+Note	4059	At line 25 in test.P2
+bad insert values cause by trigger
+CALL P2(4);
+ERROR 23000: Column 'c1' cannot be null
+show warnings;
+Level	Code	Message
+Error	1048	Column 'c1' cannot be null
+Note	4059	At line 14 in test.P2
+error in sp called by a trigger
+CALL P2(5);
+ERROR 42000: PROCEDURE test.f2 does not exist
+show warnings;
+Level	Code	Message
+Error	1305	PROCEDURE test.f2 does not exist
+Note	4059	At line 8 in test.trg1
+Note	4059	At line 18 in test.P2
+error in sp called by a trigger
+insert into t1 select 3 union select 2;
+ERROR 42000: PROCEDURE test.f2 does not exist
+show warnings;
+Level	Code	Message
+Error	1305	PROCEDURE test.f2 does not exist
+Note	4059	At line 8 in test.trg1
+error in function
+select F1(t.col1) from (select 3 "col1" union select 4) as t;
+ERROR 02000: Unhandled user-defined not found condition
+show warnings;
+Level	Code	Message
+Error	1643	Unhandled user-defined not found condition
+Note	4059	At line 6 in test.F1
+drop function F1;
+drop procedure P1;
+drop procedure P2;
+drop table t1;
diff --git a/mysql-test/suite/compat/oracle/t/sp-stacktrace.test b/mysql-test/suite/compat/oracle/t/sp-stacktrace.test
new file mode 100644
index 0000000..c9f7db6
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/sp-stacktrace.test
@@ -0,0 +1,152 @@
+
+SET sql_mode=ORACLE;
+set max_sp_recursion_depth=5;
+
+--echo #
+--echo # MDEV- ???? - add stacktrace as note when an error occured in SP
+--echo #
+
+DELIMITER $$;
+--echo # Error in anonymous block
+--error ER_SIGNAL_NOT_FOUND
+BEGIN NOT ATOMIC
+  SIGNAL SQLSTATE '02000';
+END
+$$
+DELIMITER ;$$
+show warnings;
+DELIMITER $$;
+--echo # Warning in anonymous block
+BEGIN NOT ATOMIC
+  SIGNAL SQLSTATE '01000';
+END
+$$
+DELIMITER ;$$
+show warnings;
+DELIMITER $$;
+--echo # Warning and error in anonymous block
+--error ER_SIGNAL_NOT_FOUND
+BEGIN NOT ATOMIC
+  SIGNAL SQLSTATE '01000';
+  SIGNAL SQLSTATE '02000';
+END
+$$
+DELIMITER ;$$
+show warnings;
+create or replace table t1(c1 integer not null);
+DELIMITER $$;
+create trigger trg1 before insert on t1
+for each row
+begin
+  if :new.c1 = 1 then
+    :new.c1:=null;
+  end if;
+  if :new.c1 = 2 then
+    call f2(0);
+  end if;
+end;
+$$
+CREATE or replace procedure P1(lim INT)
+AS
+  a INT;
+BEGIN
+  P2(lim);
+  return ;
+END;
+$$
+CREATE or replace procedure P2(lim INT)
+AS
+  a INT;
+  b INT;
+BEGIN
+  a:=10;
+  -- comment
+  if (lim = 2) then
+    -- error on insert values
+    insert into t1 values (null);
+  end if;
+  if (lim = 4) then
+    -- error in trigger
+    insert into t1 values (1);
+  end if;
+  if (lim = 5) then
+    -- error sp called by a trigger
+    insert into t1 values (2);
+  end if;
+  /*
+  ** Multi line comment
+  */
+  if (lim = 3) then
+    a:=11;
+    SIGNAL SQLSTATE '02000';
+    return ;
+  end if;
+  if (lim = 1) then
+    declare
+       c int;
+    begin
+      -- unknow procedure
+      call P3();
+     end;
+  end if;
+  -- max recursion depth
+  P2(lim);
+  return ;
+END;
+$$
+CREATE or replace function F1(val INT) return integer
+AS
+  a INT;
+BEGIN
+  if (val = 3) then
+    SIGNAL SQLSTATE '02000';
+  end if;
+  return  val;
+END;
+$$
+DELIMITER ;$$
+
+--echo  bad insert values
+--error ER_BAD_NULL_ERROR
+CALL P1(2);
+show warnings;
+
+--echo call unknow function
+--error ER_SP_DOES_NOT_EXIST
+CALL P1(1);
+show warnings;
+
+--echo max recursion
+--error ER_SP_RECURSION_LIMIT
+CALL P1(0);
+show warnings;
+
+--echo signal error
+--error ER_SIGNAL_NOT_FOUND
+CALL P2(3);
+show warnings;
+
+--echo bad insert values cause by trigger
+--error ER_BAD_NULL_ERROR
+CALL P2(4);
+show warnings;
+
+--echo error in sp called by a trigger
+--error ER_SP_DOES_NOT_EXIST
+CALL P2(5);
+show warnings;
+
+--echo error in sp called by a trigger
+--error ER_SP_DOES_NOT_EXIST
+insert into t1 select 3 union select 2;
+show warnings;
+
+--echo error in function
+--error ER_SIGNAL_NOT_FOUND
+select F1(t.col1) from (select 3 "col1" union select 4) as t;
+show warnings;
+
+drop function F1;
+drop procedure P1;
+drop procedure P2;
+drop table t1;
\ No newline at end of file
diff --git a/mysql-test/suite/rpl/r/rpl_slave_grp_exec.result b/mysql-test/suite/rpl/r/rpl_slave_grp_exec.result
index 9a34844..60ad6dc 100644
--- a/mysql-test/suite/rpl/r/rpl_slave_grp_exec.result
+++ b/mysql-test/suite/rpl/r/rpl_slave_grp_exec.result
@@ -35,6 +35,7 @@ a	b
 1	ZZ
 connection slave;
 call mtr.add_suppression("Slave SQL.*Table .test.t3. doesn.t exist.* error.* 1146");
+call mtr.add_suppression("At line *");
 include/wait_for_slave_sql_error.inc [errno=1146]
 SHOW TABLES LIKE 't%';
 Tables_in_test (t%)
diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result
index 411a242..e2b8359 100644
--- a/mysql-test/suite/rpl/r/rpl_sp.result
+++ b/mysql-test/suite/rpl/r/rpl_sp.result
@@ -128,6 +128,7 @@ show warnings;
 Level	Code	Message
 Error	1062	Duplicate entry '20' for key 'a'
 Warning	1196	Some non-transactional changed tables couldn't be rolled back
+Note	4059	At line 4 in mysqltest1.foo4
 select * from t2;
 a
 20
@@ -290,6 +291,7 @@ end|
 do fn1(100);
 Warnings:
 Error	1062	Duplicate entry '100' for key 'a'
+Note	4059	At line 3 in mysqltest1.fn1
 Warning	1196	Some non-transactional changed tables couldn't be rolled back
 select fn1(20);
 ERROR 23000: Duplicate entry '20' for key 'a'
diff --git a/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test b/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test
index 426c3c8..928ad7e 100644
--- a/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test
+++ b/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test
@@ -64,6 +64,7 @@ SELECT * FROM t3 ORDER BY a;
 --connection slave
 # 1146 = ER_NO_SUCH_TABLE
 call mtr.add_suppression("Slave SQL.*Table .test.t3. doesn.t exist.* error.* 1146");
+call mtr.add_suppression("At line *");
 --let $slave_sql_errno= 1146
 --source include/wait_for_slave_sql_error.inc
 SHOW TABLES LIKE 't%';
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 5a86344..c3016f1 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -7466,3 +7466,5 @@ ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD
         eng "Row variable '%-.192s' does not have a field '%-.192s'"
 ER_END_IDENTIFIER_DOES_NOT_MATCH
         eng "END identifier '%-.192s' does not match '%-.192s'"
+ER_SP_STACK_TRACE
+        eng "At line %d in %s"
\ No newline at end of file
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index d0c03d1..933a04e 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1208,11 +1208,10 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
   /* Discard the initial part of executing routines. */
   thd->profiling.discard_current_query();
 #endif
+  sp_instr *i;
   DEBUG_SYNC(thd, "sp_head_execute_before_loop");
   do
   {
-    sp_instr *i;
-
 #if defined(ENABLED_PROFILING)
     /*
      Treat each "instr" of a routine as discrete unit that could be profiled.
@@ -1372,6 +1371,13 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
       da->opt_clear_warning_info(thd->query_id);
       da->copy_sql_conditions_from_wi(thd, &sp_wi);
       da->remove_marked_sql_conditions();
+      if (i != NULL)
+        push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+                            ER_SP_STACK_TRACE,
+                            ER_THD(thd, ER_SP_STACK_TRACE),
+                            i->m_lineno,
+                            m_qname.str != NULL ? m_qname.str :
+                                                  "anonymous block");
     }
   }
 
@@ -2799,6 +2805,7 @@ int sp_head::add_instr(sp_instr *instr)
     entire stored procedure, as their life span is equal.
   */
   instr->mem_root= &main_mem_root;
+  instr->m_lineno= m_thd->m_parser_state->m_lip.yylineno;
   return insert_dynamic(&m_instr, (uchar*)&instr);
 }
 
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 55734b0..1b462f8 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -883,6 +883,7 @@ class sp_instr :public Query_arena, public Sql_alloc
   uint marked;
   uint m_ip;			///< My index
   sp_pcontext *m_ctx;		///< My parse context
+  uint m_lineno;
 
   /// Should give each a name or type code for debugging purposes?
   sp_instr(uint ip, sp_pcontext *ctx)
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 745471a..ccad296 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -643,6 +643,30 @@ bool Warning_info::is_marked_for_removal(const Sql_condition *cond) const
   return false;
 }
 
+void Warning_info::remove_notes(THD *thd)
+{
+  Sql_condition *cond;
+  Sql_condition_list::Iterator it(m_warn_list);
+  List<Sql_condition > notes_to_remove;
+  notes_to_remove.empty();
+
+  while ((cond= it++))
+  {
+    if (cond->get_level() == Sql_condition::WARN_LEVEL_NOTE)
+      notes_to_remove.push_back(cond);
+  }
+
+  if (!notes_to_remove.is_empty())
+  {
+    List_iterator_fast<Sql_condition> it(notes_to_remove);
+    while ((cond= it++))
+    {
+      m_warn_list.remove(cond);
+      m_warn_count[cond->get_level()]--;
+      m_current_statement_warn_count--;
+    }
+  }
+}
 
 void Warning_info::reserve_space(THD *thd, uint count)
 {
diff --git a/sql/sql_error.h b/sql/sql_error.h
index bbe9733..4896197 100644
--- a/sql/sql_error.h
+++ b/sql/sql_error.h
@@ -732,6 +732,9 @@ class Warning_info
   /** Make sure there is room for the given number of conditions. */
   void reserve_space(THD *thd, uint count);
 
+  // Remove all notes from warnings list.
+  void remove_notes(THD *thd);
+
   /**
     Add a new SQL-condition to the current list and increment the respective
     counters.
@@ -1125,6 +1128,9 @@ class Diagnostics_area: public Sql_state_errno,
   Sql_condition_iterator sql_conditions() const
   { return get_warning_info()->m_warn_list; }
 
+  void remove_notes(THD *thd)
+  { get_warning_info()->remove_notes(thd); }
+
   void reserve_space(THD *thd, uint count)
   { get_warning_info()->reserve_space(thd, count); }
 
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 23d577f..64bf835 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5899,9 +5899,15 @@ mysql_execute_command(THD *thd)
       if (!(sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
                                 &thd->sp_proc_cache, TRUE)))
       {
-	my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
-                 lex->spname->m_qname.str);
-	goto error;
+        /*
+          sp_find_routine can have issued an ER_SP_RECURSION_LIMIT error.
+          Send message ER_SP_DOES_NOT_EXIST only if procedure is not found in
+          cache.
+        */
+        if (!sp_cache_lookup(&thd->sp_proc_cache, lex->spname))
+          my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
+                   lex->spname->m_qname.str);
+        goto error;
       }
       else
       {
diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc
index 828149f..61edaa7 100644
--- a/sql/sql_signal.cc
+++ b/sql/sql_signal.cc
@@ -428,6 +428,9 @@ bool Sql_cmd_resignal::execute(THD *thd)
   {
     query_cache_abort(thd, &thd->query_cache_tls);
 
+    // Remove all notes from warnings list.
+    da->remove_notes(thd);
+
     /* Keep handled conditions. */
     da->unmark_sql_conditions_from_removal();
 
-- 
2.6.3.windows.1

