mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-12441 Variables declared after cursors with parameters lose values
Parse context frames (sp_pcontext) can have holes in variable run-time offsets, the missing offsets reside on the children contexts in such cases. Example: CREATE PROCEDURE p1() AS x0 INT:=100; -- context 0, position 0, run-time 0 CURSOR cur( p0 INT, -- context 1, position 0, run-time 1 p1 INT -- context 1, position 1, run-time 2 ) IS SELECT p0, p1; x1 INT:=101; -- context 0, position 1, run-time 3 BEGIN ... END; Fixing a few methods to take this into account: - sp_pcontext::find_variable() - sp_pcontext::retrieve_field_definitions() - LEX::sp_variable_declarations_init() - LEX::sp_variable_declarations_finalize() - LEX::sp_variable_declarations_rowtype_finalize() - LEX::sp_variable_declarations_with_ref_finalize() Adding a convenience method: sp_pcontext::get_last_context_variable(uint offset_from_the_end); to access variables from the end, rather than from the beginning. This helps to loop through the context variable array (m_vars) on the fragment that does not have any holes. Additionally, renaming sp_pcontext::find_context_variable() to sp_pcontext::get_context_variable(). This method simply returns the variable by its index. So let's rename to avoid assumptions that some heavy lookup is going on inside.
This commit is contained in:
@ -1348,3 +1348,136 @@ rec1.a
|
||||
rec2.a
|
||||
11
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# MDEV-12441 Variables declared after cursors with parameters lose values
|
||||
#
|
||||
CREATE PROCEDURE p1() AS
|
||||
x0 INT:=100;
|
||||
CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
|
||||
x1 INT:=101;
|
||||
BEGIN
|
||||
OPEN cur(10,11);
|
||||
CLOSE cur;
|
||||
SELECT x0, x1;
|
||||
END;
|
||||
$$
|
||||
SHOW PROCEDURE CODE p1;
|
||||
Pos Instruction
|
||||
0 set x0@0 100
|
||||
1 set x1@3 101
|
||||
2 cpush cur@0
|
||||
3 set cp1@1 10
|
||||
4 set cp2@2 11
|
||||
5 copen cur@0
|
||||
6 cclose cur@0
|
||||
7 stmt 0 "SELECT x0, x1"
|
||||
8 cpop 1
|
||||
CALL p1();
|
||||
x0 x1
|
||||
100 101
|
||||
DROP PROCEDURE p1;
|
||||
CREATE PROCEDURE p1() AS
|
||||
x0 INT:=100;
|
||||
CURSOR cur0(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
|
||||
x1 INT:=101;
|
||||
CURSOR cur1(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
|
||||
x2 INT:=102;
|
||||
CURSOR cur2(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
|
||||
x3 INT:=103;
|
||||
BEGIN
|
||||
OPEN cur0(0,1);
|
||||
CLOSE cur0;
|
||||
SELECT x0, x1, x2, x3;
|
||||
OPEN cur1(10,11);
|
||||
CLOSE cur1;
|
||||
SELECT x0, x1, x2, x3;
|
||||
OPEN cur2(20,21);
|
||||
CLOSE cur2;
|
||||
SELECT x0, x1, x2, x3;
|
||||
END;
|
||||
$$
|
||||
SHOW PROCEDURE CODE p1;
|
||||
Pos Instruction
|
||||
0 set x0@0 100
|
||||
1 set x1@3 101
|
||||
2 set x2@6 102
|
||||
3 set x3@9 103
|
||||
4 cpush cur0@0
|
||||
5 cpush cur1@1
|
||||
6 cpush cur2@2
|
||||
7 set cp1@1 0
|
||||
8 set cp2@2 1
|
||||
9 copen cur0@0
|
||||
10 cclose cur0@0
|
||||
11 stmt 0 "SELECT x0, x1, x2, x3"
|
||||
12 set cp1@4 10
|
||||
13 set cp2@5 11
|
||||
14 copen cur1@1
|
||||
15 cclose cur1@1
|
||||
16 stmt 0 "SELECT x0, x1, x2, x3"
|
||||
17 set cp1@7 20
|
||||
18 set cp2@8 21
|
||||
19 copen cur2@2
|
||||
20 cclose cur2@2
|
||||
21 stmt 0 "SELECT x0, x1, x2, x3"
|
||||
22 cpop 3
|
||||
CALL p1();
|
||||
x0 x1 x2 x3
|
||||
100 101 102 103
|
||||
x0 x1 x2 x3
|
||||
100 101 102 103
|
||||
x0 x1 x2 x3
|
||||
100 101 102 103
|
||||
DROP PROCEDURE p1;
|
||||
CREATE TABLE t1 (a INT);
|
||||
CREATE PROCEDURE p1() AS
|
||||
x0 INT:=100;
|
||||
CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
|
||||
x1 t1.a%TYPE:=101;
|
||||
BEGIN
|
||||
OPEN cur(10,11);
|
||||
CLOSE cur;
|
||||
SELECT x0, x1;
|
||||
END;
|
||||
$$
|
||||
SHOW PROCEDURE CODE p1;
|
||||
Pos Instruction
|
||||
0 set x0@0 100
|
||||
1 set x1@3 101
|
||||
2 cpush cur@0
|
||||
3 set cp1@1 10
|
||||
4 set cp2@2 11
|
||||
5 copen cur@0
|
||||
6 cclose cur@0
|
||||
7 stmt 0 "SELECT x0, x1"
|
||||
8 cpop 1
|
||||
CALL p1();
|
||||
x0 x1
|
||||
100 101
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
CREATE PROCEDURE p1() AS
|
||||
x0 INT:=100;
|
||||
CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
|
||||
x1 ROW(a INT,b INT):=ROW(101,102);
|
||||
BEGIN
|
||||
OPEN cur(10,11);
|
||||
CLOSE cur;
|
||||
SELECT x0, x1.a, x1.b;
|
||||
END;
|
||||
$$
|
||||
SHOW PROCEDURE CODE p1;
|
||||
Pos Instruction
|
||||
0 set x0@0 100
|
||||
1 set x1@3 (101,102)
|
||||
2 cpush cur@0
|
||||
3 set cp1@1 10
|
||||
4 set cp2@2 11
|
||||
5 copen cur@0
|
||||
6 cclose cur@0
|
||||
7 stmt 0 "SELECT x0, x1.a, x1.b"
|
||||
8 cpop 1
|
||||
CALL p1();
|
||||
x0 x1.a x1.b
|
||||
100 101 102
|
||||
DROP PROCEDURE p1;
|
||||
|
Reference in New Issue
Block a user