2024-02-08 15:58:26 +04:00
|
|
|
#
|
|
|
|
# Start of 11.4 tests
|
|
|
|
#
|
2023-09-04 15:28:50 +04:00
|
|
|
SET sql_mode='';
|
|
|
|
CREATE OR REPLACE PACKAGE pkg
|
|
|
|
PROCEDURE p1();
|
|
|
|
FUNCTION f1() RETURNS INT;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
CREATE OR REPLACE PACKAGE BODY pkg
|
|
|
|
-- variable declarations
|
|
|
|
DECLARE a INT DEFAULT 11;
|
|
|
|
DECLARE b INT DEFAULT 10;
|
|
|
|
-- routine declarations
|
|
|
|
PROCEDURE p1()
|
|
|
|
BEGIN
|
|
|
|
SELECT CURRENT_USER;
|
|
|
|
END;
|
|
|
|
FUNCTION f1() RETURNS INT
|
|
|
|
BEGIN
|
|
|
|
RETURN a;
|
|
|
|
END;
|
|
|
|
-- initialization section
|
|
|
|
SET a=a-b;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
SHOW CREATE PACKAGE pkg;
|
|
|
|
Package sql_mode Create Package character_set_client collation_connection Database Collation
|
|
|
|
pkg CREATE DEFINER=`root`@`localhost` PACKAGE `pkg` PROCEDURE p1();
|
|
|
|
FUNCTION f1() RETURNS INT;
|
2024-05-28 09:08:51 +04:00
|
|
|
END latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
|
2023-09-04 15:28:50 +04:00
|
|
|
SHOW CREATE PACKAGE BODY pkg;
|
|
|
|
Package body sql_mode Create Package Body character_set_client collation_connection Database Collation
|
|
|
|
pkg CREATE DEFINER=`root`@`localhost` PACKAGE BODY `pkg` DECLARE a INT DEFAULT 11;
|
|
|
|
DECLARE b INT DEFAULT 10;
|
|
|
|
-- routine declarations
|
|
|
|
PROCEDURE p1()
|
|
|
|
BEGIN
|
|
|
|
SELECT CURRENT_USER;
|
|
|
|
END;
|
|
|
|
FUNCTION f1() RETURNS INT
|
|
|
|
BEGIN
|
|
|
|
RETURN a;
|
|
|
|
END;
|
|
|
|
-- initialization section
|
|
|
|
SET a=a-b;
|
2024-05-28 09:08:51 +04:00
|
|
|
END latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
|
2023-09-04 15:28:50 +04:00
|
|
|
CALL pkg.p1();
|
|
|
|
CURRENT_USER
|
|
|
|
root@localhost
|
|
|
|
SELECT pkg.f1();
|
|
|
|
pkg.f1()
|
|
|
|
1
|
|
|
|
DROP PACKAGE pkg;
|
2024-02-08 15:58:26 +04:00
|
|
|
#
|
|
|
|
# MDEV-33428 Error messages ER_PACKAGE_ROUTINE_* are not good enough
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# Routines declared in CREATE PACKAGE missing in CREATE PACKAGE BODY
|
|
|
|
#
|
|
|
|
CREATE PACKAGE test2
|
|
|
|
PROCEDURE p1();
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
CREATE PACKAGE BODY test2
|
|
|
|
PROCEDURE p2() BEGIN SELECT 0; END;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
ERROR HY000: PROCEDURE `test.test2.p1` is declared in the package specification but is not defined in the package body
|
|
|
|
DROP PACKAGE test2;
|
|
|
|
CREATE PACKAGE test2
|
|
|
|
FUNCTION f1() RETURNS INT;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
CREATE PACKAGE BODY test2
|
|
|
|
FUNCTION f2() RETURNS INT BEGIN RETURN 10; END;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
ERROR HY000: FUNCTION `test.test2.f1` is declared in the package specification but is not defined in the package body
|
|
|
|
DROP PACKAGE test2;
|
|
|
|
CREATE PACKAGE test2
|
|
|
|
PROCEDURE p1();
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
CREATE PACKAGE BODY test2
|
|
|
|
FUNCTION p1() RETURNS INT BEGIN RETURN 10; END;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
ERROR HY000: PROCEDURE `test.test2.p1` is declared in the package specification but is not defined in the package body
|
|
|
|
DROP PACKAGE test2;
|
|
|
|
CREATE PACKAGE test2
|
|
|
|
PROCEDURE p1();
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
CREATE PACKAGE BODY test2
|
|
|
|
PROCEDURE p1(a INT) BEGIN SELECT 0; END; -- Notice different prototype
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
ERROR HY000: PROCEDURE `test.test2.p1` is declared in the package specification but is not defined in the package body
|
|
|
|
DROP PACKAGE test2;
|
|
|
|
#
|
|
|
|
# Forward declarations in CREATE PACKAGE BODY with missing implementations
|
|
|
|
#
|
|
|
|
CREATE PACKAGE test2
|
|
|
|
PROCEDURE p1();
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
CREATE PACKAGE BODY test2
|
|
|
|
PROCEDURE p1() BEGIN SELECT 0; END;
|
|
|
|
PROCEDURE p2();
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
ERROR HY000: PROCEDURE `test.test2.p2` has a forward declaration but is not defined
|
|
|
|
CREATE PACKAGE BODY test2
|
|
|
|
FUNCTION f1() RETURNS INT;
|
|
|
|
PROCEDURE p1() BEGIN SELECT 0; END;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
ERROR HY000: FUNCTION `test.test2.f1` has a forward declaration but is not defined
|
|
|
|
DROP PACKAGE test2;
|
|
|
|
#
|
|
|
|
# End of 11.4 tests
|
|
|
|
#
|
MDEV-12252 ROW data type for stored function return values
Adding support for the ROW data type in the stored function RETURNS clause:
- explicit ROW(..members...) for both sql_mode=DEFAULT and sql_mode=ORACLE
CREATE FUNCTION f1() RETURNS ROW(a INT, b VARCHAR(32)) ...
- anchored "ROW TYPE OF [db1.]table1" declarations for sql_mode=DEFAULT
CREATE FUNCTION f1() RETURNS ROW TYPE OF test.t1 ...
- anchored "[db1.]table1%ROWTYPE" declarations for sql_mode=ORACLE
CREATE FUNCTION f1() RETURN test.t1%ROWTYPE ...
Adding support for anchored scalar data types in RETURNS clause:
- "TYPE OF [db1.]table1.column1" for sql_mode=DEFAULT
CREATE FUNCTION f1() RETURNS TYPE OF test.t1.column1;
- "[db1.]table1.column1" for sql_mode=ORACLE
CREATE FUNCTION f1() RETURN test.t1.column1%TYPE;
Details:
- Adding a new sql_mode_t parameter to
sp_head::create()
sp_head::sp_head()
sp_package::create()
sp_package::sp_package()
to guarantee early initialization of sp_head::m_sql_mode.
Before this change, this member was not initialized at all during
CREATE FUNCTION/PROCEDURE/PACKAGE statements, and was not used.
Now it needs to be initialized to write properly the
mysql.proc.returns column, according to the create time sql_mode.
- Code refactoring to make the things simpler and functions smaller:
* Adding a new method
Field_row::row_create_fields(THD *thd, List<Spvar_definition> *list)
to make a Virtual_tmp_table with Fields for ROW members
from an explicit definition.
* Adding a new method
Field_row::row_create_fields(THD *thd, const Spvar_definition &def)
to make a Virtual_tmp_table with Fields for ROW members
from an explicit or a table anchored definition.
* Adding a new method
Item_args::add_array_of_item_field(THD *thd, const Virtual_tmp_table &vtable)
to create and array of Item_field corresponding to all Field instances
in a Virtual_tmp_table
* Removing Item_field_row::row_create_items(). It was decomposed
into the new methods described above.
* Moving the code from the loop body in sp_rcontext::init_var_items()
into a separate method Spvar_definition::make_item_field_row(),
to make the code clearer (smaller functions).
make_item_field_row() itself uses the new methods described above.
- Changing the data type of sp_head::m_return_field_def
from Column_definition to Spvar_definition.
So now it supports not only SQL column field types,
but also explicit ROW and anchored ROW data types,
as well as anchored column types.
- Adding a new Column_definition parameter to sp_head::create_result_field().
Before this patch, create_result_field() took the definition only
from m_return_field_def. Now it's also called with a local Column_definition
variable which contains the explicit definition resolved from an
anchored defition.
- Modifying sql_yacc.yy to support the new grammar.
Adding new helper methods:
* sf_return_fill_definition_row()
* sf_return_fill_definition_rowtype_of()
* sf_return_fill_definition_type_of()
- Fixing tests in:
* Virtual_tmp_table::setup_field_pointers() in sql_select.cc
* Send_field::normalize() in field.h
* store_column_type()
to prevent calling Type_handler_row::field_type(),
which is implemented a DBUG_ASSERT(0).
Before this patch the affected methods and functions were called only
for scalar data types. Now ROW is also possible.
- Adding a new virtual method Field::cols()
- Overriding methods:
Item_func_sp::cols()
Item_func_sp::element_index()
Item_func_sp::check_cols()
Item_func_sp::bring_value()
to support the ROW data type.
- Extending the rule sp_return_type to support
* explicit ROW and anchored ROW data types
* anchored scalar data types
- Overriding Field_row::sql_type() to print
the data type of an explicit ROW.
2023-09-25 21:48:01 +04:00
|
|
|
#
|
|
|
|
# Start of 11.7 tests
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# MDEV-12252 ROW data type for stored function return values
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# Testing fixed ROW type with package routines
|
|
|
|
#
|
|
|
|
CREATE PACKAGE pkg
|
|
|
|
FUNCTION f1() RETURNS ROW(a INT, b VARCHAR(32));
|
|
|
|
PROCEDURE p1(r ROW(a INT, b VARCHAR(32)));
|
|
|
|
PROCEDURE p2();
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
CREATE PACKAGE BODY pkg
|
|
|
|
FUNCTION f1() RETURNS ROW(a INT, b VARCHAR(32))
|
|
|
|
BEGIN
|
|
|
|
RETURN ROW(1,'b1');
|
|
|
|
END;
|
|
|
|
PROCEDURE p1(r ROW(a INT, b VARCHAR(32)))
|
|
|
|
BEGIN
|
|
|
|
SELECT r.a, r.b;
|
|
|
|
END;
|
|
|
|
PROCEDURE p2()
|
|
|
|
BEGIN
|
|
|
|
CALL p1(f1());
|
|
|
|
END;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
CALL pkg.p1(pkg.f1());
|
|
|
|
r.a r.b
|
|
|
|
1 b1
|
|
|
|
CALL pkg.p2;
|
|
|
|
r.a r.b
|
|
|
|
1 b1
|
|
|
|
DROP PACKAGE pkg;
|
|
|
|
#
|
|
|
|
# Testing "ROW TYPE OF table" with package routines
|
|
|
|
#
|
|
|
|
CREATE TABLE t1 (a INT, b VARCHAR(32));
|
|
|
|
INSERT INTO t1 VALUES (1,'b1');
|
|
|
|
CREATE PACKAGE pkg
|
|
|
|
FUNCTION f1() RETURNS ROW TYPE OF t1;
|
|
|
|
PROCEDURE p1(r ROW TYPE OF t1);
|
|
|
|
PROCEDURE p2();
|
|
|
|
END;
|
|
|
|
/
|
|
|
|
CREATE PACKAGE BODY pkg
|
|
|
|
FUNCTION f1() RETURNS ROW TYPE OF t1
|
|
|
|
BEGIN
|
|
|
|
DECLARE r ROW TYPE OF t1;
|
|
|
|
SELECT * INTO r FROM t1;
|
|
|
|
RETURN r;
|
|
|
|
END;
|
|
|
|
PROCEDURE p1(r ROW TYPE OF t1)
|
|
|
|
BEGIN
|
|
|
|
SELECT CONCAT(r.a, ' ', r.b);
|
|
|
|
END;
|
|
|
|
PROCEDURE p2()
|
|
|
|
BEGIN
|
|
|
|
CALL p1(f1());
|
|
|
|
END;
|
|
|
|
END;
|
|
|
|
/
|
|
|
|
CALL pkg.p1(pkg.f1());
|
|
|
|
CONCAT(r.a, ' ', r.b)
|
|
|
|
1 b1
|
|
|
|
CALL pkg.p2;
|
|
|
|
CONCAT(r.a, ' ', r.b)
|
|
|
|
1 b1
|
|
|
|
DROP PACKAGE pkg;
|
|
|
|
DROP TABLE t1;
|
|
|
|
#
|
|
|
|
# End of 11.7 tests
|
|
|
|
#
|