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|
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;
......@@ -4264,6 +4264,104 @@ drop table t3|
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
#
......
......@@ -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);
}
}
......
......@@ -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;
}
......
......@@ -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 @@ class sp_rcontext : public Sql_alloc
sp_cursor **m_cstack;
uint m_ccount;
sp_rcontext *m_prev_ctx; // Previous context (NULL if none)
}; // 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