mirror of
https://github.com/MariaDB/server.git
synced 2025-10-23 16:17:30 +02:00
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> *".
362 lines
6.8 KiB
Text
362 lines
6.8 KiB
Text
#
|
|
# MDEV-32101 CREATE PACKAGE [BODY] for sql_mode=DEFAULT
|
|
#
|
|
CREATE PACKAGE pkg1
|
|
PROCEDURE p1();
|
|
FUNCTION f1() RETURNS INT;
|
|
END;
|
|
$$
|
|
CREATE PACKAGE BODY pkg1
|
|
PROCEDURE p1()
|
|
BEGIN SELECT 1;
|
|
END;
|
|
FUNCTION f1() RETURNS INT RETURN 1;
|
|
END;
|
|
$$
|
|
SHOW PROCEDURE CODE pkg1.p1;
|
|
Pos Instruction
|
|
0 stmt 0 "SELECT 1"
|
|
SHOW FUNCTION CODE pkg1.f1;
|
|
Pos Instruction
|
|
0 freturn int 1
|
|
SHOW PACKAGE BODY CODE pkg1;
|
|
Pos Instruction
|
|
DROP PACKAGE pkg1;
|
|
CREATE PACKAGE pkg1
|
|
PROCEDURE p1();
|
|
FUNCTION f1() RETURNS INT;
|
|
PROCEDURE p2show();
|
|
PROCEDURE p2public();
|
|
FUNCTION f2public() RETURNS TEXT;
|
|
END;
|
|
$$
|
|
CREATE PACKAGE BODY pkg1
|
|
DECLARE a INT DEFAULT 10;
|
|
PROCEDURE p1()
|
|
BEGIN
|
|
DECLARE b INT DEFAULT 20;
|
|
SET b=a;
|
|
SET b=a+1;
|
|
SET a=b;
|
|
SET a=b+1;
|
|
SET a=a+1;
|
|
SET @a=@a+2;
|
|
SELECT f1() FROM DUAL;
|
|
END;
|
|
FUNCTION f1() RETURNS INT
|
|
BEGIN
|
|
RETURN a;
|
|
END;
|
|
PROCEDURE p2private()
|
|
BEGIN
|
|
SELECT 'This is p2private';
|
|
END;
|
|
PROCEDURE p2public()
|
|
BEGIN
|
|
SELECT 'This is p2public';
|
|
END;
|
|
FUNCTION f2private() RETURNS TEXT
|
|
BEGIN
|
|
RETURN 'This is f2private';
|
|
END;
|
|
FUNCTION f2public() RETURNS TEXT
|
|
BEGIN
|
|
RETURN 'This is f2public';
|
|
END;
|
|
PROCEDURE p2show()
|
|
BEGIN
|
|
SHOW FUNCTION CODE f2public;
|
|
SHOW FUNCTION CODE f2private;
|
|
SHOW PROCEDURE CODE p2public;
|
|
SHOW PROCEDURE CODE p2private;
|
|
SHOW PROCEDURE CODE p2show;
|
|
END;
|
|
-- Initialization section
|
|
SET a=a+1;
|
|
BEGIN
|
|
DECLARE b INT;
|
|
SET b=a;
|
|
SET b=a+1;
|
|
SET a=b;
|
|
SET a=b+1;
|
|
END;
|
|
END;
|
|
$$
|
|
SHOW PROCEDURE CODE pkg1.p1;
|
|
Pos Instruction
|
|
0 set b@0 20
|
|
1 set b@0 PACKAGE_BODY.a@0
|
|
2 set b@0 PACKAGE_BODY.a@0 + 1
|
|
3 set PACKAGE_BODY.a@0 b@0
|
|
4 set PACKAGE_BODY.a@0 b@0 + 1
|
|
5 set PACKAGE_BODY.a@0 PACKAGE_BODY.a@0 + 1
|
|
6 stmt 31 "SET @a=@a+2"
|
|
7 stmt 0 "SELECT f1() FROM DUAL"
|
|
SHOW FUNCTION CODE pkg1.f1;
|
|
Pos Instruction
|
|
0 freturn int PACKAGE_BODY.a@0
|
|
SHOW PACKAGE BODY CODE pkg1;
|
|
Pos Instruction
|
|
0 set a@0 10
|
|
1 set a@0 a@0 + 1
|
|
2 set b@1 NULL
|
|
3 set b@1 a@0
|
|
4 set b@1 a@0 + 1
|
|
5 set a@0 b@1
|
|
6 set a@0 b@1 + 1
|
|
CALL pkg1.p2show;
|
|
Pos Instruction
|
|
0 freturn blob 'This is f2public'
|
|
Pos Instruction
|
|
0 freturn blob 'This is f2private'
|
|
Pos Instruction
|
|
0 stmt 0 "SELECT 'This is p2public'"
|
|
Pos Instruction
|
|
0 stmt 0 "SELECT 'This is p2private'"
|
|
Pos Instruction
|
|
0 stmt 110 "SHOW FUNCTION CODE f2public"
|
|
1 stmt 110 "SHOW FUNCTION CODE f2private"
|
|
2 stmt 109 "SHOW PROCEDURE CODE p2public"
|
|
3 stmt 109 "SHOW PROCEDURE CODE p2private"
|
|
4 stmt 109 "SHOW PROCEDURE CODE p2show"
|
|
DROP PACKAGE pkg1;
|
|
CREATE TABLE t1 (a INT);
|
|
CREATE PACKAGE pkg1
|
|
PROCEDURE p1();
|
|
END;
|
|
$$
|
|
CREATE PACKAGE BODY pkg1
|
|
DECLARE a TYPE OF t1.a DEFAULT 10;
|
|
PROCEDURE p1()
|
|
BEGIN
|
|
DECLARE b TYPE OF t1.a DEFAULT 20;
|
|
SET b=a;
|
|
SET b=a+1;
|
|
SET b=b+1;
|
|
SET a=b;
|
|
SET a=b+1;
|
|
SET a=a+1;
|
|
END;
|
|
-- Initialization section
|
|
SET a=a+1;
|
|
BEGIN
|
|
DECLARE b TYPE OF t1.a;
|
|
SET b=a;
|
|
SET b=a+1;
|
|
SET a=b;
|
|
SET a=b+1;
|
|
END;
|
|
END;
|
|
$$
|
|
SHOW PROCEDURE CODE pkg1.p1;
|
|
Pos Instruction
|
|
0 set b@0 20
|
|
1 set b@0 PACKAGE_BODY.a@0
|
|
2 set b@0 PACKAGE_BODY.a@0 + 1
|
|
3 set b@0 b@0 + 1
|
|
4 set PACKAGE_BODY.a@0 b@0
|
|
5 set PACKAGE_BODY.a@0 b@0 + 1
|
|
6 set PACKAGE_BODY.a@0 PACKAGE_BODY.a@0 + 1
|
|
SHOW PACKAGE BODY CODE pkg1;
|
|
Pos Instruction
|
|
0 set a@0 10
|
|
1 set a@0 a@0 + 1
|
|
2 set b@1 NULL
|
|
3 set b@1 a@0
|
|
4 set b@1 a@0 + 1
|
|
5 set a@0 b@1
|
|
6 set a@0 b@1 + 1
|
|
DROP PACKAGE pkg1;
|
|
DROP TABLE t1;
|
|
CREATE PACKAGE pkg1
|
|
PROCEDURE p1();
|
|
END;
|
|
$$
|
|
CREATE PACKAGE BODY pkg1
|
|
DECLARE a ROW(a INT,b TEXT) DEFAULT ROW(10,'x10');
|
|
PROCEDURE p1()
|
|
BEGIN
|
|
DECLARE b ROW(a INT,b TEXT) DEFAULT ROW(20,'x20');
|
|
SET b=a;
|
|
SET a=b;
|
|
SET b.a=a.a+1;
|
|
SET a.a=b.a+1;
|
|
SET a.a=a.a+1;
|
|
END;
|
|
-- Initialization section
|
|
SET a.a:=a.a+1;
|
|
BEGIN
|
|
DECLARE b ROW(a INT,b TEXT) DEFAULT ROW(30,'x30');
|
|
SET b=a;
|
|
SET b.a=a.a+1;
|
|
SET a=b;
|
|
SET a.a=b.a+1;
|
|
END;
|
|
END;
|
|
$$
|
|
SHOW PROCEDURE CODE pkg1.p1;
|
|
Pos Instruction
|
|
0 set b@0 (20,'x20')
|
|
1 set b@0 PACKAGE_BODY.a@0
|
|
2 set PACKAGE_BODY.a@0 b@0
|
|
3 set b.a@0[0] PACKAGE_BODY.a.a@0[0] + 1
|
|
4 set PACKAGE_BODY.a.a@0[0] b.a@0[0] + 1
|
|
5 set PACKAGE_BODY.a.a@0[0] PACKAGE_BODY.a.a@0[0] + 1
|
|
SHOW PACKAGE BODY CODE pkg1;
|
|
Pos Instruction
|
|
0 set a@0 (10,'x10')
|
|
1 set a.a@0[0] a.a@0[0] + 1
|
|
2 set b@1 (30,'x30')
|
|
3 set b@1 a@0
|
|
4 set b.a@1[0] a.a@0[0] + 1
|
|
5 set a@0 b@1
|
|
6 set a.a@0[0] b.a@1[0] + 1
|
|
DROP PACKAGE pkg1;
|
|
CREATE TABLE t1 (a INT, b TEXT);
|
|
CREATE PACKAGE pkg1
|
|
PROCEDURE p1();
|
|
END;
|
|
$$
|
|
CREATE PACKAGE BODY pkg1
|
|
DECLARE a ROW TYPE OF t1 DEFAULT ROW(10,'x10');
|
|
PROCEDURE p1()
|
|
BEGIN
|
|
DECLARE b ROW TYPE OF t1 DEFAULT ROW(20,'x20');
|
|
SET b=a;
|
|
SET a=b;
|
|
SET b.a=a.a+1;
|
|
SET a.a=b.a+1;
|
|
SET a.a=a.a+1;
|
|
END;
|
|
-- Initialization section
|
|
SET a.a=a.a+1;
|
|
BEGIN
|
|
DECLARE b ROW TYPE OF t1 DEFAULT ROW(30,'x30');
|
|
SET b=a;
|
|
SET b.a=a.a+1;
|
|
SET a=b;
|
|
SET a.a=b.a+1;
|
|
END;
|
|
END;
|
|
$$
|
|
SHOW PROCEDURE CODE pkg1.p1;
|
|
Pos Instruction
|
|
0 set b@0 (20,'x20')
|
|
1 set b@0 PACKAGE_BODY.a@0
|
|
2 set PACKAGE_BODY.a@0 b@0
|
|
3 set b.a@0["a"] PACKAGE_BODY.a.a@0["a"] + 1
|
|
4 set PACKAGE_BODY.a.a@0["a"] b.a@0["a"] + 1
|
|
5 set PACKAGE_BODY.a.a@0["a"] PACKAGE_BODY.a.a@0["a"] + 1
|
|
SHOW PACKAGE BODY CODE pkg1;
|
|
Pos Instruction
|
|
0 set a@0 (10,'x10')
|
|
1 set a.a@0["a"] a.a@0["a"] + 1
|
|
2 set b@1 (30,'x30')
|
|
3 set b@1 a@0
|
|
4 set b.a@1["a"] a.a@0["a"] + 1
|
|
5 set a@0 b@1
|
|
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
|