From b145ca06942f8176b7b10dae82c281a312bb1edc Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 13 Sep 2005 15:32:42 +0200 Subject: [PATCH] Fixed BUG#12379: PROCEDURE with HANDLER calling FUNCTION with error get strange result according to Monty's suggestions, fixing the SELECT behaviour on errors with SP handlers. Note that some warnings from SELECT still shows up when the handler has caught - this is an effect of another known bug (BUG#7049). --- mysql-test/r/sp.result | 59 ++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 55 +++++++++++++++++++++++++++++++++++++++ sql/sql_class.cc | 28 +++++++++++++++++++- sql/sql_class.h | 4 ++- 4 files changed, 144 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 4454f818efb..3d48a9f2803 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3264,4 +3264,63 @@ bug131333() NULL drop procedure bug131333| drop function bug131333| +drop function if exists bug12379| +drop procedure if exists bug12379_1| +drop procedure if exists bug12379_2| +drop procedure if exists bug12379_3| +drop table if exists t3| +create table t3 (c1 char(1) primary key not null)| +create function bug12379() +returns integer +begin +insert into t3 values('X'); +insert into t3 values('X'); +return 0; +end| +create procedure bug12379_1() +begin +declare exit handler for sqlexception select 42; +select bug12379(); +END| +create procedure bug12379_2() +begin +declare exit handler for sqlexception begin end; +select bug12379(); +end| +create procedure bug12379_3() +begin +select bug12379(); +end| +select bug12379()| +ERROR 23000: Duplicate entry 'X' for key 1 +select 1| +1 +1 +call bug12379_1()| +bug12379() +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 +select 3| +3 +3 +call bug12379_3()| +ERROR 23000: Duplicate entry 'X' for key 1 +select 4| +4 +4 +drop function bug12379| +drop procedure bug12379_1| +drop procedure bug12379_2| +drop procedure bug12379_3| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 2b705329961..7a9738e8ada 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4108,6 +4108,61 @@ drop procedure bug131333| drop function bug131333| +# +# BUG#12379: PROCEDURE with HANDLER calling FUNCTION with error get +# strange result +# +--disable_warnings +drop function if exists bug12379| +drop procedure if exists bug12379_1| +drop procedure if exists bug12379_2| +drop procedure if exists bug12379_3| +drop table if exists t3| +--enable_warnings + +create table t3 (c1 char(1) primary key not null)| + +create function bug12379() + returns integer +begin + insert into t3 values('X'); + insert into t3 values('X'); + return 0; +end| + +create procedure bug12379_1() +begin + declare exit handler for sqlexception select 42; + + select bug12379(); +END| +create procedure bug12379_2() +begin + declare exit handler for sqlexception begin end; + + select bug12379(); +end| +create procedure bug12379_3() +begin + select bug12379(); +end| + +--error 1062 +select bug12379()| +select 1| +call bug12379_1()| +select 2| +call bug12379_2()| +select 3| +--error 1062 +call bug12379_3()| +select 4| + +drop function bug12379| +drop procedure bug12379_1| +drop procedure bug12379_2| +drop procedure bug12379_3| + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 975014b9780..2699a4fa628 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -865,9 +865,34 @@ sql_exchange::sql_exchange(char *name,bool flag) bool select_send::send_fields(List &list, uint flags) { - return thd->protocol->send_fields(&list, flags); + bool res; + if (!(res= thd->protocol->send_fields(&list, flags))) + status= 1; + return res; } +void select_send::abort() +{ + DBUG_ENTER("select_send::abort"); + if (status && thd->spcont && + thd->spcont->find_handler(thd->net.last_errno, + MYSQL_ERROR::WARN_LEVEL_ERROR)) + { + /* + Executing stored procedure without a handler. + Here we should actually send an error to the client, + but as an error will break a multiple result set, the only thing we + can do for now is to nicely end the current data set and remembering + the error so that the calling routine will abort + */ + thd->net.report_error= 0; + send_eof(); + thd->net.report_error= 1; // Abort SP + } + DBUG_VOID_RETURN; +} + + /* Send data to client. Returns 0 if ok */ bool select_send::send_data(List &items) @@ -930,6 +955,7 @@ bool select_send::send_eof() if (!thd->net.report_error) { ::send_eof(thd); + status= 0; return 0; } else diff --git a/sql/sql_class.h b/sql/sql_class.h index a0c61944c6a..1a215d39841 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1658,12 +1658,14 @@ public: class select_send :public select_result { + int status; public: - select_send() {} + select_send() :status(0) {} bool send_fields(List &list, uint flags); bool send_data(List &items); bool send_eof(); bool simple_select() { return 1; } + void abort(); };