Bug #61392 | CONTINUE HANDLER FOR NOT FOUND being triggered from internal stored function | ||
---|---|---|---|
Submitted: | 2 Jun 2011 21:05 | Modified: | 31 Oct 2011 14:13 |
Reporter: | David Poor | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Stored Routines | Severity: | S2 (Serious) |
Version: | 5.5.14, 5.5.10 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | continue handler, stored function |
[2 Jun 2011 21:05]
David Poor
[3 Jun 2011 4:16]
Valeriy Kravchuk
Thank you for the bug report. Verified with current mysql-5.5 from bzr on Mac OS X: macbook-pro:5.5 openxs$ bin/mysql -uroot test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 16 Server version: 5.5.14-debug Source distribution Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CREATE TABLE `test2` ( -> `RecNum` int(3) NOT NULL AUTO_INCREMENT, -> `TableValue` varchar(3) DEFAULT NULL, -> UNIQUE KEY `RecNum` (`RecNum`) -> ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.12 sec) mysql> insert into `test2`(`RecNum`,`TableValue`) values (1,'1'); Query OK, 1 row affected (0.00 sec) mysql> insert into `test2`(`RecNum`,`TableValue`) values (2,'2'); Query OK, 1 row affected (0.00 sec) mysql> insert into `test2`(`RecNum`,`TableValue`) values (3,'-1'); Query OK, 1 row affected (0.00 sec) mysql> insert into `test2`(`RecNum`,`TableValue`) values (4,'4'); Query OK, 1 row affected (0.00 sec) mysql> mysql> delimiter $$ mysql> CREATE FUNCTION `returnFromQuery`(param int) RETURNS varchar(5) CHARSET latin1 -> BEGIN -> DECLARE newValue varchar(5) default null; -> Select TableValue FROM test2 where RecNum=param INTO newValue; -> RETURN newValue; -> END$$ Query OK, 0 rows affected (0.04 sec) mysql> CREATE FUNCTION `testCursorHandler`(doCall int) RETURNS varchar(200) CHARSET latin1 -> READS SQL DATA -> BEGIN -> DECLARE returnValue VARCHAR(200) DEFAULT ""; -> DECLARE newValue varchar(3); -> DECLARE done INT DEFAULT 0; -> DECLARE cur1 CURSOR FOR -> select IF(doCall=0,returnFromQuery(RecNum),returnFromQuery(TableValue)) as -> testValue -> from test2 -> order by RecNum; -> DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; -> IF done=0 THEN -> OPEN cur1; -> REPEAT -> FETCH cur1 INTO newValue; -> set newValue=IFNULL(newValue,"---"); -> set returnValue=CONCAT(returnValue,newvalue,"(",done,"), "); -> UNTIL done END REPEAT; -> CLOSE cur1; -> END IF; -> RETURN returnValue; -> END$$ Query OK, 0 rows affected (0.03 sec) mysql> select testCursorHandler(0); -> $$ +---------------------------------+ | testCursorHandler(0) | +---------------------------------+ | 1(0), 2(0), -1(0), 4(0), 4(1), | +---------------------------------+ 1 row in set, 1 warning (0.01 sec) mysql> show warnings\G *************************** 1. row *************************** Level: Error Code: 1329 Message: No data - zero rows fetched, selected, or processed 1 row in set (0.00 sec) mysql> select testCursorHandler(1); -> $$ +----------------------+ | testCursorHandler(1) | +----------------------+ | 1(1), | +----------------------+ 1 row in set, 1 warning (0.01 sec) mysql> show warnings\G *************************** 1. row *************************** Level: Warning Code: 1329 Message: No data - zero rows fetched, selected, or processed 1 row in set (0.00 sec)
[19 Jul 2011 16:32]
MySQL Verification Team
my tests show that it seems this bug was introduced in 5.5.6 ... And the change history of 5.5.6 say this: "Incompatible Change: Handling of warnings and errors during stored program execution was problematic: If one statement generated several warnings or errors, only the handler for the first was activated, even if another might be more appropriate. Warning or error information could be lost. (Bug #36185, Bug #5889, Bug #9857, Bug #23032)"
[17 Oct 2011 13:36]
Santo Leto
Can be easily repeated using the example in http://dev.mysql.com/doc/refman/5.5/en/cursors.html USE TEST; DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (id char(16), data int); CREATE TABLE t2 (i int); DROP PROCEDURE IF EXISTS curdemo; delimiter $$ CREATE PROCEDURE curdemo() BEGIN DECLARE done INT DEFAULT 0; DECLARE a CHAR(16); DECLARE b,c INT; DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1; DECLARE cur2 CURSOR FOR SELECT i FROM test.t2; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur1; OPEN cur2; read_loop: LOOP FETCH cur1 INTO a, b; FETCH cur2 INTO c; IF done THEN LEAVE read_loop; END IF; IF b < c THEN INSERT INTO test.t3 VALUES (a,b); ELSE INSERT INTO test.t3 VALUES (a,c); END IF; END LOOP; CLOSE cur1; CLOSE cur2; END$$ delimiter ; CALL curdemo(); On 5.5.5: mysql> CALL curdemo(); Query OK, 0 rows affected (0.00 sec) On 5.5.14: mysql> CALL curdemo(); Query OK, 0 rows affected, 1 warning (0.10 sec) mysql> show warnings\G *************************** 1. row *************************** Level: Error Code: 1329 Message: No data - zero rows fetched, selected, or processed 1 row in set (0.00 sec) mysql>
[31 Oct 2011 14:13]
Paul DuBois
Noted in 5.6.4 changelog. The RETURN statement did not clear the diagnostics area as it should have. Now the diagnostics area is cleared before executing RETURN. This prevents a condition in a nested function call from incorrectly propagating to an outer scope. It also means there is no way to return an SQL warning from a stored function. This change is not backward compatible, but the resulting behavior is more like standard SQL.
[6 Mar 2012 16:31]
Sveta Smirnova
Bug #64521 was marked as duplicate of this one.