Commit a5925a90 authored by unknown's avatar unknown

Fixed BUG#7049: Stored procedure CALL errors are ignored

  Search the chain of sp_rcontexts recursively for handlers. If one is found,
  it will be detected in the sp_head::execute() method at the corresponding
  level.


mysql-test/r/sp.result:
  New test case for BUG#7049.
  Note that the spurious warnings in the BUG#12379 test now are gone (as expected).
mysql-test/t/sp.test:
  New test case for BUG#7049.
sql/sp_head.cc:
  Link sp_rcontexts to allow catching errors across invokation boundaries.
  (Also fixed print method for the hreturn instruction.)
sql/sp_rcontext.cc:
  Link sp_rcontexts to allow catching errors across invokation boundaries.
  If a handler is not found in the current sp_rcontext, recurse into the previous ones (if any).
sql/sp_rcontext.h:
  Link sp_rcontexts to allow catching errors across invokation boundaries.
parent ad8ff141
...@@ -3310,19 +3310,15 @@ select 1| ...@@ -3310,19 +3310,15 @@ select 1|
1 1
call bug12379_1()| call bug12379_1()|
bug12379() bug12379()
NULL
42 42
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| select 2|
2 2
2 2
call bug12379_2()| call bug12379_2()|
bug12379() bug12379()
Warnings: NULL
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 3| select 3|
3 3
3 3
...@@ -3390,4 +3386,91 @@ s1 ...@@ -3390,4 +3386,91 @@ s1
set sql_mode=@sm| set sql_mode=@sm|
drop table t3| drop table t3|
drop procedure bug6127| 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; drop table t1,t2;
...@@ -4264,6 +4264,104 @@ drop table t3| ...@@ -4264,6 +4264,104 @@ drop table t3|
drop procedure bug6127| 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 # BUG#NNNN: New bug synopsis
# #
......
...@@ -1110,7 +1110,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) ...@@ -1110,7 +1110,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
DBUG_RETURN(-1); DBUG_RETURN(-1);
// QQ Should have some error checking here? (types, etc...) // 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; goto end;
for (i= 0 ; i < argcount ; i++) for (i= 0 ; i < argcount ; i++)
{ {
...@@ -1254,7 +1254,7 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -1254,7 +1254,7 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
save_spcont= octx= thd->spcont; save_spcont= octx= thd->spcont;
if (! octx) if (! octx)
{ // Create a temporary old context { // 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); DBUG_RETURN(-1);
thd->spcont= octx; thd->spcont= octx;
...@@ -1262,7 +1262,7 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -1262,7 +1262,7 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
thd->spcont->callers_arena= thd; 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; thd->spcont= save_spcont;
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -2390,7 +2390,10 @@ sp_instr_hreturn::print(String *str) ...@@ -2390,7 +2390,10 @@ sp_instr_hreturn::print(String *str)
str->append("hreturn "); str->append("hreturn ");
str->qs_append(m_frame); str->qs_append(m_frame);
if (m_dest) if (m_dest)
{
str->append(' ');
str->qs_append(m_dest); str->qs_append(m_dest);
}
} }
......
...@@ -29,9 +29,9 @@ ...@@ -29,9 +29,9 @@
#include "sp_rcontext.h" #include "sp_rcontext.h"
#include "sp_pcontext.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_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_frame= (Item **)sql_alloc(fsize * sizeof(Item*));
m_handler= (sp_handler_t *)sql_alloc(hmax * sizeof(sp_handler_t)); m_handler= (sp_handler_t *)sql_alloc(hmax * sizeof(sp_handler_t));
...@@ -116,7 +116,11 @@ sp_rcontext::find_handler(uint sql_errno, ...@@ -116,7 +116,11 @@ sp_rcontext::find_handler(uint sql_errno,
} }
} }
if (found < 0) if (found < 0)
{
if (m_prev_ctx)
return m_prev_ctx->find_handler(sql_errno, level);
return FALSE; return FALSE;
}
m_hfound= found; m_hfound= found;
return TRUE; return TRUE;
} }
......
...@@ -66,7 +66,7 @@ class sp_rcontext : public Sql_alloc ...@@ -66,7 +66,7 @@ class sp_rcontext : public Sql_alloc
*/ */
Query_arena *callers_arena; 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() ~sp_rcontext()
{ {
...@@ -226,6 +226,8 @@ private: ...@@ -226,6 +226,8 @@ private:
sp_cursor **m_cstack; sp_cursor **m_cstack;
uint m_ccount; uint m_ccount;
sp_rcontext *m_prev_ctx; // Previous context (NULL if none)
}; // class sp_rcontext : public Sql_alloc }; // class sp_rcontext : public Sql_alloc
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment