Commit a5925a90 authored by unknown's avatar unknown
Browse files

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
Loading
Loading
Loading
Loading
+89 −6
Original line number Diff line number Diff line
@@ -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;
+98 −0
Original line number Diff line number Diff line
@@ -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
#
+6 −3
Original line number Diff line number Diff line
@@ -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,8 +2390,11 @@ sp_instr_hreturn::print(String *str)
  str->append("hreturn ");
  str->qs_append(m_frame);
  if (m_dest)
  {
    str->append(' ');
    str->qs_append(m_dest);
  }
}


uint
+6 −2
Original line number Diff line number Diff line
@@ -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;
}
+3 −1
Original line number Diff line number Diff line
@@ -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