1
0
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:
Alexander Barkov
2025-02-08 17:39:27 +04:00
parent 6be0940f10
commit b7d67ceb5f
25 changed files with 731 additions and 72 deletions

View File

@@ -1020,3 +1020,77 @@ ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor param
#
# End of 10.8 tests
#
# Start of 11.4 tests
#
# MDEV-36047 Package body variables are not allowed as FETCH targets
#
CREATE PACKAGE pkg AS
FUNCTION f1 RETURN INT;
END;
$$
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; -- SHOW CODE should display vc with a "PACKAGE_BODY" prefix
CLOSE cur;
RETURN vc;
END;
BEGIN
DECLARE
CURSOR cur IS SELECT 1 AS c FROM DUAL;
BEGIN
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
DROP PACKAGE pkg;
CREATE PACKAGE pkg AS
FUNCTION f1 RETURN TEXT;
END;
$$
CREATE PACKAGE BODY pkg AS
vc1 INT := 0;
FUNCTION f1 RETURN TEXT AS
CURSOR cur IS SELECT 1 AS c1, 2 AS c2 FROM DUAL;
vc2 INT := 0;
BEGIN
OPEN cur;
FETCH cur INTO vc1, vc2;
CLOSE cur;
RETURN vc1 || ' ' || vc2;
END;
END;
$$
SELECT pkg.f1() FROM DUAL;
pkg.f1()
1 2
DROP PACKAGE pkg;
CREATE PACKAGE pkg AS
FUNCTION f1 RETURN TEXT;
END;
$$
CREATE PACKAGE BODY pkg AS
vc ROW(p1 INT, p2 INT);
FUNCTION f1 RETURN TEXT AS
CURSOR cur IS SELECT 1 AS c1, 2 AS c2 FROM DUAL;
BEGIN
OPEN cur;
FETCH cur INTO vc;
CLOSE cur;
RETURN vc.p1 || ' ' || vc.p2;
END;
END;
$$
SELECT pkg.f1() FROM DUAL;
pkg.f1()
1 2
DROP PACKAGE pkg;
# End of 11.4 tests

View File

@@ -243,3 +243,107 @@ Pos Instruction
7 jump 11
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 AS
FUNCTION f1 RETURN INT;
END;
$$
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; -- SHOW CODE should display vc with a "PACKAGE_BODY" prefix
CLOSE cur;
RETURN vc;
END;
BEGIN
DECLARE
CURSOR cur IS SELECT 1 AS c FROM DUAL;
BEGIN
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 AS
FUNCTION f1 RETURN TEXT;
END;
$$
CREATE PACKAGE BODY pkg AS
vc1 INT := 0;
FUNCTION f1 RETURN TEXT AS
CURSOR cur IS SELECT 1 AS c1, 2 AS c2 FROM DUAL;
vc2 INT := 0;
BEGIN
OPEN cur;
FETCH cur INTO vc1, vc2;
CLOSE cur;
RETURN 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(concat(PACKAGE_BODY.vc1@0,' '),vc2@0)
DROP PACKAGE pkg;
CREATE PACKAGE pkg AS
FUNCTION f1 RETURN TEXT;
END;
$$
CREATE PACKAGE BODY pkg AS
vc ROW(p1 INT, p2 INT);
FUNCTION f1 RETURN TEXT AS
CURSOR cur IS SELECT 1 AS c1, 2 AS c2 FROM DUAL;
BEGIN
OPEN cur;
FETCH cur INTO vc;
CLOSE cur;
RETURN 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(concat(PACKAGE_BODY.vc.p1@0[0],' '),PACKAGE_BODY.vc.p2@0[1])
DROP PACKAGE pkg;
# End of 11.4 tests

View File

@@ -0,0 +1,26 @@
DELIMITER $$;
CREATE PACKAGE pkg AS
FUNCTION f1 RETURN INT;
END;
$$
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; -- SHOW CODE should display vc with a "PACKAGE_BODY" prefix
CLOSE cur;
RETURN vc;
END;
BEGIN
DECLARE
CURSOR cur IS SELECT 1 AS c FROM DUAL;
BEGIN
OPEN cur;
FETCH cur INTO vc; -- SHOW CODE should display vc without a prefix
CLOSE cur;
END;
END;
$$
DELIMITER ;$$

View File

@@ -0,0 +1,20 @@
# Mixing a package body variable and a local variable in the same FETCH.
DELIMITER $$;
CREATE PACKAGE pkg AS
FUNCTION f1 RETURN TEXT;
END;
$$
CREATE PACKAGE BODY pkg AS
vc1 INT := 0;
FUNCTION f1 RETURN TEXT AS
CURSOR cur IS SELECT 1 AS c1, 2 AS c2 FROM DUAL;
vc2 INT := 0;
BEGIN
OPEN cur;
FETCH cur INTO vc1, vc2;
CLOSE cur;
RETURN vc1 || ' ' || vc2;
END;
END;
$$
DELIMITER ;$$

View File

@@ -0,0 +1,19 @@
# Fetching into a PACKAGE BODY variable of the ROW type
DELIMITER $$;
CREATE PACKAGE pkg AS
FUNCTION f1 RETURN TEXT;
END;
$$
CREATE PACKAGE BODY pkg AS
vc ROW(p1 INT, p2 INT);
FUNCTION f1 RETURN TEXT AS
CURSOR cur IS SELECT 1 AS c1, 2 AS c2 FROM DUAL;
BEGIN
OPEN cur;
FETCH cur INTO vc;
CLOSE cur;
RETURN vc.p1 || ' ' || vc.p2;
END;
END;
$$
DELIMITER ;$$

View File

@@ -1042,3 +1042,24 @@ DELIMITER ;$$
--echo #
--echo # End of 10.8 tests
--echo #
--echo # Start of 11.4 tests
--echo #
--echo # MDEV-36047 Package body variables are not allowed as FETCH targets
--echo #
--source sp-cursor-pkg-01.inc
SELECT pkg.f1() FROM DUAL;
DROP PACKAGE pkg;
--source sp-cursor-pkg-02.inc
SELECT pkg.f1() FROM DUAL;
DROP PACKAGE pkg;
--source sp-cursor-pkg-03.inc
SELECT pkg.f1() FROM DUAL;
DROP PACKAGE pkg;
--echo # End of 11.4 tests

View File

@@ -180,3 +180,28 @@ SHOW PROCEDURE CODE pkg1.p1;
SHOW PACKAGE BODY CODE pkg1;
DROP PACKAGE pkg1;
DROP TABLE t1;
--echo # Start of 11.4 tests
--echo #
--echo # MDEV-36047 Package body variables are not allowed as FETCH targets
--echo #
--source sp-cursor-pkg-01.inc
SELECT pkg.f1() FROM DUAL;
SHOW FUNCTION CODE pkg.f1;
SHOW PACKAGE BODY CODE pkg;
DROP PACKAGE pkg;
--source sp-cursor-pkg-02.inc
SELECT pkg.f1() FROM DUAL;
SHOW FUNCTION CODE pkg.f1;
DROP PACKAGE pkg;
--source sp-cursor-pkg-03.inc
SELECT pkg.f1() FROM DUAL;
SHOW FUNCTION CODE pkg.f1;
DROP PACKAGE pkg;
--echo # End of 11.4 tests