From: Alexander Nozdrin Date: October 14 2010 12:28pm Subject: bzr commit into mysql-5.5-bugteam branch (alexander.nozdrin:3239) Bug#55843 List-Archive: http://lists.mysql.com/commits/120770 X-Bug: 55843 Message-Id: <201010141230.o9ECU1px017520@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1934217109089178646==" --===============1934217109089178646== 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/bug55843/mysql-5.5-bugteam-bug55843/ based on revid:dmitry.shulga@stripped 3239 Alexander Nozdrin 2010-10-14 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/suite/rpl/r/rpl_row_trig003.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-07-30 15:28:36 +0000 +++ b/mysql-test/r/signal.result 2010-10-14 12:28:28 +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 @@ -1473,7 +1455,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 @@ -1528,7 +1509,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 @@ -1585,7 +1565,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() @@ -1646,7 +1625,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() @@ -2148,9 +2126,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 $$ @@ -2195,18 +2170,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-07-30 15:28:36 +0000 +++ b/mysql-test/r/signal_demo3.result 2010-10-14 12:28:28 +0000 @@ -95,11 +95,11 @@ call proc_1(); ERROR 45000: Oops in proc_1 show warnings; Level Code Message -Error 1051 Unknown table '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 '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 '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-10-14 12:28:28 +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-07-30 15:28:36 +0000 +++ b/mysql-test/r/sp-bugs.result 2010-10-14 12:28:28 +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-10-14 12:28:28 +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-07-30 15:28:36 +0000 +++ b/mysql-test/r/sp-error.result 2010-10-14 12:28:28 +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; # @@ -1889,11 +1910,8 @@ SET NEW.a = 10; SET NEW.a = 99999999999; END| UPDATE t1 SET b = 20; -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 SHOW WARNINGS; Level Code Message -Warning 1264 Out of range value for column 'a' at row 1 SELECT * FROM t1; a b 10 20 @@ -1945,11 +1963,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-07-30 15:28:36 +0000 +++ b/mysql-test/r/sp.result 2010-10-14 12:28:28 +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-06 14:34:28 +0000 +++ b/mysql-test/r/sp_trans.result 2010-10-14 12:28:28 +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-10-14 12:28:28 +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-07-30 15:28:36 +0000 +++ b/mysql-test/r/view.result 2010-10-14 12:28:28 +0000 @@ -3946,8 +3946,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-10-14 12:28:28 +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-10-14 12:28:28 +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/suite/rpl/r/rpl_row_trig003.result' --- a/mysql-test/suite/rpl/r/rpl_row_trig003.result 2010-07-30 15:28:36 +0000 +++ b/mysql-test/suite/rpl/r/rpl_row_trig003.result 2010-10-14 12:28:28 +0000 @@ -69,15 +69,9 @@ INSERT INTO test.t2 VALUES(NULL,0,'Testi UPDATE test.t1 SET b1 = 0 WHERE b1 = 1; INSERT INTO test.t2 VALUES(NULL,1,'This is an after update test.', 'If this works, total will not be zero on the master or slave',1.4321,5.221,0,YEAR(NOW()),NOW()); UPDATE test.t2 SET b1 = 0 WHERE b1 = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed INSERT INTO test.t1 VALUES(NULL,1,'add some more test data test.', 'and hope for the best', 3.321,5.221,0,YEAR(NOW()),NOW()); DELETE FROM test.t1 WHERE id = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed DELETE FROM test.t2 WHERE id = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed DROP TRIGGER test.t1_bi; DROP TRIGGER test.t2_ai; DROP TRIGGER test.t1_bu; === modified file 'mysql-test/t/sp-error.test' --- a/mysql-test/t/sp-error.test 2010-07-30 15:28:36 +0000 +++ b/mysql-test/t/sp-error.test 2010-10-14 12:28:28 +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-10-12 12:19:33 +0000 +++ b/sql/sp_head.cc 2010-10-14 12:28:28 +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->stmt_da->sql_errno(), - thd->stmt_da->get_sqlstate(), - MYSQL_ERROR::WARN_LEVEL_ERROR, - thd->stmt_da->message()); - } - else if (thd->warning_info->statement_warn_count()) - { - List_iterator it(thd->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. @todo @@ -1431,19 +1333,10 @@ sp_head::execute(THD *thd) 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. */ @@ -1691,7 +1584,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; @@ -1808,7 +1701,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); @@ -2026,7 +1919,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); @@ -2041,7 +1934,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. */ @@ -3029,7 +2922,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); } @@ -3235,7 +3128,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-08-16 15:16:07 +0000 +++ b/sql/sp_head.h 2010-10-14 12:28:28 +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:28:36 +0000 +++ b/sql/sp_rcontext.cc 2010-10-14 12:28:28 +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()); + DBUG_ASSERT((uint) 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; + m_raised_conditions[hfound].clear(); + m_raised_conditions[hfound].set(sql_errno, sqlstate, level, msg); } - /* - 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); - } - - return FALSE; + return hfound; } void @@ -370,31 +339,188 @@ sp_rcontext::pop_hstack() } /** - Prepare found handler to be executed. + Handles current SQL condition (if any). + + This is the public-interface function to handle SQL conditions in stored + routines. - @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 + @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) +{ + + if (thd->is_error()) + { + int handler_idx= find_handler(thd, + thd->stmt_da->sql_errno(), + thd->stmt_da->get_sqlstate(), + MYSQL_ERROR::WARN_LEVEL_ERROR, + thd->stmt_da->message()); + if (handler_idx < 0) + return -1; + + List_iterator it(thd->warning_info->warn_list()); + MYSQL_ERROR *err; + while ((err= it++)) + { + if (err->get_level() == MYSQL_ERROR::WARN_LEVEL_ERROR && + err->get_sql_errno() == thd->stmt_da->sql_errno() && + !strcmp(err->get_sqlstate(), thd->stmt_da->get_sqlstate()) && + !strcmp(err->get_message_text(), thd->stmt_da->message())) + { + thd->warning_info->remove_warning(thd, err); + thd->stmt_da->remove_warning(); + + it.remove(); + + break; + } + } + + return handler_idx; + } + else if (thd->warning_info->statement_warn_count()) + { + List_iterator it(thd->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; + + 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; + + thd->warning_info->remove_warning(thd, err); + thd->stmt_da->remove_warning(); + + 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 +533,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 +548,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 +576,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-07-30 15:28:36 +0000 +++ b/sql/sp_rcontext.h 2010-10-14 12:28:28 +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. */ @@ -239,16 +249,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-07-30 15:28:36 +0000 +++ b/sql/sql_error.cc 2010-10-14 12:28:28 +0000 @@ -494,6 +494,14 @@ void Warning_info::clear_warning_info(ul m_current_row_for_warning= 1; /* Start counting from the first row */ } +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 warning info was replaced. @@ -562,6 +570,14 @@ MYSQL_ERROR *Warning_info::push_warning( return cond; } + +void Warning_info::remove_warning(THD *thd, const MYSQL_ERROR *warning) +{ + m_warn_count[warning->get_level()]--; + m_statement_warn_count--; +} + + /* Push the warning to error list if there is still room in the list === modified file 'sql/sql_error.h' --- a/sql/sql_error.h 2010-07-30 15:28:36 +0000 +++ b/sql/sql_error.h 2010-10-14 12:28:28 +0000 @@ -97,6 +97,9 @@ public: return m_statement_warn_count; } + void remove_warning() + { --m_statement_warn_count; } + Diagnostics_area() { reset_diagnostics_area(); } private: @@ -471,12 +474,16 @@ 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, MYSQL_ERROR::enum_warning_level level, const char* msg); + void remove_warning(THD *thd, const MYSQL_ERROR *warning); + /** Set the read only status for this statement area. This is a privileged operation, reserved for the implementation of === modified file 'sql/sql_signal.cc' --- a/sql/sql_signal.cc 2010-07-30 15:28:36 +0000 +++ b/sql/sql_signal.cc 2010-10-14 12:28:28 +0000 @@ -491,14 +491,24 @@ bool Resignal_statement::execute(THD *th 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->warning_info->reserve_space(thd, 2); + + cond= thd->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); --===============1934217109089178646== 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\ # xkcgxqmz60v3vjr2 # target_branch: file:///home/alik/MySQL/bzr/00/bug55843/mysql-5.5-\ # bugteam-bug55843/ # testament_sha1: 604c6d059395d23ef5ea116545f23230df259cc0 # timestamp: 2010-10-14 16:28:36 +0400 # base_revision_id: dmitry.shulga@stripped\ # 4g7xt4a7za2cnonp # # Begin bundle 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 --===============1934217109089178646==--