Commit 77bd9d36 authored by unknown's avatar unknown
Browse files

Fixed BUG#10961: Stored procedures: crash if select * from dual

  Have to catch errors from SELECT when opening a cursor.


mysql-test/r/sp.result:
  New test case for BUG#10961.
mysql-test/t/sp.test:
  New test case for BUG#10961.
sql/protocol.h:
  Init data in Protocol_cursor constructor, for error cases.
sql/sp_head.cc:
  Catch "hidden" errors during SELECT when opening a cursor.
parent abbdab6a
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -3109,4 +3109,33 @@ select bug9559()|
bug9559()
-3
drop function bug9559|
drop procedure if exists bug10961|
create procedure bug10961()
begin
declare v char;
declare x int;
declare c cursor for select * from dual;
declare continue handler for sqlexception select x;
set x = 1;
open c;
set x = 2;
fetch c into v;
set x = 3;
close c;
end|
call bug10961()|
x
1
x
2
x
3
call bug10961()|
x
1
x
2
x
3
drop procedure bug10961|
drop table t1,t2;
+29 −0
Original line number Diff line number Diff line
@@ -3801,6 +3801,7 @@ call bug5963_2(1)|
drop procedure bug5963_2|
drop table t3|


#
# BUG#9559: Functions: Numeric Operations using -ve value gives incorrect
#           results.
@@ -3820,6 +3821,34 @@ select bug9559()|
drop function bug9559|


#
# BUG#10961: Stored procedures: crash if select * from dual
#
--disable_warnings
drop procedure if exists bug10961|
--enable_warnings
# "select * from dual" results in an error, so the cursor will not open
create procedure bug10961()
begin
  declare v char;
  declare x int;
  declare c cursor for select * from dual;
  declare continue handler for sqlexception select x;

  set x = 1;
  open c;
  set x = 2;
  fetch c into v;
  set x = 3;
  close c;
end|

call bug10961()|
call bug10961()|

drop procedure bug10961|


#
# BUG#NNNN: New bug synopsis
#
+2 −2
Original line number Diff line number Diff line
@@ -159,8 +159,8 @@ class Protocol_cursor :public Protocol_simple
  MYSQL_ROWS **prev_record;
  ulong row_count;

  Protocol_cursor() {}
  Protocol_cursor(THD *thd_arg, MEM_ROOT *ini_alloc) :Protocol_simple(thd_arg), alloc(ini_alloc) {}
  Protocol_cursor() :data(NULL) {}
  Protocol_cursor(THD *thd_arg, MEM_ROOT *ini_alloc) :Protocol_simple(thd_arg), alloc(ini_alloc), data(NULL) {}
  bool prepare_for_send(List<Item> *item_list) 
  {
    row_count= 0;
+13 −1
Original line number Diff line number Diff line
@@ -1913,7 +1913,19 @@ sp_instr_copen::execute(THD *thd, uint *nextp)
    else
      res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);

    c->post_open(thd, (lex_keeper ? TRUE : FALSE));
    /*
      Work around the fact that errors in selects are not returned properly
      (but instead converted into a warning), so if a condition handler
      caught, we have lost the result code.
     */
    if (!res)
    {
      uint dummy1, dummy2;

      if (thd->spcont->found_handler(&dummy1, &dummy2))
	res= -1;
    }
    c->post_open(thd, (lex_keeper && !res ? TRUE : FALSE));
  }

  DBUG_RETURN(res);