From 77bd9d36e6c703045e01de655952f98f79e6332a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Jun 2005 12:18:41 +0200 Subject: [PATCH] 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. --- mysql-test/r/sp.result | 29 +++++++++++++++++++++++++++++ mysql-test/t/sp.test | 29 +++++++++++++++++++++++++++++ sql/protocol.h | 4 ++-- sql/sp_head.cc | 14 +++++++++++++- 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index da54c100178..3c6fa84882f 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -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; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 18389f4d80a..7acd4d81081 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -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 # diff --git a/sql/protocol.h b/sql/protocol.h index 01331ef64ba..5b402cb2669 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -159,8 +159,8 @@ public: 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_list) { row_count= 0; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fcca1b51d1c..c17c8b81cb2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -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);