diff --git a/mysql-test/main/sp-code.result b/mysql-test/main/sp-code.result index 001b03a0e3b..c3af01d19e8 100644 --- a/mysql-test/main/sp-code.result +++ b/mysql-test/main/sp-code.result @@ -1113,23 +1113,26 @@ Pos Instruction 10 stmt 0 "SELECT rec1.a, rec1.b" 11 cfetch cur1@1 rec1@0 12 jump 6 -13 cursor_copy_struct cur0 rec0@1 -14 copen cur0@0 -15 cfetch cur0@0 rec0@1 -16 jump_if_not 21(21) `cur0`%FOUND -17 set rec0.a@1["a"] 10 -18 set rec0.b@1["b"] 'b0' -19 cfetch cur0@0 rec0@1 -20 jump 16 -21 cursor_copy_struct cur2 rec2@2 -22 copen cur2@2 -23 cfetch cur2@2 rec2@2 -24 jump_if_not 29(29) `cur2`%FOUND -25 set rec2.a@2["a"] 10 -26 set rec2.b@2["b"] 'b0' -27 cfetch cur2@2 rec2@2 -28 jump 24 -29 cpop 3 +13 cclose cur1@1 +14 cursor_copy_struct cur0 rec0@1 +15 copen cur0@0 +16 cfetch cur0@0 rec0@1 +17 jump_if_not 22(22) `cur0`%FOUND +18 set rec0.a@1["a"] 10 +19 set rec0.b@1["b"] 'b0' +20 cfetch cur0@0 rec0@1 +21 jump 17 +22 cclose cur0@0 +23 cursor_copy_struct cur2 rec2@2 +24 copen cur2@2 +25 cfetch cur2@2 rec2@2 +26 jump_if_not 31(31) `cur2`%FOUND +27 set rec2.a@2["a"] 10 +28 set rec2.b@2["b"] 'b0' +29 cfetch cur2@2 rec2@2 +30 jump 26 +31 cclose cur2@2 +32 cpop 3 DROP PROCEDURE p1; # Nested explicit cursor FOR loops CREATE PROCEDURE p1() @@ -1164,14 +1167,14 @@ Pos Instruction 1 cursor_copy_struct cur0 rec0@0 2 copen cur0@0 3 cfetch cur0@0 rec0@0 -4 jump_if_not 29(29) `cur0`%FOUND +4 jump_if_not 31(31) `cur0`%FOUND 5 cpush cur1@1 6 set rec0.a@0["a"] 11 7 set rec0.b@0["b"] 'b0' 8 cursor_copy_struct cur1 rec1@1 9 copen cur1@1 10 cfetch cur1@1 rec1@1 -11 jump_if_not 26(26) `cur1`%FOUND +11 jump_if_not 27(27) `cur1`%FOUND 12 set rec1.a@1["a"] 11 13 set rec1.b@1["b"] 'b1' 14 cpush cur2@2 @@ -1183,13 +1186,16 @@ Pos Instruction 20 set rec2.b@2["b"] 'b2' 21 cfetch cur2@2 rec2@2 22 jump 18 -23 cpop 1 -24 cfetch cur1@1 rec1@1 -25 jump 11 -26 cpop 1 -27 cfetch cur0@0 rec0@0 -28 jump 4 -29 cpop 1 +23 cclose cur2@2 +24 cpop 1 +25 cfetch cur1@1 rec1@1 +26 jump 11 +27 cclose cur1@1 +28 cpop 1 +29 cfetch cur0@0 rec0@0 +30 jump 4 +31 cclose cur0@0 +32 cpop 1 DROP PROCEDURE p1; # Implicit cursor FOR loops CREATE PROCEDURE p1() diff --git a/mysql-test/main/sp-cursor.result b/mysql-test/main/sp-cursor.result index 1f8cb7f0635..42d6e455109 100644 --- a/mysql-test/main/sp-cursor.result +++ b/mysql-test/main/sp-cursor.result @@ -611,3 +611,76 @@ a b a b 2 b2 DROP TABLE t1; +# +# MDEV-15941 Explicit cursor FOR loop does not close the cursor +# +BEGIN NOT ATOMIC +DECLARE v INT; +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +FETCH cur INTO v; +END; +$$ +rec.a +1 +ERROR 24000: Cursor is not open +BEGIN NOT ATOMIC +DECLARE v INT; +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +label: +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +FETCH cur INTO v; +END; +$$ +rec.a +1 +ERROR 24000: Cursor is not open +BEGIN NOT ATOMIC +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +OPEN cur; +FOR rec IN cur DO +SELECT rec.a; +END FOR; +END; +$$ +ERROR 24000: Cursor is already open +BEGIN NOT ATOMIC +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +END; +$$ +rec.a +1 +rec.a +1 +BEGIN NOT ATOMIC +DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +label1: +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +label2: +FOR rec IN cur +DO +SELECT rec.a; +END FOR; +END; +$$ +rec.a +1 +rec.a +1 diff --git a/mysql-test/main/sp-cursor.test b/mysql-test/main/sp-cursor.test index 2e7a72cf8d0..bc352872075 100644 --- a/mysql-test/main/sp-cursor.test +++ b/mysql-test/main/sp-cursor.test @@ -607,3 +607,85 @@ END; $$ DELIMITER ;$$ DROP TABLE t1; + + +--echo # +--echo # MDEV-15941 Explicit cursor FOR loop does not close the cursor +--echo # + +DELIMITER $$; +--error ER_SP_CURSOR_NOT_OPEN +BEGIN NOT ATOMIC + DECLARE v INT; + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; + FOR rec IN cur + DO + SELECT rec.a; + END FOR; + FETCH cur INTO v; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_SP_CURSOR_NOT_OPEN +BEGIN NOT ATOMIC + DECLARE v INT; + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +label: + FOR rec IN cur + DO + SELECT rec.a; + END FOR; + FETCH cur INTO v; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_SP_CURSOR_ALREADY_OPEN +BEGIN NOT ATOMIC + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; + OPEN cur; + FOR rec IN cur DO + SELECT rec.a; + END FOR; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; + FOR rec IN cur + DO + SELECT rec.a; + END FOR; + FOR rec IN cur + DO + SELECT rec.a; + END FOR; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE cur CURSOR FOR SELECT 1 AS a FROM DUAL; +label1: + FOR rec IN cur + DO + SELECT rec.a; + END FOR; +label2: + FOR rec IN cur + DO + SELECT rec.a; + END FOR; +END; +$$ +DELIMITER ;$$ diff --git a/mysql-test/suite/compat/oracle/r/sp-code.result b/mysql-test/suite/compat/oracle/r/sp-code.result index f1dd4180854..1049563511c 100644 --- a/mysql-test/suite/compat/oracle/r/sp-code.result +++ b/mysql-test/suite/compat/oracle/r/sp-code.result @@ -1084,23 +1084,26 @@ Pos Instruction 10 stmt 0 "SELECT rec1.a, rec1.b" 11 cfetch cur1@1 rec1@0 12 jump 6 -13 cursor_copy_struct cur0 rec0@1 -14 copen cur0@0 -15 cfetch cur0@0 rec0@1 -16 jump_if_not 21(21) "cur0"%FOUND -17 set rec0.a@1["a"] 10 -18 set rec0.b@1["b"] 'b0' -19 cfetch cur0@0 rec0@1 -20 jump 16 -21 cursor_copy_struct cur2 rec2@2 -22 copen cur2@2 -23 cfetch cur2@2 rec2@2 -24 jump_if_not 29(29) "cur2"%FOUND -25 set rec2.a@2["a"] 10 -26 set rec2.b@2["b"] 'b0' -27 cfetch cur2@2 rec2@2 -28 jump 24 -29 cpop 3 +13 cclose cur1@1 +14 cursor_copy_struct cur0 rec0@1 +15 copen cur0@0 +16 cfetch cur0@0 rec0@1 +17 jump_if_not 22(22) "cur0"%FOUND +18 set rec0.a@1["a"] 10 +19 set rec0.b@1["b"] 'b0' +20 cfetch cur0@0 rec0@1 +21 jump 17 +22 cclose cur0@0 +23 cursor_copy_struct cur2 rec2@2 +24 copen cur2@2 +25 cfetch cur2@2 rec2@2 +26 jump_if_not 31(31) "cur2"%FOUND +27 set rec2.a@2["a"] 10 +28 set rec2.b@2["b"] 'b0' +29 cfetch cur2@2 rec2@2 +30 jump 26 +31 cclose cur2@2 +32 cpop 3 DROP PROCEDURE p1; CREATE PROCEDURE p1 AS @@ -1137,14 +1140,14 @@ Pos Instruction 1 cursor_copy_struct cur0 rec0@0 2 copen cur0@0 3 cfetch cur0@0 rec0@0 -4 jump_if_not 29(29) "cur0"%FOUND +4 jump_if_not 31(31) "cur0"%FOUND 5 cpush cur1@1 6 set rec0.a@0["a"] 11 7 set rec0.b@0["b"] 'b0' 8 cursor_copy_struct cur1 rec1@1 9 copen cur1@1 10 cfetch cur1@1 rec1@1 -11 jump_if_not 26(26) "cur1"%FOUND +11 jump_if_not 27(27) "cur1"%FOUND 12 set rec1.a@1["a"] 11 13 set rec1.b@1["b"] 'b1' 14 cpush cur2@2 @@ -1156,13 +1159,16 @@ Pos Instruction 20 set rec2.b@2["b"] 'b2' 21 cfetch cur2@2 rec2@2 22 jump 18 -23 cpop 1 -24 cfetch cur1@1 rec1@1 -25 jump 11 -26 cpop 1 -27 cfetch cur0@0 rec0@0 -28 jump 4 -29 cpop 1 +23 cclose cur2@2 +24 cpop 1 +25 cfetch cur1@1 rec1@1 +26 jump 11 +27 cclose cur1@1 +28 cpop 1 +29 cfetch cur0@0 rec0@0 +30 jump 4 +31 cclose cur0@0 +32 cpop 1 DROP PROCEDURE p1; # # MDEV-12098 sql_mode=ORACLE: Implicit cursor FOR loop diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result index a46daf30a8f..093d52ba4e3 100644 --- a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result +++ b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result @@ -1331,6 +1331,93 @@ rec2.a rec2.b DROP PROCEDURE p1; DROP TABLE t1; # +# MDEV-15941 Explicit cursor FOR loop does not close the cursor +# +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +v INT; +BEGIN +FOR rec IN cur +LOOP +NULL; +END LOOP; +FETCH cur INTO v; +END; +$$ +ERROR 24000: Cursor is not open +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +v INT; +BEGIN +<