Commit b145ca06 authored by pem@mysql.com's avatar pem@mysql.com

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).
parent 54560d50
...@@ -3264,4 +3264,63 @@ bug131333() ...@@ -3264,4 +3264,63 @@ bug131333()
NULL NULL
drop procedure bug131333| drop procedure bug131333|
drop function 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; drop table t1,t2;
...@@ -4108,6 +4108,61 @@ drop procedure bug131333| ...@@ -4108,6 +4108,61 @@ drop procedure bug131333|
drop function 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 # BUG#NNNN: New bug synopsis
# #
......
...@@ -865,9 +865,34 @@ sql_exchange::sql_exchange(char *name,bool flag) ...@@ -865,9 +865,34 @@ sql_exchange::sql_exchange(char *name,bool flag)
bool select_send::send_fields(List<Item> &list, uint flags) bool select_send::send_fields(List<Item> &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 */ /* Send data to client. Returns 0 if ok */
bool select_send::send_data(List<Item> &items) bool select_send::send_data(List<Item> &items)
...@@ -930,6 +955,7 @@ bool select_send::send_eof() ...@@ -930,6 +955,7 @@ bool select_send::send_eof()
if (!thd->net.report_error) if (!thd->net.report_error)
{ {
::send_eof(thd); ::send_eof(thd);
status= 0;
return 0; return 0;
} }
else else
......
...@@ -1658,12 +1658,14 @@ public: ...@@ -1658,12 +1658,14 @@ public:
class select_send :public select_result { class select_send :public select_result {
int status;
public: public:
select_send() {} select_send() :status(0) {}
bool send_fields(List<Item> &list, uint flags); bool send_fields(List<Item> &list, uint flags);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
bool send_eof(); bool send_eof();
bool simple_select() { return 1; } bool simple_select() { return 1; }
void abort();
}; };
......
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