mirror of
https://github.com/MariaDB/server.git
synced 2025-10-27 05:56:07 +03:00
******
This patch fixes the following bugs:
- Bug#5889: Exit handler for a warning doesn't hide the warning in
trigger
- Bug#9857: Stored procedures: handler for sqlwarning ignored
- Bug#23032: Handlers declared in a SP do not handle warnings generated
in sub-SP
- Bug#36185: Incorrect precedence for warning and exception handlers
The problem was in the way warnings/errors during stored routine execution
were handled. Prior to this patch the logic was as follows:
- when a warning/an error happens: if we're executing a stored routine,
and there is a handler for that warning/error, remember the handler,
ignore the warning/error and continue execution.
- after a stored routine instruction is executed: check for a remembered
handler and activate one (if any).
This logic caused several problems:
- if one instruction generates several warnings (errors) it's impossible
to choose the right handler -- a handler for the first generated
condition was chosen and remembered for activation.
- mess with handling conditions in scopes different from the current one.
- not putting generated warnings/errors into Warning Info (Diagnostic
Area) is against The Standard.
The patch changes the logic as follows:
- Diagnostic Area is cleared on the beginning of each statement that
either is able to generate warnings, or is able to work with tables.
- at the end of a stored routine instruction, Diagnostic Area is left
intact.
- Diagnostic Area is checked after each stored routine instruction. If
an instruction generates several condition, it's now possible to take a
look at all of them and determine an appropriate handler.
65 lines
1.5 KiB
Plaintext
65 lines
1.5 KiB
Plaintext
drop procedure if exists test.longprocedure;
|
|
drop table if exists t1;
|
|
create table t1 (a int);
|
|
insert into t1 values (1),(2),(3);
|
|
length
|
|
107520
|
|
select length(routine_definition) from information_schema.routines where routine_schema = 'test' and routine_name = 'longprocedure';
|
|
length(routine_definition)
|
|
107530
|
|
call test.longprocedure(@value);
|
|
select @value;
|
|
@value
|
|
3
|
|
drop procedure test.longprocedure;
|
|
drop table t1;
|
|
create table t1 (f1 char(100) , f2 mediumint , f3 int , f4 real, f5 numeric);
|
|
insert into t1 (f1, f2, f3, f4, f5) values
|
|
("This is a test case for for Bug#9819", 1, 2, 3.0, 4.598);
|
|
Warnings:
|
|
Note 1265 Data truncated for column 'f5' at row 1
|
|
create table t2 like t1;
|
|
select count(*) from t1;
|
|
count(*)
|
|
256
|
|
select count(*) from t2;
|
|
count(*)
|
|
0
|
|
drop procedure if exists p1;
|
|
create procedure p1()
|
|
begin
|
|
declare done integer default 0;
|
|
declare vf1 char(100) ;
|
|
declare vf2 mediumint;
|
|
declare vf3 int ;
|
|
declare vf4 real ;
|
|
declare vf5 numeric ;
|
|
declare cur1 cursor for select f1,f2,f3,f4,f5 from t1;
|
|
declare continue handler for sqlstate '02000' set done = 1;
|
|
open cur1;
|
|
while done <> 1 do
|
|
fetch cur1 into vf1, vf2, vf3, vf4, vf5;
|
|
if not done then
|
|
insert into t2 values (vf1, vf2, vf3, vf4, vf5);
|
|
end if;
|
|
end while;
|
|
close cur1;
|
|
end|
|
|
call p1();
|
|
Warnings:
|
|
Error 1329 No data - zero rows fetched, selected, or processed
|
|
select count(*) from t1;
|
|
count(*)
|
|
256
|
|
select count(*) from t2;
|
|
count(*)
|
|
256
|
|
select f1 from t1 limit 1;
|
|
f1
|
|
This is a test case for for Bug#9819
|
|
select f1 from t2 limit 1;
|
|
f1
|
|
This is a test case for for Bug#9819
|
|
drop procedure p1;
|
|
drop table t1, t2;
|