mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +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:
@@ -838,3 +838,92 @@ c
|
||||
rec=(30,b30)
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# 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;
|
||||
$$
|
||||
CALL p1();
|
||||
x0 x1
|
||||
100 101
|
||||
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;
|
||||
$$
|
||||
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;
|
||||
$$
|
||||
CALL p1();
|
||||
x0 x1.a x1.b
|
||||
100 101 102
|
||||
DROP PROCEDURE p1;
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(10));
|
||||
INSERT INTO t1 VALUES (10,'Tbl-t1.b0');
|
||||
CREATE PROCEDURE p1() AS
|
||||
x0 INT:=100;
|
||||
CURSOR cur(cp1 INT, cp2 INT) IS SELECT a,b FROM t1;
|
||||
x1 t1%ROWTYPE:=ROW(101,'Var-x1.b0');
|
||||
BEGIN
|
||||
SELECT x0, x1.a, x1.b;
|
||||
OPEN cur(10,11);
|
||||
FETCH cur INTO x1;
|
||||
CLOSE cur;
|
||||
SELECT x0, x1.a, x1.b;
|
||||
END;
|
||||
$$
|
||||
CALL p1();
|
||||
x0 x1.a x1.b
|
||||
100 101 Var-x1.b0
|
||||
x0 x1.a x1.b
|
||||
100 10 Tbl-t1.b0
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(10));
|
||||
INSERT INTO t1 VALUES (10,'Tbl-t1.b0');
|
||||
CREATE PROCEDURE p1() AS
|
||||
x0 INT:=100;
|
||||
CURSOR cur(cp1 INT, cp2 INT) IS SELECT a,b FROM t1;
|
||||
x1 cur%ROWTYPE:=ROW(101,'Var-x1.b0');
|
||||
BEGIN
|
||||
SELECT x0, x1.a, x1.b;
|
||||
OPEN cur(10,11);
|
||||
FETCH cur INTO x1;
|
||||
CLOSE cur;
|
||||
SELECT x0, x1.a, x1.b;
|
||||
END;
|
||||
$$
|
||||
CALL p1();
|
||||
x0 x1.a x1.b
|
||||
100 101 Var-x1.b0
|
||||
x0 x1.a x1.b
|
||||
100 10 Tbl-t1.b0
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
|
||||
Reference in New Issue
Block a user