From: Alexander Nozdrin Date: December 15 2010 6:21pm Subject: bzr commit into mysql-trunk-bugfixing branch (alexander.nozdrin:3426) Bug#55843 List-Archive: http://lists.mysql.com/commits/126993 X-Bug: 55843 Message-Id: <201012151824.oBFIOIpL032316@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1260251802102920835==" --===============1260251802102920835== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/alik/MySQL/bzr/00/bug55847/mysql-trunk-bugfixing-bug55847.2/ based on revid:alexander.nozdrin@stripped 3426 Alexander Nozdrin 2010-12-15 A patch for Bug#55843 (Handled condition appears as not handled). Patch for Bug 23032 changed the behavior so that handled condition (sql warning or exception) left in Warning_info. The problem was that handled conditions were treated as unhandled ones, so they were shown as "active statement" warnings. This patch consists of two parts: 1. Refactoring SQL handlers: it changes the way how SQL handlers are found and activated 2. Fix the problem. 1. We used to search handlers recursively (from the current scope up to the top one). That was needed because a search for handlers was done right when an SQL condition occurs. After patch for Bug 23032 the search for SQL handlers happens after SQL statement completes. That means, there is no need to do a recursive search now: - if there are warnings, they are handled by SQL handlers within the current scope only; - if there is an error, it is propagated to the outer scope. 2. The bug fix is to remove conditions, which have SQL handlers from Warning Info. modified: mysql-test/r/signal.result mysql-test/r/signal_demo3.result mysql-test/r/sp-big.result mysql-test/r/sp-bugs.result mysql-test/r/sp-code.result mysql-test/r/sp-error.result mysql-test/r/sp.result mysql-test/r/sp_trans.result mysql-test/r/strict.result mysql-test/r/view.result mysql-test/suite/rpl/r/rpl_row_sp005.result mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result mysql-test/t/sp-error.test sql/sp_head.cc sql/sp_head.h sql/sp_rcontext.cc sql/sp_rcontext.h sql/sql_error.cc sql/sql_error.h sql/sql_signal.cc === modified file 'mysql-test/r/signal.result' --- a/mysql-test/r/signal.result 2010-10-27 10:28:09 +0000 +++ b/mysql-test/r/signal.result 2010-12-15 18:21:04 +0000 @@ -1189,8 +1189,6 @@ end $$ call test_signal() $$ Caught by SQLSTATE Caught by SQLSTATE -Warnings: -Warning 1012 Raising a warning drop procedure test_signal $$ create procedure test_signal() begin @@ -1206,8 +1204,6 @@ end $$ call test_signal() $$ Caught by number Caught by number -Warnings: -Warning 1012 Raising a warning drop procedure test_signal $$ create procedure test_signal() begin @@ -1223,8 +1219,6 @@ end $$ call test_signal() $$ Caught by SQLWARNING Caught by SQLWARNING -Warnings: -Warning 1012 Raising a warning drop procedure test_signal $$ create procedure test_signal() begin @@ -1240,8 +1234,6 @@ end $$ call test_signal() $$ Caught by SQLSTATE Caught by SQLSTATE -Warnings: -Error 1012 Raising a not found drop procedure test_signal $$ create procedure test_signal() begin @@ -1257,8 +1249,6 @@ end $$ call test_signal() $$ Caught by number Caught by number -Warnings: -Error 1012 Raising a not found drop procedure test_signal $$ create procedure test_signal() begin @@ -1274,8 +1264,6 @@ end $$ call test_signal() $$ Caught by NOT FOUND Caught by NOT FOUND -Warnings: -Error 1012 Raising a not found drop procedure test_signal $$ create procedure test_signal() begin @@ -1291,8 +1279,6 @@ end $$ call test_signal() $$ Caught by SQLSTATE Caught by SQLSTATE -Warnings: -Error 1012 Raising an error drop procedure test_signal $$ create procedure test_signal() begin @@ -1308,8 +1294,6 @@ end $$ call test_signal() $$ Caught by number Caught by number -Warnings: -Error 1012 Raising an error drop procedure test_signal $$ create procedure test_signal() begin @@ -1325,8 +1309,6 @@ end $$ call test_signal() $$ Caught by SQLEXCEPTION Caught by SQLEXCEPTION -Warnings: -Error 1012 Raising an error drop procedure test_signal $$ # # Test where SIGNAL can be used @@ -1466,7 +1448,6 @@ after RESIGNAL after RESIGNAL Warnings: Warning 1012 Raising a warning -Warning 1012 Raising a warning drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1521,7 +1502,6 @@ after RESIGNAL after RESIGNAL Warnings: Warning 1264 Out of range value for column 'a' at row 1 -Warning 1264 Out of range value for column 'a' at row 1 drop procedure test_resignal $$ create procedure test_resignal() begin @@ -1578,7 +1558,6 @@ before RESIGNAL after RESIGNAL after RESIGNAL Warnings: -Warning 1012 Raising a warning Warning 5555 RESIGNAL of a warning drop procedure test_resignal $$ create procedure test_resignal() @@ -1639,7 +1618,6 @@ before RESIGNAL after RESIGNAL after RESIGNAL Warnings: -Warning 1264 Out of range value for column 'a' at row 1 Warning 5555 RESIGNAL of a warning drop procedure test_resignal $$ create procedure test_resignal() @@ -2141,9 +2119,6 @@ CALL peter_p2() $$ ERROR 42000: Hi, I am a useless error message show warnings $$ Level Code Message -Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' -Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' -Error 9999 Variable 'sql_mode' can't be set to the value of 'NULL' Error 9999 Hi, I am a useless error message drop procedure peter_p1 $$ drop procedure peter_p2 $$ @@ -2188,18 +2163,15 @@ CALL peter_p2() $$ 1 1 Level Code Message -Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' 2 2 Level Code Message Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' -Error 1232 Variable 'sql_mode' can't be set to the value of 'NULL' 3 3 Level Code Message Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' Error 1232 Variable 'sql_mode' can't be set to the value of 'NULL' -Error 9999 Variable 'sql_mode' can't be set to the value of 'NULL' ERROR 42000: Hi, I am a useless error message show warnings $$ Level Code Message === modified file 'mysql-test/r/signal_demo3.result' --- a/mysql-test/r/signal_demo3.result 2010-08-30 06:38:09 +0000 +++ b/mysql-test/r/signal_demo3.result 2010-12-15 18:21:04 +0000 @@ -95,11 +95,11 @@ call proc_1(); ERROR 45000: Oops in proc_1 show warnings; Level Code Message -Error 1051 Unknown table 'demo.oops_it_is_not_here' -Error 1644 Oops in proc_9 -Error 1644 Oops in proc_8 -Error 1644 Oops in proc_7 -Error 1644 Oops in proc_6 +Error 1644 Oops in proc_5 +Error 1644 Oops in proc_4 +Error 1644 Oops in proc_3 +Error 1644 Oops in proc_2 +Error 1644 Oops in proc_1 SET @@session.max_error_count = 7; SELECT @@session.max_error_count; @@session.max_error_count @@ -108,13 +108,13 @@ call proc_1(); ERROR 45000: Oops in proc_1 show warnings; Level Code Message -Error 1051 Unknown table 'demo.oops_it_is_not_here' -Error 1644 Oops in proc_9 -Error 1644 Oops in proc_8 Error 1644 Oops in proc_7 Error 1644 Oops in proc_6 Error 1644 Oops in proc_5 Error 1644 Oops in proc_4 +Error 1644 Oops in proc_3 +Error 1644 Oops in proc_2 +Error 1644 Oops in proc_1 SET @@session.max_error_count = 9; SELECT @@session.max_error_count; @@session.max_error_count @@ -123,7 +123,6 @@ call proc_1(); ERROR 45000: Oops in proc_1 show warnings; Level Code Message -Error 1051 Unknown table 'demo.oops_it_is_not_here' Error 1644 Oops in proc_9 Error 1644 Oops in proc_8 Error 1644 Oops in proc_7 @@ -132,6 +131,7 @@ Error 1644 Oops in proc_5 Error 1644 Oops in proc_4 Error 1644 Oops in proc_3 Error 1644 Oops in proc_2 +Error 1644 Oops in proc_1 drop database demo; SET @@global.max_error_count = @start_global_value; SELECT @@global.max_error_count; === modified file 'mysql-test/r/sp-big.result' --- a/mysql-test/r/sp-big.result 2010-07-30 15:28:36 +0000 +++ b/mysql-test/r/sp-big.result 2010-12-15 18:21:04 +0000 @@ -46,8 +46,6 @@ end while; close cur1; end| call p1(); -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select count(*) from t1; count(*) 256 === modified file 'mysql-test/r/sp-bugs.result' --- a/mysql-test/r/sp-bugs.result 2010-11-11 05:06:16 +0000 +++ b/mysql-test/r/sp-bugs.result 2010-12-15 18:21:04 +0000 @@ -43,8 +43,6 @@ END| SELECT f2 (); f2 () NULL -Warnings: -Error 1305 FUNCTION testdb.f_not_exists does not exist DROP SCHEMA testdb; USE test; # === modified file 'mysql-test/r/sp-code.result' --- a/mysql-test/r/sp-code.result 2010-07-30 15:28:36 +0000 +++ b/mysql-test/r/sp-code.result 2010-12-15 18:21:04 +0000 @@ -711,8 +711,6 @@ looping i looping 1 looping i looping 0 -Warnings: -Error 1062 Duplicate entry '1' for key 'a' call proc_26977_works(2); do something do something @@ -732,8 +730,6 @@ looping i looping 0 optimizer: keep hreturn optimizer: keep hreturn -Warnings: -Error 1062 Duplicate entry '2' for key 'a' drop table t1; drop procedure proc_26977_broken; drop procedure proc_26977_works; @@ -928,20 +924,16 @@ CALL p1(); Warning found! Warning found! Level Code Message -Warning 1105 Unknown error Warning found! Warning found! Level Code Message -Warning 1105 Unknown error Warning found! Warning found! Level Code Message -Warning 1105 Unknown error End of Result Set found! End of Result Set found! Level Code Message Warning 1105 Unknown error -Error 1329 No data - zero rows fetched, selected, or processed SET SESSION debug="-d,bug23032_emit_warning"; DROP PROCEDURE p1; DROP TABLE t1; === modified file 'mysql-test/r/sp-error.result' --- a/mysql-test/r/sp-error.result 2010-10-27 10:28:09 +0000 +++ b/mysql-test/r/sp-error.result 2010-12-15 18:21:04 +0000 @@ -1344,8 +1344,6 @@ set @in_func := 0; select func_20713_a(); func_20713_a() NULL -Warnings: -Error 1146 Table 'test.bogus_table_20713' doesn't exist select @in_func; @in_func 2 @@ -1353,8 +1351,6 @@ set @in_func := 0; select func_20713_b(); func_20713_b() NULL -Warnings: -Error 1146 Table 'test.bogus_table_20713' doesn't exist select @in_func; @in_func 2 @@ -1754,77 +1750,103 @@ DROP PROCEDURE p2; # - Case 2 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a INT); CREATE PROCEDURE p1() BEGIN DECLARE c INT DEFAULT 0; -DECLARE CONTINUE HANDLER FOR SQLWARNING SET c = c + 1; -CALL p2(); -CALL p3(); -CALL p4(); +DECLARE CONTINUE HANDLER FOR SQLWARNING +BEGIN +SET c = c + 1; +SELECT 'Warning caught!' AS Msg; +END; +CALL p2(); # 1 warning +CALL p3(); # 1 warning +CALL p4(); # No warnings +CALL p5(); # 1 warning SELECT c; SELECT @@warning_count; SHOW WARNINGS; END| CREATE PROCEDURE p2() BEGIN -SELECT CAST('10 ' as unsigned integer); +SELECT CAST('2 ' as unsigned integer); END| CREATE PROCEDURE p3() BEGIN -SELECT CAST('10 ' as unsigned integer); -SELECT 1; +SELECT CAST('3 ' as unsigned integer); +SELECT 1; # does not clear the warning END| CREATE PROCEDURE p4() BEGIN -SELECT CAST('10 ' as unsigned integer); -CALL p2(); +SELECT CAST('4 ' as unsigned integer); +INSERT INTO t1 VALUES(1); # Clears the warning END| CREATE PROCEDURE p5() BEGIN -SELECT CAST('10 ' as unsigned integer); +SELECT CAST('5 ' as unsigned integer); +CALL p2(); +END| +CREATE PROCEDURE p6() +BEGIN +SELECT CAST('6 ' as unsigned integer); SHOW WARNINGS; END| -CREATE PROCEDURE P6() +CREATE PROCEDURE p7() BEGIN DECLARE c INT DEFAULT 0; -DECLARE CONTINUE HANDLER FOR SQLWARNING SET c = c + 1; -CALL p5(); +DECLARE CONTINUE HANDLER FOR SQLWARNING +BEGIN +SET c = c + 1; +SELECT 'Warning caught!' AS Msg; +END; +CALL p6(); SELECT c; END| + CALL p1(); -CAST('10 ' as unsigned integer) -10 -CAST('10 ' as unsigned integer) -10 +CAST('2 ' as unsigned integer) +2 +Msg +Warning caught! +CAST('3 ' as unsigned integer) +3 1 1 -CAST('10 ' as unsigned integer) -10 -CAST('10 ' as unsigned integer) -10 +Msg +Warning caught! +CAST('4 ' as unsigned integer) +4 +CAST('5 ' as unsigned integer) +5 +CAST('2 ' as unsigned integer) +2 +Msg +Warning caught! c 3 @@warning_count -1 +0 Level Code Message -Warning 1292 Truncated incorrect INTEGER value: '10 ' -Warnings: -Warning 1292 Truncated incorrect INTEGER value: '10 ' -CALL p6(); -CAST('10 ' as unsigned integer) -10 + +CALL p7(); +CAST('6 ' as unsigned integer) +6 Level Code Message -Warning 1292 Truncated incorrect INTEGER value: '10 ' +Warning 1292 Truncated incorrect INTEGER value: '6 ' +Msg +Warning caught! c 1 -Warnings: -Warning 1292 Truncated incorrect INTEGER value: '10 ' + DROP PROCEDURE p1; DROP PROCEDURE p2; DROP PROCEDURE p3; DROP PROCEDURE p4; DROP PROCEDURE p5; DROP PROCEDURE p6; +DROP PROCEDURE p7; +DROP TABLE t1; # - Case 3: check that "Exception trumps No Data". @@ -1871,7 +1893,6 @@ exception exception Warnings: Warning 1292 Truncated incorrect INTEGER value: '10 ' -Error 1048 Column 'b' cannot be null DROP TABLE t1; DROP PROCEDURE p1; # @@ -1915,11 +1936,8 @@ CALL p1(); NULL warning caught (expected) warning caught (expected) -Warnings: -Warning 1365 Division by 0 SHOW WARNINGS; Level Code Message -Warning 1365 Division by 0 CALL p2(); 5 / 0 NULL === modified file 'mysql-test/r/sp.result' --- a/mysql-test/r/sp.result 2010-11-10 11:26:45 +0000 +++ b/mysql-test/r/sp.result 2010-12-15 18:21:04 +0000 @@ -737,8 +737,6 @@ close c; end| insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14)| call cur1()| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select * from t1| id data foo 40 @@ -774,8 +772,6 @@ close c1; close c2; end| call cur2()| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select * from t3 order by i,s| s i bar 3 @@ -865,8 +861,6 @@ end$ set @@sql_mode = ''| set sql_select_limit = 1| call modes(@c1, @c2)| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed set sql_select_limit = default| select @c1, @c2| @c1 @c2 @@ -1688,64 +1682,42 @@ end| call h_ee()| h_ee Inner (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' call h_es()| h_es Outer (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' call h_en()| h_en Outer (good) -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed call h_ew()| h_ew Outer (good) call h_ex()| h_ex Outer (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' call h_se()| h_se Inner (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' call h_ss()| h_ss Inner (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' call h_sn()| h_sn Outer (good) -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed call h_sw()| h_sw Outer (good) call h_sx()| h_sx Outer (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' call h_ne()| h_ne Inner (good) -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed call h_ns()| h_ns Inner (good) -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed call h_nn()| h_nn Inner (good) -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed call h_we()| h_we Inner (good) @@ -1758,18 +1730,12 @@ Inner (good) call h_xe()| h_xe Inner (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' call h_xs()| h_xs Inner (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' call h_xx()| h_xx Inner (good) -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' drop table t3| drop procedure h_ee| drop procedure h_es| @@ -1918,8 +1884,6 @@ set @x2 = 2; close c1; end| call bug2260()| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select @x2| @x2 2 @@ -2063,8 +2027,6 @@ insert into t3 values (123456789012); insert into t3 values (0); end| call bug2780()| -Warnings: -Warning 1264 Out of range value for column 's1' at row 1 select @x| @x 1 @@ -2487,8 +2449,6 @@ declare continue handler for sqlstate 'H select s1 from t3 union select s2 from t3; end| call bug4904()| -Warnings: -Error 1267 Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin2_general_ci,IMPLICIT) for operation 'UNION' drop procedure bug4904| drop table t3| drop procedure if exists bug336| @@ -2628,17 +2588,13 @@ select row_count()| row_count() 1 call bug4905()| -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' select row_count()| row_count() --1 +0 call bug4905()| -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' select row_count()| row_count() --1 +0 select * from t3| s1 1 @@ -2659,14 +2615,10 @@ insert into t3 values (1)| call bug6029()| sqlstate 23000 sqlstate 23000 -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' delete from t3| call bug6029()| 1136 1136 -Warnings: -Error 1136 Column count doesn't match value count at row 1 drop procedure bug6029| drop table t3| drop procedure if exists bug8540| @@ -2958,23 +2910,15 @@ end| call bug6900()| 2 2 -Warnings: -Error 1136 Column count doesn't match value count at row 1 call bug9074()| x1 x2 x3 x4 x5 x6 1 1 1 1 1 1 -Warnings: -Error 1062 Duplicate entry 'a' for key 'w' call bug6900_9074(0)| sqlexception sqlexception -Warnings: -Error 1136 Column count doesn't match value count at row 1 call bug6900_9074(1)| 23000 23000 -Warnings: -Error 1062 Duplicate entry 'a' for key 'w' drop procedure bug6900| drop procedure bug9074| drop procedure bug6900_9074| @@ -3017,13 +2961,9 @@ delete from t1| call bug9856()| 16 16 -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed call bug9856()| 16 16 -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed drop procedure bug9856| drop procedure if exists bug9674_1| drop procedure if exists bug9674_2| @@ -3254,8 +3194,6 @@ x 2 x 3 -Warnings: -Error 1326 Cursor is not open call bug10961()| x 1 @@ -3263,8 +3201,6 @@ x 2 x 3 -Warnings: -Error 1326 Cursor is not open drop procedure bug10961| DROP PROCEDURE IF EXISTS bug6866| DROP VIEW IF EXISTS tv| @@ -3380,11 +3316,7 @@ insert into t1 values ('Name4', 13), ('Name5', 14)| call bug11529()| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed call bug11529()| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed delete from t1| drop procedure bug11529| set character set utf8| @@ -3558,32 +3490,24 @@ end; end if; end| call bug12168('a')| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select * from t4| a 1 3 truncate t4| call bug12168('b')| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select * from t4| a 2 4 truncate t4| call bug12168('a')| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select * from t4| a 1 3 truncate t4| call bug12168('b')| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select * from t4| a 2 @@ -3883,8 +3807,6 @@ end| call bug7049_2()| Result Caught it -Warnings: -Error 1062 Duplicate entry '42' for key 'x' select * from t3| x 42 @@ -3892,16 +3814,12 @@ delete from t3| call bug7049_4()| Result Caught it -Warnings: -Error 1062 Duplicate entry '42' for key 'x' select * from t3| x 42 select bug7049_2()| bug7049_2() 1 -Warnings: -Error 1062 Duplicate entry '42' for key 'x' drop table t3| drop procedure bug7049_1| drop procedure bug7049_2| @@ -4029,8 +3947,6 @@ end| call bug14845()| a 0 -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed drop procedure bug14845| drop procedure if exists bug13549_1| drop procedure if exists bug13549_2| @@ -4234,8 +4150,6 @@ end| call bug13729()| 55 55 -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' select * from t3| s1 1 @@ -4272,15 +4186,11 @@ Handler boo v isnull(v) NULL 1 -Warnings: -Error 1054 Unknown column 'undefined_var' in 'field list' call bug14643_2()| Handler boo Handler boo -Warnings: -Error 1054 Unknown column 'undefined_var' in 'field list' drop procedure bug14643_1| drop procedure bug14643_2| drop procedure if exists bug14304| @@ -4604,15 +4514,11 @@ Handler error End done -Warnings: -Error 1054 Unknown column 'v' in 'field list' call bug14498_2()| Handler error End done -Warnings: -Error 1054 Unknown column 'v' in 'field list' call bug14498_3()| v maybe @@ -4620,22 +4526,16 @@ Handler error End done -Warnings: -Error 1054 Unknown column 'v' in 'field list' call bug14498_4()| Handler error End done -Warnings: -Error 1054 Unknown column 'v' in 'field list' call bug14498_5()| Handler error End done -Warnings: -Error 1054 Unknown column 'v' in 'field list' drop procedure bug14498_1| drop procedure bug14498_2| drop procedure bug14498_3| @@ -4700,8 +4600,6 @@ Before NOT FOUND condition is triggered After NOT FOUND condtition is triggered xid xdone 1 1 -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed call bug15231_3()| Result Missed it (correct) @@ -4709,8 +4607,6 @@ Level Code Message Warning 1366 Incorrect decimal value: 'zap' for column 'x' at row 1 Result Caught it (correct) -Warnings: -Warning 1366 Incorrect decimal value: 'zap' for column 'x' at row 1 call bug15231_5()| Result Missed it (correct) @@ -4739,8 +4635,6 @@ end| call bug15011()| Handler Inner -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' drop procedure bug15011| drop table t3| drop procedure if exists bug17476| @@ -4816,8 +4710,6 @@ i 1 i 0 -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed drop table t3| drop procedure bug16887| drop procedure if exists bug16474_1| @@ -4890,8 +4782,6 @@ declare continue handler for sqlexceptio select no_such_function(); end| call bug18787()| -Warnings: -Error 1305 FUNCTION test.no_such_function does not exist drop procedure bug18787| create database bug18344_012345678901| use bug18344_012345678901| @@ -5265,8 +5155,6 @@ statement failed statement failed statement after update statement after update -Warnings: -Error 1242 Subquery returns more than 1 row select * from t3| a 1 @@ -5278,8 +5166,6 @@ statement failed statement failed statement after update statement after update -Warnings: -Error 1242 Subquery returns more than 1 row select * from t3| a 1 @@ -5312,8 +5198,6 @@ in continue handler in continue handler reachable code a2 reachable code a2 -Warnings: -Error 1242 Subquery returns more than 1 row select * from t3| a 1 @@ -5329,8 +5213,6 @@ in continue handler in continue handler reachable code a2 reachable code a2 -Warnings: -Error 1242 Subquery returns more than 1 row select * from t3| a 1 @@ -5364,8 +5246,6 @@ in continue handler in continue handler reachable code a2 reachable code a2 -Warnings: -Error 1305 FUNCTION test.no_such_function does not exist drop procedure bug8153_proc_a| drop procedure bug8153_proc_b| drop table t3| @@ -5934,13 +5814,9 @@ end| select func_8407_a()| func_8407_a() NULL -Warnings: -Error 1146 Table 'test.no_such_view' doesn't exist select func_8407_b()| func_8407_b() 1500 -Warnings: -Error 1146 Table 'test.no_such_view' doesn't exist drop function func_8407_a| drop function func_8407_b| drop table if exists table_26503| @@ -6062,8 +5938,6 @@ looping i looping 0 leaving handler leaving handler -Warnings: -Error 1062 Duplicate entry '1' for key 'a' call proc_26503_ok_2(2)| do something do something @@ -6075,8 +5949,6 @@ looping i looping 4 leaving handler leaving handler -Warnings: -Error 1062 Duplicate entry '2' for key 'a' call proc_26503_ok_3(3)| do something do something @@ -6096,8 +5968,6 @@ looping i looping 0 leaving handler leaving handler -Warnings: -Error 1062 Duplicate entry '3' for key 'a' call proc_26503_ok_4(4)| do something do something @@ -6109,8 +5979,6 @@ looping i looping 4 leaving handler leaving handler -Warnings: -Error 1062 Duplicate entry '4' for key 'a' drop table table_26503| drop procedure proc_26503_ok_1| drop procedure proc_26503_ok_2| @@ -6824,8 +6692,6 @@ DECLARE CONTINUE HANDLER FOR SQLEXCEPTIO SELECT x FROM t1; END| CALL bug29770(); -Warnings: -Error 1054 Unknown column 'x' in 'field list' SELECT @state, @exception; @state @exception run NULL @@ -6864,8 +6730,6 @@ end; end while; end// call proc_33618(20); -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed drop table t_33618; drop procedure proc_33618; # === modified file 'mysql-test/r/sp_trans.result' --- a/mysql-test/r/sp_trans.result 2010-10-07 12:47:15 +0000 +++ b/mysql-test/r/sp_trans.result 2010-12-15 18:21:04 +0000 @@ -99,8 +99,6 @@ return i; end| set @error_in_func:= 0| insert into t1 values (bug10015_6(5)), (bug10015_6(6))| -Warnings: -Error 1062 Duplicate entry '1' for key 'PRIMARY' select @error_in_func| @error_in_func 1 @@ -526,8 +524,6 @@ until done end repeat; close c; end| call bug14210()| -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed select count(*) from t4| count(*) 256 === modified file 'mysql-test/r/strict.result' --- a/mysql-test/r/strict.result 2010-09-07 06:45:00 +0000 +++ b/mysql-test/r/strict.result 2010-12-15 18:21:04 +0000 @@ -1193,8 +1193,6 @@ select'a'; insert into t1 values (200); call t1(); a a -Warnings: -Error 1264 Out of range value for column 'col1' at row 1 select * from t1; col1 drop procedure t1; === modified file 'mysql-test/r/view.result' --- a/mysql-test/r/view.result 2010-12-03 09:18:23 +0000 +++ b/mysql-test/r/view.result 2010-12-15 18:21:04 +0000 @@ -3948,8 +3948,6 @@ create view a as select 1; end| call p(); call p(); -Warnings: -Error 1050 Table 'a' already exists drop view a; drop procedure p; # === modified file 'mysql-test/suite/rpl/r/rpl_row_sp005.result' --- a/mysql-test/suite/rpl/r/rpl_row_sp005.result 2010-07-30 15:28:36 +0000 +++ b/mysql-test/suite/rpl/r/rpl_row_sp005.result 2010-12-15 18:21:04 +0000 @@ -77,8 +77,6 @@ id2 < ---- Master selects-- > ------------------------- CALL test.p1(); -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed SELECT * FROM test.t3 ORDER BY id3; id3 c 1 MySQL === modified file 'mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result' --- a/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result 2010-07-30 15:28:36 +0000 +++ b/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result 2010-12-15 18:21:04 +0000 @@ -38,8 +38,6 @@ INSERT INTO t1 VALUES ('MySQL','1993-02- END| CALL p2(); CALL p1(); -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed DROP TABLE t1; DROP TABLE t2; DROP PROCEDURE p1; === modified file 'mysql-test/t/sp-error.test' --- a/mysql-test/t/sp-error.test 2010-10-26 11:48:08 +0000 +++ b/mysql-test/t/sp-error.test 2010-12-15 18:21:04 +0000 @@ -2585,15 +2585,26 @@ DROP PROCEDURE p2; --echo # - Case 2 --echo +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(a INT); + delimiter |; CREATE PROCEDURE p1() BEGIN DECLARE c INT DEFAULT 0; - DECLARE CONTINUE HANDLER FOR SQLWARNING SET c = c + 1; - CALL p2(); - CALL p3(); - CALL p4(); + DECLARE CONTINUE HANDLER FOR SQLWARNING + BEGIN + SET c = c + 1; + SELECT 'Warning caught!' AS Msg; + END; + CALL p2(); # 1 warning + CALL p3(); # 1 warning + CALL p4(); # No warnings + CALL p5(); # 1 warning SELECT c; SELECT @@warning_count; SHOW WARNINGS; @@ -2601,39 +2612,54 @@ CREATE PROCEDURE p1() CREATE PROCEDURE p2() BEGIN - SELECT CAST('10 ' as unsigned integer); - END| + SELECT CAST('2 ' as unsigned integer); + END| # 1 warning is passed to the caller CREATE PROCEDURE p3() BEGIN - SELECT CAST('10 ' as unsigned integer); - SELECT 1; - END| + SELECT CAST('3 ' as unsigned integer); + SELECT 1; # does not clear the warning + END| # 1 warning is passed to the caller CREATE PROCEDURE p4() BEGIN - SELECT CAST('10 ' as unsigned integer); + SELECT CAST('4 ' as unsigned integer); + INSERT INTO t1 VALUES(1); # Clears the warning + END| # No warnings to pass + +CREATE PROCEDURE p5() + BEGIN + SELECT CAST('5 ' as unsigned integer); CALL p2(); END| -CREATE PROCEDURE p5() +CREATE PROCEDURE p6() BEGIN - SELECT CAST('10 ' as unsigned integer); + SELECT CAST('6 ' as unsigned integer); SHOW WARNINGS; END| -CREATE PROCEDURE P6() +CREATE PROCEDURE p7() BEGIN DECLARE c INT DEFAULT 0; - DECLARE CONTINUE HANDLER FOR SQLWARNING SET c = c + 1; - CALL p5(); + DECLARE CONTINUE HANDLER FOR SQLWARNING + BEGIN + SET c = c + 1; + SELECT 'Warning caught!' AS Msg; + END; + CALL p6(); SELECT c; END| delimiter ;| +--echo CALL p1(); -CALL p6(); + +--echo +CALL p7(); + +--echo DROP PROCEDURE p1; DROP PROCEDURE p2; @@ -2641,6 +2667,9 @@ DROP PROCEDURE p3; DROP PROCEDURE p4; DROP PROCEDURE p5; DROP PROCEDURE p6; +DROP PROCEDURE p7; + +DROP TABLE t1; --echo --echo # - Case 3: check that "Exception trumps No Data". === modified file 'sql/sp_head.cc' --- a/sql/sp_head.cc 2010-12-14 15:02:19 +0000 +++ b/sql/sp_head.cc 2010-12-15 18:21:04 +0000 @@ -1076,104 +1076,6 @@ void sp_head::recursion_level_error(THD /** - Find an SQL handler for any condition (warning or error) after execution - of a stored routine instruction. Basically, this function looks for an - appropriate SQL handler in RT-contexts. If an SQL handler is found, it is - remembered in the RT-context for future activation (the context can be - inactive at the moment). - - If there is no pending condition, the function just returns. - - If there was an error during the execution, an SQL handler for it will be - searched within the current and outer scopes. - - There might be several errors in the Warning Info (that's possible by using - SIGNAL/RESIGNAL in nested scopes) -- the function is looking for an SQL - handler for the latest (current) error only. - - If there was a warning during the execution, an SQL handler for it will be - searched within the current scope only. - - If several warnings were thrown during the execution and there are different - SQL handlers for them, it is not determined which SQL handler will be chosen. - Only one SQL handler will be executed. - - If warnings and errors were thrown during the execution, the error takes - precedence. I.e. error handler will be executed. If there is no handler - for that error, condition will remain unhandled. - - Once a warning or an error has been handled it is not removed from - Warning Info. - - According to The Standard (quoting PeterG): - - An SQL procedure statement works like this ... - SQL/Foundation 13.5 - (General Rules) (greatly summarized) says: - (1) Empty diagnostics area, thus clearing the condition. - (2) Execute statement. - During execution, if Exception Condition occurs, - set Condition Area = Exception Condition and stop - statement. - During execution, if No Data occurs, - set Condition Area = No Data Condition and continue - statement. - During execution, if Warning occurs, - and Condition Area is not already full due to - an earlier No Data condition, set Condition Area - = Warning and continue statement. - (3) Finish statement. - At end of execution, if Condition Area is not - already full due to an earlier No Data or Warning, - set Condition Area = Successful Completion. - In effect, this system means there is a precedence: - Exception trumps No Data, No Data trumps Warning, - Warning trumps Successful Completion. - - NB: "Procedure statements" include any DDL or DML or - control statements. So CREATE and DELETE and WHILE - and CALL and RETURN are procedure statements. But - DECLARE and END are not procedure statements. - - @param thd thread handle - @param ctx runtime context of the stored routine -*/ - -static void -find_handler_after_execution(THD *thd, sp_rcontext *ctx) -{ - if (thd->is_error()) - { - ctx->find_handler(thd, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->get_sqlstate(), - MYSQL_ERROR::WARN_LEVEL_ERROR, - thd->get_stmt_da()->message()); - } - else if (thd->get_warning_info()->statement_warn_count()) - { - List_iterator it(thd->get_warning_info()->warn_list()); - MYSQL_ERROR *err; - while ((err= it++)) - { - if (err->get_level() != MYSQL_ERROR::WARN_LEVEL_WARN && - err->get_level() != MYSQL_ERROR::WARN_LEVEL_NOTE) - continue; - - if (ctx->find_handler(thd, - err->get_sql_errno(), - err->get_sqlstate(), - err->get_level(), - err->get_message_text())) - { - break; - } - } - } -} - - -/** Execute the routine. The main instruction jump loop is there. Assume the parameters already set. @@ -1438,19 +1340,10 @@ sp_head::execute(THD *thd, bool merge_da errors are not catchable by SQL handlers) or the connection has been killed during execution. */ - if (!thd->is_fatal_error && !thd->killed_errno()) + if (!thd->is_fatal_error && !thd->killed_errno() && + ctx->handle_sql_condition(thd, &ip, i, &execute_arena, &backup_arena)) { - /* - Find SQL handler in the appropriate RT-contexts: - - warnings can be handled by SQL handlers within - the current scope only; - - errors can be handled by any SQL handler from outer scope. - */ - find_handler_after_execution(thd, ctx); - - /* If found, activate handler for the current scope. */ - if (ctx->activate_handler(thd, &ip, i, &execute_arena, &backup_arena)) - err_status= FALSE; + err_status= FALSE; } /* Reset sp_rcontext::end_partial_result_set flag. */ @@ -1705,7 +1598,7 @@ sp_head::execute_trigger(THD *thd, init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0); thd->set_n_backup_active_arena(&call_arena, &backup_arena); - if (!(nctx= new sp_rcontext(m_pcont, 0, octx)) || + if (!(nctx= new sp_rcontext(m_pcont, NULL)) || nctx->init(thd)) { err_status= TRUE; @@ -1822,7 +1715,7 @@ sp_head::execute_function(THD *thd, Item init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0); thd->set_n_backup_active_arena(&call_arena, &backup_arena); - if (!(nctx= new sp_rcontext(m_pcont, return_value_fld, octx)) || + if (!(nctx= new sp_rcontext(m_pcont, return_value_fld)) || nctx->init(thd)) { thd->restore_active_arena(&call_arena, &backup_arena); @@ -2040,7 +1933,7 @@ sp_head::execute_procedure(THD *thd, Lis if (! octx) { /* Create a temporary old context. */ - if (!(octx= new sp_rcontext(m_pcont, NULL, octx)) || octx->init(thd)) + if (!(octx= new sp_rcontext(m_pcont, NULL)) || octx->init(thd)) { delete octx; /* Delete octx if it was init() that failed. */ DBUG_RETURN(TRUE); @@ -2055,7 +1948,7 @@ sp_head::execute_procedure(THD *thd, Lis thd->spcont->callers_arena= thd; } - if (!(nctx= new sp_rcontext(m_pcont, NULL, octx)) || + if (!(nctx= new sp_rcontext(m_pcont, NULL)) || nctx->init(thd)) { delete nctx; /* Delete nctx if it was init() that failed. */ @@ -3050,7 +2943,7 @@ int sp_instr::exec_open_and_lock_tables( return result; } -uint sp_instr::get_cont_dest() +uint sp_instr::get_cont_dest() const { return (m_ip+1); } @@ -3261,7 +3154,7 @@ sp_instr_set_trigger_field::print(String sp_instr_opt_meta */ -uint sp_instr_opt_meta::get_cont_dest() +uint sp_instr_opt_meta::get_cont_dest() const { return m_cont_dest; } === modified file 'sql/sp_head.h' --- a/sql/sp_head.h 2010-11-29 16:27:58 +0000 +++ b/sql/sp_head.h 2010-12-15 18:21:04 +0000 @@ -599,7 +599,7 @@ public: Get the continuation destination of this instruction. @return the continuation destination */ - virtual uint get_cont_dest(); + virtual uint get_cont_dest() const; /* Execute core function of instruction after all preparations (e.g. @@ -871,7 +871,7 @@ public: virtual void set_destination(uint old_dest, uint new_dest) = 0; - virtual uint get_cont_dest(); + virtual uint get_cont_dest() const; protected: === modified file 'sql/sp_rcontext.cc' --- a/sql/sp_rcontext.cc 2010-07-30 15:30:30 +0000 +++ b/sql/sp_rcontext.cc 2010-12-15 18:21:04 +0000 @@ -27,8 +27,7 @@ #include "sql_select.h" // create_virtual_tmp_table sp_rcontext::sp_rcontext(sp_pcontext *root_parsing_ctx, - Field *return_value_fld, - sp_rcontext *prev_runtime_ctx) + Field *return_value_fld) :end_partial_result_set(FALSE), m_root_parsing_ctx(root_parsing_ctx), m_var_table(0), @@ -39,10 +38,8 @@ sp_rcontext::sp_rcontext(sp_pcontext *ro m_hcount(0), m_hsp(0), m_ihsp(0), - m_hfound(-1), m_ccount(0), - m_case_expr_holders(0), - m_prev_runtime_ctx(prev_runtime_ctx) + m_case_expr_holders(0) { } @@ -172,7 +169,7 @@ sp_rcontext::set_return_value(THD *thd, #define IS_EXCEPTION_CONDITION(S) ((S)[0] != '0' || (S)[1] > '2') /** - Find an SQL handler for the given error. + Find an SQL handler for the given SQL condition. SQL handlers are pushed on the stack m_handler, with the latest/innermost one on the top; we then search for matching handlers from the top and @@ -183,39 +180,25 @@ sp_rcontext::set_return_value(THD *thd, Note that mysql error code handlers is a MySQL extension, not part of the standard. - SQL handlers for warnings are searched in the current scope only. - - SQL handlers for errors are searched in the current and in outer scopes. - That's why finding and activation of handler must be separated: an errror - handler might be located in the outer scope, which is not active at the - moment. Before such handler can be activated, execution flow should - unwind to that scope. - - Found SQL handler is remembered in m_hfound for future activation. - If no handler is found, m_hfound is -1. - @param thd Thread handle @param sql_errno The error code @param sqlstate The error SQL state @param level The error level @param msg The error message - @retval TRUE if an SQL handler was found - @retval FALSE otherwise + @return SQL handler index, or -1 if there is no handler. */ -bool +int sp_rcontext::find_handler(THD *thd, uint sql_errno, const char *sqlstate, MYSQL_ERROR::enum_warning_level level, const char *msg) { + int hfound= -1; int i= m_hcount; - /* Reset previously found handler. */ - m_hfound= -1; - /* If this is a fatal sub-statement error, and this runtime context corresponds to a sub-statement, no CONTINUE/EXIT @@ -242,56 +225,42 @@ sp_rcontext::find_handler(THD *thd, { case sp_cond_type_t::number: if (sql_errno == cond->mysqlerr && - (m_hfound < 0 || m_handler[m_hfound].cond->type > sp_cond_type_t::number)) - m_hfound= i; // Always the most specific + (hfound < 0 || m_handler[hfound].cond->type > sp_cond_type_t::number)) + hfound= i; // Always the most specific break; case sp_cond_type_t::state: if (strcmp(sqlstate, cond->sqlstate) == 0 && - (m_hfound < 0 || m_handler[m_hfound].cond->type > sp_cond_type_t::state)) - m_hfound= i; + (hfound < 0 || m_handler[hfound].cond->type > sp_cond_type_t::state)) + hfound= i; break; case sp_cond_type_t::warning: if ((IS_WARNING_CONDITION(sqlstate) || level == MYSQL_ERROR::WARN_LEVEL_WARN) && - m_hfound < 0) - m_hfound= i; + hfound < 0) + hfound= i; break; case sp_cond_type_t::notfound: - if (IS_NOT_FOUND_CONDITION(sqlstate) && m_hfound < 0) - m_hfound= i; + if (IS_NOT_FOUND_CONDITION(sqlstate) && hfound < 0) + hfound= i; break; case sp_cond_type_t::exception: if (IS_EXCEPTION_CONDITION(sqlstate) && level == MYSQL_ERROR::WARN_LEVEL_ERROR && - m_hfound < 0) - m_hfound= i; + hfound < 0) + hfound= i; break; } } - if (m_hfound >= 0) + if (hfound >= 0) { - DBUG_ASSERT((uint) m_hfound < m_root_parsing_ctx->max_handler_index()); - - m_raised_conditions[m_hfound].clear(); - m_raised_conditions[m_hfound].set(sql_errno, sqlstate, level, msg); - - return TRUE; - } + DBUG_ASSERT((uint) hfound < m_root_parsing_ctx->max_handler_index()); - /* - Only "exception conditions" are propagated to handlers in calling - contexts. If no handler is found locally for a "completion condition" - (warning or "not found") we will simply resume execution. - */ - if (m_prev_runtime_ctx && IS_EXCEPTION_CONDITION(sqlstate) && - level == MYSQL_ERROR::WARN_LEVEL_ERROR) - { - return m_prev_runtime_ctx->find_handler(thd, sql_errno, sqlstate, - level, msg); + m_raised_conditions[hfound].clear(); + m_raised_conditions[hfound].set(sql_errno, sqlstate, level, msg); } - return FALSE; + return hfound; } void @@ -370,31 +339,187 @@ sp_rcontext::pop_hstack() } /** - Prepare found handler to be executed. + Handle current SQL condition (if any). - @retval TRUE if an SQL handler is activated (was found) and IP of the - first handler instruction. - @retval FALSE if there is no active handler + This is the public-interface function to handle SQL conditions in stored + routines. + + @param thd Thread handle. + @param ip[out] Instruction pointer to the first handler instruction. + @param cur_spi Current SP instruction. + @param execute_arena Current execution arena for SP. + @param backup_arena Backup arena for SP. */ bool +sp_rcontext::handle_sql_condition(THD *thd, + uint *ip, + const sp_instr *cur_spi, + Query_arena *execute_arena, + Query_arena *backup_arena) +{ + int handler_idx= find_handler(thd); + + if (handler_idx < 0) + return FALSE; + + activate_handler(thd, handler_idx, ip, cur_spi, execute_arena, backup_arena); + + return TRUE; +} + + +/** + Find an SQL handler for any condition (warning or error) after execution + of a stored routine instruction. Basically, this function does two: + - looks for an appropriate SQL handler in the current RT-context; + - removes handled SQL condition from Warning Info. + + If there is no pending condition, the function just returns. + + There might be several errors in the Warning Info (that's possible by using + SIGNAL/RESIGNAL in nested scopes) -- the function is looking for an SQL + handler for the latest (current) error only. + + If several warnings were thrown during the execution and there are different + SQL handlers for them, it is not determined which SQL handler will be chosen. + Only one SQL handler will be executed. + + If warnings and errors were thrown during the execution, the error takes + precedence. I.e. error handler will be executed. If there is no handler + for that error, condition will remain unhandled. + + Once a warning or an error has been handled it is removed from + Warning Info. + + According to The Standard (quoting PeterG): + + An SQL procedure statement works like this ... + SQL/Foundation 13.5 + (General Rules) (greatly summarized) says: + (1) Empty diagnostics area, thus clearing the condition. + (2) Execute statement. + During execution, if Exception Condition occurs, + set Condition Area = Exception Condition and stop + statement. + During execution, if No Data occurs, + set Condition Area = No Data Condition and continue + statement. + During execution, if Warning occurs, + and Condition Area is not already full due to + an earlier No Data condition, set Condition Area + = Warning and continue statement. + (3) Finish statement. + At end of execution, if Condition Area is not + already full due to an earlier No Data or Warning, + set Condition Area = Successful Completion. + In effect, this system means there is a precedence: + Exception trumps No Data, No Data trumps Warning, + Warning trumps Successful Completion. + + NB: "Procedure statements" include any DDL or DML or + control statements. So CREATE and DELETE and WHILE + and CALL and RETURN are procedure statements. But + DECLARE and END are not procedure statements. + + @param thd thread handle + + @return SQL handler index, or -1 if there is no handler or no pending SQL + condition. +*/ + +int +sp_rcontext::find_handler(THD *thd) +{ + Diagnostics_area *da= thd->get_stmt_da(); + Warning_info *wi= thd->get_warning_info(); + + if (thd->is_error()) + { + + int handler_idx= find_handler(thd, da->sql_errno(), da->get_sqlstate(), + MYSQL_ERROR::WARN_LEVEL_ERROR, da->message()); + if (handler_idx < 0) + return -1; + + MYSQL_ERROR *err_condition= wi->get_error_condition(); + + if (!err_condition) + return -1; + + List_iterator it(wi->warn_list()); + MYSQL_ERROR *err; + + while ((err= it++)) + { + if (err != err_condition) + continue; + + da->remove_warning(err); + it.remove(); + + break; + } + + return handler_idx; + } + else if (wi->statement_warn_count()) + { + List_iterator it(wi->warn_list()); + MYSQL_ERROR *err; + while ((err= it++)) + { + if (err->get_level() != MYSQL_ERROR::WARN_LEVEL_WARN && + err->get_level() != MYSQL_ERROR::WARN_LEVEL_NOTE) + continue; + + int handler_idx= find_handler(thd, + err->get_sql_errno(), + err->get_sqlstate(), + err->get_level(), + err->get_message_text()); + if (handler_idx < 0) + continue; + + da->remove_warning(err); + it.remove(); + + return handler_idx; + } + } + + return -1; +} + +/** + Prepare an SQL handler to be executed. + + @param thd Thread handle. + @param handler_idx Handler index (must be >= 0). + @param ip[out] Instruction pointer to the first handler instruction. + @param cur_spi Current SP instruction. + @param execute_arena Current execution arena for SP. + @param backup_arena Backup arena for SP. +*/ + +void sp_rcontext::activate_handler(THD *thd, + int handler_idx, uint *ip, - sp_instr *instr, + const sp_instr *cur_spi, Query_arena *execute_arena, Query_arena *backup_arena) { - if (m_hfound < 0) - return FALSE; + DBUG_ASSERT(handler_idx >= 0); - switch (m_handler[m_hfound].type) { + switch (m_handler[handler_idx].type) { case SP_HANDLER_NONE: break; case SP_HANDLER_CONTINUE: thd->restore_active_arena(execute_arena, backup_arena); thd->set_n_backup_active_arena(execute_arena, backup_arena); - push_hstack(instr->get_cont_dest()); + push_hstack(cur_spi->get_cont_dest()); /* Fall through */ @@ -407,10 +532,9 @@ sp_rcontext::activate_handler(THD *thd, /* Enter handler. */ DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index()); - DBUG_ASSERT(m_hfound >= 0); - m_in_handler[m_ihsp].ip= m_handler[m_hfound].handler; - m_in_handler[m_ihsp].index= m_hfound; + m_in_handler[m_ihsp].ip= m_handler[handler_idx].handler; + m_in_handler[m_ihsp].index= handler_idx; m_ihsp++; DBUG_PRINT("info", ("Entering handler...")); @@ -423,13 +547,8 @@ sp_rcontext::activate_handler(THD *thd, // (e.g. "bad data"). /* Return IP of the activated SQL handler. */ - *ip= m_handler[m_hfound].handler; - - /* Reset found handler. */ - m_hfound= -1; + *ip= m_handler[handler_idx].handler; } - - return TRUE; } void @@ -456,9 +575,6 @@ sp_rcontext::raised_condition() const return raised; } - if (m_prev_runtime_ctx) - return m_prev_runtime_ctx->raised_condition(); - return NULL; } === modified file 'sql/sp_rcontext.h' --- a/sql/sp_rcontext.h 2010-11-13 15:11:39 +0000 +++ b/sql/sp_rcontext.h 2010-12-15 18:21:04 +0000 @@ -107,8 +107,7 @@ class sp_rcontext : public Sql_alloc sp_head *sp; #endif - sp_rcontext(sp_pcontext *root_parsing_ctx, Field *return_value_fld, - sp_rcontext *prev_runtime_ctx); + sp_rcontext(sp_pcontext *root_parsing_ctx, Field *return_value_fld); bool init(THD *thd); ~sp_rcontext(); @@ -139,13 +138,6 @@ class sp_rcontext : public Sql_alloc void pop_handlers(uint count); - bool - find_handler(THD *thd, - uint sql_errno, - const char *sqlstate, - MYSQL_ERROR::enum_warning_level level, - const char *msg); - MYSQL_ERROR * raised_condition() const; @@ -156,12 +148,11 @@ class sp_rcontext : public Sql_alloc pop_hstack(); bool - activate_handler(THD *thd, - uint *ip, - sp_instr *instr, - Query_arena *execute_arena, - Query_arena *backup_arena); - + handle_sql_condition(THD *thd, + uint *ip, + const sp_instr *cur_spi, + Query_arena *execute_arena, + Query_arena *backup_arena); void exit_handler(); @@ -198,6 +189,25 @@ class sp_rcontext : public Sql_alloc get_case_expr_addr(int case_expr_id); private: + int + find_handler(THD *thd); + + int + find_handler(THD *thd, + uint sql_errno, + const char *sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char *msg); + + void + activate_handler(THD *thd, + int handler_idx, + uint *ip, + const sp_instr *cur_spi, + Query_arena *execute_arena, + Query_arena *backup_arena); + +private: sp_pcontext *m_root_parsing_ctx; /* Virtual table for storing variables. */ @@ -240,16 +250,12 @@ private: /** Active handler stack. */ sp_active_handler_t *m_in_handler; uint m_ihsp; // Stack pointer for m_in_handler - int m_hfound; // Set by find_handler; -1 if not found sp_cursor **m_cstack; uint m_ccount; Item_cache **m_case_expr_holders; - /* Previous runtime context (NULL if none) */ - sp_rcontext *m_prev_runtime_ctx; - private: bool init_var_table(THD *thd); bool init_var_items(); === modified file 'sql/sql_error.cc' --- a/sql/sql_error.cc 2010-12-15 12:00:26 +0000 +++ b/sql/sql_error.cc 2010-12-15 18:21:04 +0000 @@ -505,6 +505,13 @@ void Warning_info::append_warning_info(T } } +void Warning_info::reserve_space(THD *thd, uint count) +{ + /* Make room for count conditions */ + while ((m_warn_list.elements > 0) && + ((m_warn_list.elements + count) > thd->variables.max_error_count)) + m_warn_list.pop(); +} /** Append warnings only if the original contents of the routine @@ -574,6 +581,12 @@ MYSQL_ERROR *Warning_info::push_warning( return cond; } +void Warning_info::remove_warning(const MYSQL_ERROR *sql_condition) +{ + m_warn_count[sql_condition->get_level()]--; + m_statement_warn_count--; +} + MYSQL_ERROR *Warning_info::push_warning(THD *thd, const MYSQL_ERROR *sql_condition) { MYSQL_ERROR *new_condition= push_warning(thd, === modified file 'sql/sql_error.h' --- a/sql/sql_error.h 2010-12-15 12:00:26 +0000 +++ b/sql/sql_error.h 2010-12-15 18:21:04 +0000 @@ -327,6 +327,8 @@ public: ulong statement_warn_count() const { return m_statement_warn_count; } + void reserve_space(THD *thd, uint count); + /** Add a new condition to the current list. */ MYSQL_ERROR *push_warning(THD *thd, uint sql_errno, const char* sqlstate, @@ -367,10 +369,14 @@ public: { m_error_condition= NULL; } private: + void remove_warning(const MYSQL_ERROR *sql_condition); + +private: /** Read only status. */ bool m_read_only; friend class Sql_cmd_resignal; + friend class Diagnostics_area; }; /** @@ -440,6 +446,12 @@ public: return m_statement_warn_count; } + void remove_warning(const MYSQL_ERROR *sql_condition) + { + --m_statement_warn_count; + m_warning_info->remove_warning(sql_condition); + } + Diagnostics_area(Warning_info *warning_info) : m_warning_info(warning_info) { reset_diagnostics_area(); } === modified file 'sql/sql_signal.cc' --- a/sql/sql_signal.cc 2010-12-14 15:02:19 +0000 +++ b/sql/sql_signal.cc 2010-12-15 18:21:04 +0000 @@ -492,14 +492,24 @@ bool Sql_cmd_resignal::execute(THD *thd) DBUG_RETURN(result); } - if (m_cond == NULL) + if (m_cond) { - /* RESIGNAL without signal_value */ - result= raise_condition(thd, signaled); - DBUG_RETURN(result); + MYSQL_ERROR *cond; + + query_cache_abort(&thd->query_cache_tls); + + /* Make room for 2 conditions. */ + thd->get_warning_info()->reserve_space(thd, 2); + + cond= thd->get_warning_info()->push_warning(thd, + signaled->get_sql_errno(), + signaled->get_sqlstate(), + signaled->get_level(), + signaled->get_message_text()); + if (cond) + cond->copy_opt_attributes(signaled); } - /* RESIGNAL with signal_value */ result= raise_condition(thd, signaled); DBUG_RETURN(result); --===============1260251802102920835== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/alexander.nozdrin@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: alexander.nozdrin@stripped\ # 0sfn1kkjx3cnas0g # target_branch: file:///home/alik/MySQL/bzr/00/bug55847/mysql-trunk-\ # bugfixing-bug55847.2/ # testament_sha1: cc7629e2ff9c00430a3870706fc7b0efbdfd2fb3 # timestamp: 2010-12-15 21:21:18 +0300 # base_revision_id: alexander.nozdrin@stripped\ # 61h77wt0kur6aosk # # Begin bundle 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 UJAvm1N9 --===============1260251802102920835==--