mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-36047 Package body variables are not allowed as FETCH targets
It was not possible to use a package body variable as a fetch target: CREATE PACKAGE BODY pkg AS vc INT := 0; FUNCTION f1 RETURN INT AS CURSOR cur IS SELECT 1 AS c FROM DUAL; BEGIN OPEN cur; FETCH cur INTO vc; -- this returned "Undeclared variable: vc" error. CLOSE cur; RETURN vc; END; END; FETCH assumed that all fetch targets reside of the same sp_rcontext instance with the cursor. This patch fixes the problem. Now a cursor and its fetch target can reside in different sp_rcontext instances. Details: - Adding a helper class sp_rcontext_addr (a combination of Sp_rcontext_handler pointer and an offset in the rcontext) - Adding a new class sp_fetch_target deriving from sp_rcontext_addr. Fetch targets in "FETCH cur INTO target1, target2 ..." are now collected into this structure instead of sp_variable. sp_variable cannot be used any more to store fetch targets, because it does not have a pointer to Sp_rcontext_handler (it only has the current rcontext offset). - Removing members sp_instr_set members m_rcontext_handler and m_offset. Deriving sp_instr_set from sp_rcontext_addr instead. - Renaming sp_instr_cfetch member "List<sp_variable> m_varlist" to "List<sp_fetch_target> m_fetch_target_list". - Fixing LEX::sp_add_cfetch() to return the pointer to the created sp_fetch_target instance (instead of returning bool). This helps to make the grammar in sql_yacc.c simpler - Renaming LEX::sp_add_cfetch() to LEX::sp_add_instr_cfetch(), as `if(sp_add_cfetch())` changed its meaning to the opposite, to avoid automatic wrong merge from earlier versions. - Chaning the "List<sp_variable> *vars" parameter to sp_cursor::fetch to have the data type "List<sp_fetch_target> *". - Changing the data type of "List<sp_variable> &vars" in sp_cursor::Select_fetch_into_spvars::send_data_to_variable_list() to "List<sp_fetch_target> &". - Adding THD helper methods get_rcontext() and get_variable(). - Moving the code from sql_yacc.yy into a new LEX method LEX::make_fetch_target(). - Simplifying the grammar in sql_yacc.yy using the new LEX method. Changing the data type of the bison rule sp_fetch_list from "void" to "List<sp_fetch_target> *".
This commit is contained in:
@@ -258,3 +258,105 @@ Pos Instruction
|
||||
6 set a.a@0["a"] b.a@1["a"] + 1
|
||||
DROP PACKAGE pkg1;
|
||||
DROP TABLE t1;
|
||||
# Start of 11.4 tests
|
||||
#
|
||||
# MDEV-36047 Package body variables are not allowed as FETCH targets
|
||||
#
|
||||
CREATE PACKAGE pkg
|
||||
FUNCTION f1() RETURNS INT;
|
||||
END;
|
||||
$$
|
||||
CREATE PACKAGE BODY pkg
|
||||
DECLARE vc INT DEFAULT 0;
|
||||
FUNCTION f1() RETURNS INT
|
||||
BEGIN
|
||||
DECLARE cur CURSOR FOR SELECT 1 AS c FROM DUAL;
|
||||
OPEN cur;
|
||||
FETCH cur INTO vc; -- SHOW CODE should display vc with a "PACKAGE_BODY" prefix
|
||||
CLOSE cur;
|
||||
RETURN vc;
|
||||
END;
|
||||
BEGIN
|
||||
DECLARE cur CURSOR FOR SELECT 1 AS c FROM DUAL;
|
||||
OPEN cur;
|
||||
FETCH cur INTO vc; -- SHOW CODE should display vc without a prefix
|
||||
CLOSE cur;
|
||||
END;
|
||||
END;
|
||||
$$
|
||||
SELECT pkg.f1() FROM DUAL;
|
||||
pkg.f1()
|
||||
1
|
||||
SHOW FUNCTION CODE pkg.f1;
|
||||
Pos Instruction
|
||||
0 cpush cur@0
|
||||
1 copen cur@0
|
||||
2 cfetch cur@0 PACKAGE_BODY.vc@0
|
||||
3 cclose cur@0
|
||||
4 freturn int PACKAGE_BODY.vc@0
|
||||
SHOW PACKAGE BODY CODE pkg;
|
||||
Pos Instruction
|
||||
0 set vc@0 0
|
||||
1 cpush cur@0
|
||||
2 copen cur@0
|
||||
3 cfetch cur@0 vc@0
|
||||
4 cclose cur@0
|
||||
5 cpop 1
|
||||
DROP PACKAGE pkg;
|
||||
CREATE PACKAGE pkg
|
||||
FUNCTION f1() RETURNS TEXT;
|
||||
END;
|
||||
$$
|
||||
CREATE PACKAGE BODY pkg
|
||||
DECLARE vc1 INT DEFAULT 0;
|
||||
FUNCTION f1() RETURNS TEXT
|
||||
BEGIN
|
||||
DECLARE vc2 INT DEFAULT 0;
|
||||
DECLARE cur CURSOR FOR SELECT 1 AS c1, 2 AS c2 FROM DUAL;
|
||||
OPEN cur;
|
||||
FETCH cur INTO vc1, vc2;
|
||||
CLOSE cur;
|
||||
RETURN CONCAT(vc1, ' ', vc2);
|
||||
END;
|
||||
END;
|
||||
$$
|
||||
SELECT pkg.f1() FROM DUAL;
|
||||
pkg.f1()
|
||||
1 2
|
||||
SHOW FUNCTION CODE pkg.f1;
|
||||
Pos Instruction
|
||||
0 set vc2@0 0
|
||||
1 cpush cur@0
|
||||
2 copen cur@0
|
||||
3 cfetch cur@0 PACKAGE_BODY.vc1@0 vc2@0
|
||||
4 cclose cur@0
|
||||
5 freturn blob concat(PACKAGE_BODY.vc1@0,' ',vc2@0)
|
||||
DROP PACKAGE pkg;
|
||||
CREATE PACKAGE pkg
|
||||
FUNCTION f1() RETURNS TEXT;
|
||||
END;
|
||||
$$
|
||||
CREATE PACKAGE BODY pkg
|
||||
DECLARE vc ROW(p1 INT, p2 INT);
|
||||
FUNCTION f1() RETURNS TEXT
|
||||
BEGIN
|
||||
DECLARE cur CURSOR FOR SELECT 1 AS c1, 2 AS c2 FROM DUAL;
|
||||
OPEN cur;
|
||||
FETCH cur INTO vc;
|
||||
CLOSE cur;
|
||||
RETURN CONCAT(vc.p1, ' ', vc.p2);
|
||||
END;
|
||||
END;
|
||||
$$
|
||||
SELECT pkg.f1() FROM DUAL;
|
||||
pkg.f1()
|
||||
1 2
|
||||
SHOW FUNCTION CODE pkg.f1;
|
||||
Pos Instruction
|
||||
0 cpush cur@0
|
||||
1 copen cur@0
|
||||
2 cfetch cur@0 PACKAGE_BODY.vc@0
|
||||
3 cclose cur@0
|
||||
4 freturn blob concat(PACKAGE_BODY.vc.p1@0[0],' ',PACKAGE_BODY.vc.p2@0[1])
|
||||
DROP PACKAGE pkg;
|
||||
# End of 11.4 tests
|
||||
|
Reference in New Issue
Block a user