summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/sp.result95
-rw-r--r--mysql-test/t/sp.test98
-rw-r--r--sql/sp_head.cc9
-rw-r--r--sql/sp_rcontext.cc8
-rw-r--r--sql/sp_rcontext.h4
5 files changed, 202 insertions, 12 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index f9e6eae7e57..dea04dfdfdf 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3310,19 +3310,15 @@ select 1|
1
call bug12379_1()|
bug12379()
+NULL
42
42
-Warnings:
-Error 1062 Duplicate entry 'X' for key 1
-Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
select 2|
2
2
call bug12379_2()|
bug12379()
-Warnings:
-Error 1062 Duplicate entry 'X' for key 1
-Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
+NULL
select 3|
3
3
@@ -3390,4 +3386,91 @@ s1
set sql_mode=@sm|
drop table t3|
drop procedure bug6127|
+drop table if exists t3|
+drop procedure if exists bug7049_1|
+drop procedure if exists bug7049_2|
+drop procedure if exists bug7049_3|
+drop procedure if exists bug7049_4|
+drop procedure if exists bug7049_5|
+drop procedure if exists bug7049_6|
+drop function if exists bug7049_1|
+drop function if exists bug7049_2|
+create table t3 ( x int unique )|
+create procedure bug7049_1()
+begin
+insert into t3 values (42);
+insert into t3 values (42);
+end|
+create procedure bug7049_2()
+begin
+declare exit handler for sqlexception
+select 'Caught it' as 'Result';
+call bug7049_1();
+select 'Missed it' as 'Result';
+end|
+create procedure bug7049_3()
+call bug7049_1()|
+create procedure bug7049_4()
+begin
+declare exit handler for sqlexception
+select 'Caught it' as 'Result';
+call bug7049_3();
+select 'Missed it' as 'Result';
+end|
+create procedure bug7049_5()
+begin
+declare x decimal(2,1);
+set x = 'zap';
+end|
+create procedure bug7049_6()
+begin
+declare exit handler for sqlwarning
+select 'Caught it' as 'Result';
+call bug7049_5();
+select 'Missed it' as 'Result';
+end|
+create function bug7049_1()
+returns int
+begin
+insert into t3 values (42);
+insert into t3 values (42);
+return 42;
+end|
+create function bug7049_2()
+returns int
+begin
+declare x int default 0;
+declare continue handler for sqlexception
+set x = 1;
+set x = bug7049_1();
+return x;
+end|
+call bug7049_2()|
+Result
+Caught it
+select * from t3|
+x
+42
+delete from t3|
+call bug7049_4()|
+Result
+Caught it
+select * from t3|
+x
+42
+call bug7049_6()|
+Result
+Caught it
+select bug7049_2()|
+bug7049_2()
+1
+drop table t3|
+drop procedure bug7049_1|
+drop procedure bug7049_2|
+drop procedure bug7049_3|
+drop procedure bug7049_4|
+drop procedure bug7049_5|
+drop procedure bug7049_6|
+drop function bug7049_1|
+drop function bug7049_2|
drop table t1,t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 65d4f89e2bb..67fb165d4f4 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -4265,6 +4265,104 @@ drop procedure bug6127|
#
+# BUG#7049: Stored procedure CALL errors are ignored
+#
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug7049_1|
+drop procedure if exists bug7049_2|
+drop procedure if exists bug7049_3|
+drop procedure if exists bug7049_4|
+drop procedure if exists bug7049_5|
+drop procedure if exists bug7049_6|
+drop function if exists bug7049_1|
+drop function if exists bug7049_2|
+--enable_warnings
+
+create table t3 ( x int unique )|
+
+create procedure bug7049_1()
+begin
+ insert into t3 values (42);
+ insert into t3 values (42);
+end|
+
+create procedure bug7049_2()
+begin
+ declare exit handler for sqlexception
+ select 'Caught it' as 'Result';
+
+ call bug7049_1();
+ select 'Missed it' as 'Result';
+end|
+
+create procedure bug7049_3()
+ call bug7049_1()|
+
+create procedure bug7049_4()
+begin
+ declare exit handler for sqlexception
+ select 'Caught it' as 'Result';
+
+ call bug7049_3();
+ select 'Missed it' as 'Result';
+end|
+
+create procedure bug7049_5()
+begin
+ declare x decimal(2,1);
+
+ set x = 'zap';
+end|
+
+create procedure bug7049_6()
+begin
+ declare exit handler for sqlwarning
+ select 'Caught it' as 'Result';
+
+ call bug7049_5();
+ select 'Missed it' as 'Result';
+end|
+
+create function bug7049_1()
+ returns int
+begin
+ insert into t3 values (42);
+ insert into t3 values (42);
+ return 42;
+end|
+
+create function bug7049_2()
+ returns int
+begin
+ declare x int default 0;
+ declare continue handler for sqlexception
+ set x = 1;
+
+ set x = bug7049_1();
+ return x;
+end|
+
+call bug7049_2()|
+select * from t3|
+delete from t3|
+call bug7049_4()|
+select * from t3|
+call bug7049_6()|
+select bug7049_2()|
+
+drop table t3|
+drop procedure bug7049_1|
+drop procedure bug7049_2|
+drop procedure bug7049_3|
+drop procedure bug7049_4|
+drop procedure bug7049_5|
+drop procedure bug7049_6|
+drop function bug7049_1|
+drop function bug7049_2|
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 671acbc2a0c..ab0e42a7ab6 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1110,7 +1110,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
DBUG_RETURN(-1);
// QQ Should have some error checking here? (types, etc...)
- if (!(nctx= new sp_rcontext(csize, hmax, cmax)))
+ if (!(nctx= new sp_rcontext(octx, csize, hmax, cmax)))
goto end;
for (i= 0 ; i < argcount ; i++)
{
@@ -1254,7 +1254,7 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
save_spcont= octx= thd->spcont;
if (! octx)
{ // Create a temporary old context
- if (!(octx= new sp_rcontext(csize, hmax, cmax)))
+ if (!(octx= new sp_rcontext(octx, csize, hmax, cmax)))
DBUG_RETURN(-1);
thd->spcont= octx;
@@ -1262,7 +1262,7 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
thd->spcont->callers_arena= thd;
}
- if (!(nctx= new sp_rcontext(csize, hmax, cmax)))
+ if (!(nctx= new sp_rcontext(octx, csize, hmax, cmax)))
{
thd->spcont= save_spcont;
DBUG_RETURN(-1);
@@ -2390,7 +2390,10 @@ sp_instr_hreturn::print(String *str)
str->append("hreturn ");
str->qs_append(m_frame);
if (m_dest)
+ {
+ str->append(' ');
str->qs_append(m_dest);
+ }
}
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 252bd7e5cab..ccb38358049 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -29,9 +29,9 @@
#include "sp_rcontext.h"
#include "sp_pcontext.h"
-sp_rcontext::sp_rcontext(uint fsize, uint hmax, uint cmax)
+sp_rcontext::sp_rcontext(sp_rcontext *prev, uint fsize, uint hmax, uint cmax)
: m_count(0), m_fsize(fsize), m_result(NULL), m_hcount(0), m_hsp(0),
- m_ihsp(0), m_hfound(-1), m_ccount(0)
+ m_ihsp(0), m_hfound(-1), m_ccount(0), m_prev_ctx(prev)
{
m_frame= (Item **)sql_alloc(fsize * sizeof(Item*));
m_handler= (sp_handler_t *)sql_alloc(hmax * sizeof(sp_handler_t));
@@ -116,7 +116,11 @@ sp_rcontext::find_handler(uint sql_errno,
}
}
if (found < 0)
+ {
+ if (m_prev_ctx)
+ return m_prev_ctx->find_handler(sql_errno, level);
return FALSE;
+ }
m_hfound= found;
return TRUE;
}
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index 22fa4f6e865..c7a298eccc0 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -66,7 +66,7 @@ class sp_rcontext : public Sql_alloc
*/
Query_arena *callers_arena;
- sp_rcontext(uint fsize, uint hmax, uint cmax);
+ sp_rcontext(sp_rcontext *prev, uint fsize, uint hmax, uint cmax);
~sp_rcontext()
{
@@ -226,6 +226,8 @@ private:
sp_cursor **m_cstack;
uint m_ccount;
+ sp_rcontext *m_prev_ctx; // Previous context (NULL if none)
+
}; // class sp_rcontext : public Sql_alloc