mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-15941 Explicit cursor FOR loop does not close the cursor
This commit is contained in:
@ -1113,23 +1113,26 @@ Pos Instruction
|
|||||||
10 stmt 0 "SELECT rec1.a, rec1.b"
|
10 stmt 0 "SELECT rec1.a, rec1.b"
|
||||||
11 cfetch cur1@1 rec1@0
|
11 cfetch cur1@1 rec1@0
|
||||||
12 jump 6
|
12 jump 6
|
||||||
13 cursor_copy_struct cur0 rec0@1
|
13 cclose cur1@1
|
||||||
14 copen cur0@0
|
14 cursor_copy_struct cur0 rec0@1
|
||||||
15 cfetch cur0@0 rec0@1
|
15 copen cur0@0
|
||||||
16 jump_if_not 21(21) `cur0`%FOUND
|
16 cfetch cur0@0 rec0@1
|
||||||
17 set rec0.a@1["a"] 10
|
17 jump_if_not 22(22) `cur0`%FOUND
|
||||||
18 set rec0.b@1["b"] 'b0'
|
18 set rec0.a@1["a"] 10
|
||||||
19 cfetch cur0@0 rec0@1
|
19 set rec0.b@1["b"] 'b0'
|
||||||
20 jump 16
|
20 cfetch cur0@0 rec0@1
|
||||||
21 cursor_copy_struct cur2 rec2@2
|
21 jump 17
|
||||||
22 copen cur2@2
|
22 cclose cur0@0
|
||||||
23 cfetch cur2@2 rec2@2
|
23 cursor_copy_struct cur2 rec2@2
|
||||||
24 jump_if_not 29(29) `cur2`%FOUND
|
24 copen cur2@2
|
||||||
25 set rec2.a@2["a"] 10
|
25 cfetch cur2@2 rec2@2
|
||||||
26 set rec2.b@2["b"] 'b0'
|
26 jump_if_not 31(31) `cur2`%FOUND
|
||||||
27 cfetch cur2@2 rec2@2
|
27 set rec2.a@2["a"] 10
|
||||||
28 jump 24
|
28 set rec2.b@2["b"] 'b0'
|
||||||
29 cpop 3
|
29 cfetch cur2@2 rec2@2
|
||||||
|
30 jump 26
|
||||||
|
31 cclose cur2@2
|
||||||
|
32 cpop 3
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
# Nested explicit cursor FOR loops
|
# Nested explicit cursor FOR loops
|
||||||
CREATE PROCEDURE p1()
|
CREATE PROCEDURE p1()
|
||||||
@ -1164,14 +1167,14 @@ Pos Instruction
|
|||||||
1 cursor_copy_struct cur0 rec0@0
|
1 cursor_copy_struct cur0 rec0@0
|
||||||
2 copen cur0@0
|
2 copen cur0@0
|
||||||
3 cfetch cur0@0 rec0@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
|
5 cpush cur1@1
|
||||||
6 set rec0.a@0["a"] 11
|
6 set rec0.a@0["a"] 11
|
||||||
7 set rec0.b@0["b"] 'b0'
|
7 set rec0.b@0["b"] 'b0'
|
||||||
8 cursor_copy_struct cur1 rec1@1
|
8 cursor_copy_struct cur1 rec1@1
|
||||||
9 copen cur1@1
|
9 copen cur1@1
|
||||||
10 cfetch cur1@1 rec1@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
|
12 set rec1.a@1["a"] 11
|
||||||
13 set rec1.b@1["b"] 'b1'
|
13 set rec1.b@1["b"] 'b1'
|
||||||
14 cpush cur2@2
|
14 cpush cur2@2
|
||||||
@ -1183,13 +1186,16 @@ Pos Instruction
|
|||||||
20 set rec2.b@2["b"] 'b2'
|
20 set rec2.b@2["b"] 'b2'
|
||||||
21 cfetch cur2@2 rec2@2
|
21 cfetch cur2@2 rec2@2
|
||||||
22 jump 18
|
22 jump 18
|
||||||
23 cpop 1
|
23 cclose cur2@2
|
||||||
24 cfetch cur1@1 rec1@1
|
24 cpop 1
|
||||||
25 jump 11
|
25 cfetch cur1@1 rec1@1
|
||||||
26 cpop 1
|
26 jump 11
|
||||||
27 cfetch cur0@0 rec0@0
|
27 cclose cur1@1
|
||||||
28 jump 4
|
28 cpop 1
|
||||||
29 cpop 1
|
29 cfetch cur0@0 rec0@0
|
||||||
|
30 jump 4
|
||||||
|
31 cclose cur0@0
|
||||||
|
32 cpop 1
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
# Implicit cursor FOR loops
|
# Implicit cursor FOR loops
|
||||||
CREATE PROCEDURE p1()
|
CREATE PROCEDURE p1()
|
||||||
|
@ -611,3 +611,76 @@ a b
|
|||||||
a b
|
a b
|
||||||
2 b2
|
2 b2
|
||||||
DROP TABLE t1;
|
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
|
||||||
|
@ -607,3 +607,85 @@ END;
|
|||||||
$$
|
$$
|
||||||
DELIMITER ;$$
|
DELIMITER ;$$
|
||||||
DROP TABLE t1;
|
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 ;$$
|
||||||
|
@ -1084,23 +1084,26 @@ Pos Instruction
|
|||||||
10 stmt 0 "SELECT rec1.a, rec1.b"
|
10 stmt 0 "SELECT rec1.a, rec1.b"
|
||||||
11 cfetch cur1@1 rec1@0
|
11 cfetch cur1@1 rec1@0
|
||||||
12 jump 6
|
12 jump 6
|
||||||
13 cursor_copy_struct cur0 rec0@1
|
13 cclose cur1@1
|
||||||
14 copen cur0@0
|
14 cursor_copy_struct cur0 rec0@1
|
||||||
15 cfetch cur0@0 rec0@1
|
15 copen cur0@0
|
||||||
16 jump_if_not 21(21) "cur0"%FOUND
|
16 cfetch cur0@0 rec0@1
|
||||||
17 set rec0.a@1["a"] 10
|
17 jump_if_not 22(22) "cur0"%FOUND
|
||||||
18 set rec0.b@1["b"] 'b0'
|
18 set rec0.a@1["a"] 10
|
||||||
19 cfetch cur0@0 rec0@1
|
19 set rec0.b@1["b"] 'b0'
|
||||||
20 jump 16
|
20 cfetch cur0@0 rec0@1
|
||||||
21 cursor_copy_struct cur2 rec2@2
|
21 jump 17
|
||||||
22 copen cur2@2
|
22 cclose cur0@0
|
||||||
23 cfetch cur2@2 rec2@2
|
23 cursor_copy_struct cur2 rec2@2
|
||||||
24 jump_if_not 29(29) "cur2"%FOUND
|
24 copen cur2@2
|
||||||
25 set rec2.a@2["a"] 10
|
25 cfetch cur2@2 rec2@2
|
||||||
26 set rec2.b@2["b"] 'b0'
|
26 jump_if_not 31(31) "cur2"%FOUND
|
||||||
27 cfetch cur2@2 rec2@2
|
27 set rec2.a@2["a"] 10
|
||||||
28 jump 24
|
28 set rec2.b@2["b"] 'b0'
|
||||||
29 cpop 3
|
29 cfetch cur2@2 rec2@2
|
||||||
|
30 jump 26
|
||||||
|
31 cclose cur2@2
|
||||||
|
32 cpop 3
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
CREATE PROCEDURE p1
|
CREATE PROCEDURE p1
|
||||||
AS
|
AS
|
||||||
@ -1137,14 +1140,14 @@ Pos Instruction
|
|||||||
1 cursor_copy_struct cur0 rec0@0
|
1 cursor_copy_struct cur0 rec0@0
|
||||||
2 copen cur0@0
|
2 copen cur0@0
|
||||||
3 cfetch cur0@0 rec0@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
|
5 cpush cur1@1
|
||||||
6 set rec0.a@0["a"] 11
|
6 set rec0.a@0["a"] 11
|
||||||
7 set rec0.b@0["b"] 'b0'
|
7 set rec0.b@0["b"] 'b0'
|
||||||
8 cursor_copy_struct cur1 rec1@1
|
8 cursor_copy_struct cur1 rec1@1
|
||||||
9 copen cur1@1
|
9 copen cur1@1
|
||||||
10 cfetch cur1@1 rec1@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
|
12 set rec1.a@1["a"] 11
|
||||||
13 set rec1.b@1["b"] 'b1'
|
13 set rec1.b@1["b"] 'b1'
|
||||||
14 cpush cur2@2
|
14 cpush cur2@2
|
||||||
@ -1156,13 +1159,16 @@ Pos Instruction
|
|||||||
20 set rec2.b@2["b"] 'b2'
|
20 set rec2.b@2["b"] 'b2'
|
||||||
21 cfetch cur2@2 rec2@2
|
21 cfetch cur2@2 rec2@2
|
||||||
22 jump 18
|
22 jump 18
|
||||||
23 cpop 1
|
23 cclose cur2@2
|
||||||
24 cfetch cur1@1 rec1@1
|
24 cpop 1
|
||||||
25 jump 11
|
25 cfetch cur1@1 rec1@1
|
||||||
26 cpop 1
|
26 jump 11
|
||||||
27 cfetch cur0@0 rec0@0
|
27 cclose cur1@1
|
||||||
28 jump 4
|
28 cpop 1
|
||||||
29 cpop 1
|
29 cfetch cur0@0 rec0@0
|
||||||
|
30 jump 4
|
||||||
|
31 cclose cur0@0
|
||||||
|
32 cpop 1
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
#
|
#
|
||||||
# MDEV-12098 sql_mode=ORACLE: Implicit cursor FOR loop
|
# MDEV-12098 sql_mode=ORACLE: Implicit cursor FOR loop
|
||||||
|
@ -1331,6 +1331,93 @@ rec2.a rec2.b
|
|||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP TABLE t1;
|
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
|
||||||
|
<<label>>
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
NULL;
|
||||||
|
END LOOP label;
|
||||||
|
FETCH cur INTO v;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR 24000: Cursor is not open
|
||||||
|
DECLARE
|
||||||
|
CURSOR cur IS SELECT 1 AS a FROM DUAL;
|
||||||
|
BEGIN
|
||||||
|
OPEN cur;
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
NULL;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR 24000: Cursor is already open
|
||||||
|
DECLARE
|
||||||
|
CURSOR cur IS SELECT 1 AS a FROM DUAL;
|
||||||
|
BEGIN
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
SELECT rec.a;
|
||||||
|
END LOOP;
|
||||||
|
SELECT cur%ISOPEN;
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
SELECT rec.a;
|
||||||
|
END LOOP;
|
||||||
|
SELECT cur%ISOPEN;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
rec.a
|
||||||
|
1
|
||||||
|
cur%ISOPEN
|
||||||
|
0
|
||||||
|
rec.a
|
||||||
|
1
|
||||||
|
cur%ISOPEN
|
||||||
|
0
|
||||||
|
DECLARE
|
||||||
|
CURSOR cur IS SELECT 1 AS a FROM DUAL;
|
||||||
|
BEGIN
|
||||||
|
<<label1>>
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
SELECT rec.a;
|
||||||
|
END LOOP label1;
|
||||||
|
SELECT cur%ISOPEN;
|
||||||
|
<<label2>>
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
SELECT rec.a;
|
||||||
|
END LOOP;
|
||||||
|
SELECT cur%ISOPEN;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
rec.a
|
||||||
|
1
|
||||||
|
cur%ISOPEN
|
||||||
|
0
|
||||||
|
rec.a
|
||||||
|
1
|
||||||
|
cur%ISOPEN
|
||||||
|
0
|
||||||
|
#
|
||||||
# MDEV-14139 Anchored data types for variables
|
# MDEV-14139 Anchored data types for variables
|
||||||
#
|
#
|
||||||
DECLARE
|
DECLARE
|
||||||
|
@ -1424,6 +1424,98 @@ DROP PROCEDURE p1;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-15941 Explicit cursor FOR loop does not close the cursor
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_SP_CURSOR_NOT_OPEN
|
||||||
|
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;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_SP_CURSOR_NOT_OPEN
|
||||||
|
DECLARE
|
||||||
|
CURSOR cur IS SELECT 1 AS a FROM DUAL;
|
||||||
|
v INT;
|
||||||
|
BEGIN
|
||||||
|
<<label>>
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
NULL;
|
||||||
|
END LOOP label;
|
||||||
|
FETCH cur INTO v;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_SP_CURSOR_ALREADY_OPEN
|
||||||
|
DECLARE
|
||||||
|
CURSOR cur IS SELECT 1 AS a FROM DUAL;
|
||||||
|
BEGIN
|
||||||
|
OPEN cur;
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
NULL;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
DECLARE
|
||||||
|
CURSOR cur IS SELECT 1 AS a FROM DUAL;
|
||||||
|
BEGIN
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
SELECT rec.a;
|
||||||
|
END LOOP;
|
||||||
|
SELECT cur%ISOPEN;
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
SELECT rec.a;
|
||||||
|
END LOOP;
|
||||||
|
SELECT cur%ISOPEN;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
DECLARE
|
||||||
|
CURSOR cur IS SELECT 1 AS a FROM DUAL;
|
||||||
|
BEGIN
|
||||||
|
<<label1>>
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
SELECT rec.a;
|
||||||
|
END LOOP label1;
|
||||||
|
SELECT cur%ISOPEN;
|
||||||
|
<<label2>>
|
||||||
|
FOR rec IN cur
|
||||||
|
LOOP
|
||||||
|
SELECT rec.a;
|
||||||
|
END LOOP;
|
||||||
|
SELECT cur%ISOPEN;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-14139 Anchored data types for variables
|
--echo # MDEV-14139 Anchored data types for variables
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -5891,6 +5891,26 @@ bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop)
|
|||||||
return sp_while_loop_finalize(thd);
|
return sp_while_loop_finalize(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LEX::sp_for_loop_outer_block_finalize(THD *thd,
|
||||||
|
const Lex_for_loop_st &loop)
|
||||||
|
{
|
||||||
|
Lex_spblock tmp;
|
||||||
|
tmp.curs= MY_TEST(loop.m_implicit_cursor);
|
||||||
|
if (unlikely(sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END
|
||||||
|
return true;
|
||||||
|
if (!loop.is_for_loop_explicit_cursor())
|
||||||
|
return false;
|
||||||
|
/*
|
||||||
|
Explicit cursor FOR loop must close the cursor automatically.
|
||||||
|
Note, implicit cursor FOR loop does not need to close the cursor,
|
||||||
|
it's closed by sp_instr_cpop.
|
||||||
|
*/
|
||||||
|
sp_instr_cclose *ic= new (thd->mem_root)
|
||||||
|
sp_instr_cclose(sphead->instructions(), spcont,
|
||||||
|
loop.m_cursor_offset);
|
||||||
|
return ic == NULL || sphead->add_instr(ic);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name,
|
bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name,
|
||||||
|
@ -3802,6 +3802,7 @@ public:
|
|||||||
sp_for_loop_cursor_finalize(thd, loop) :
|
sp_for_loop_cursor_finalize(thd, loop) :
|
||||||
sp_for_loop_intrange_finalize(thd, loop);
|
sp_for_loop_intrange_finalize(thd, loop);
|
||||||
}
|
}
|
||||||
|
bool sp_for_loop_outer_block_finalize(THD *thd, const Lex_for_loop_st &loop);
|
||||||
/* End of FOR LOOP methods */
|
/* End of FOR LOOP methods */
|
||||||
|
|
||||||
bool add_signal_statement(THD *thd, const class sp_condition_value *value);
|
bool add_signal_statement(THD *thd, const class sp_condition_value *value);
|
||||||
|
@ -4729,9 +4729,7 @@ sp_labeled_control:
|
|||||||
}
|
}
|
||||||
pop_sp_loop_label // The inner WHILE block
|
pop_sp_loop_label // The inner WHILE block
|
||||||
{
|
{
|
||||||
Lex_spblock tmp;
|
if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $4)))
|
||||||
tmp.curs= MY_TEST($4.m_implicit_cursor);
|
|
||||||
if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| sp_label REPEAT_SYM
|
| sp_label REPEAT_SYM
|
||||||
@ -4781,12 +4779,10 @@ sp_unlabeled_control:
|
|||||||
sp_proc_stmts1
|
sp_proc_stmts1
|
||||||
END FOR_SYM
|
END FOR_SYM
|
||||||
{
|
{
|
||||||
Lex_spblock tmp;
|
|
||||||
tmp.curs= MY_TEST($3.m_implicit_cursor);
|
|
||||||
if (unlikely(Lex->sp_for_loop_finalize(thd, $3)))
|
if (unlikely(Lex->sp_for_loop_finalize(thd, $3)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block
|
Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block
|
||||||
if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END
|
if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $3)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| REPEAT_SYM
|
| REPEAT_SYM
|
||||||
|
@ -4676,9 +4676,7 @@ sp_labeled_control:
|
|||||||
}
|
}
|
||||||
pop_sp_loop_label // The inner WHILE block
|
pop_sp_loop_label // The inner WHILE block
|
||||||
{
|
{
|
||||||
Lex_spblock tmp;
|
if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $4)))
|
||||||
tmp.curs= MY_TEST($4.m_implicit_cursor);
|
|
||||||
if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| labels_declaration_oracle REPEAT_SYM
|
| labels_declaration_oracle REPEAT_SYM
|
||||||
@ -4728,12 +4726,10 @@ sp_unlabeled_control:
|
|||||||
sp_proc_stmts1
|
sp_proc_stmts1
|
||||||
END LOOP_SYM
|
END LOOP_SYM
|
||||||
{
|
{
|
||||||
Lex_spblock tmp;
|
|
||||||
tmp.curs= MY_TEST($3.m_implicit_cursor);
|
|
||||||
if (unlikely(Lex->sp_for_loop_finalize(thd, $3)))
|
if (unlikely(Lex->sp_for_loop_finalize(thd, $3)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block
|
Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block
|
||||||
if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END
|
if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $3)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| REPEAT_SYM
|
| REPEAT_SYM
|
||||||
|
@ -720,6 +720,10 @@ public:
|
|||||||
*this= other;
|
*this= other;
|
||||||
}
|
}
|
||||||
bool is_for_loop_cursor() const { return m_upper_bound == NULL; }
|
bool is_for_loop_cursor() const { return m_upper_bound == NULL; }
|
||||||
|
bool is_for_loop_explicit_cursor() const
|
||||||
|
{
|
||||||
|
return is_for_loop_cursor() && !m_implicit_cursor;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user