You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Copy file name to clipboardExpand all lines: mysql-test/main/sp-anchor-row-type-table.result
+85Lines changed: 85 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -852,3 +852,88 @@ DROP TABLE t1;
852
852
#
853
853
# End of 10.4 tests
854
854
#
855
+
#
856
+
# Start of 11.7 tests
857
+
#
858
+
#
859
+
# MDEV-12252 ROW data type for stored function return values
860
+
#
861
+
CREATE FUNCTION f1() RETURNS ROW TYPE OF step1.step2.step3 RETURN ROW(1,2);
862
+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.step3 RETURN ROW(1,2)' at line 1
863
+
CREATE FUNCTION f1() RETURNS ROW TYPE OF t1 RETURN ROW(1,2);
864
+
SHOW CREATE FUNCTION f1;
865
+
Function sql_mode Create Function character_set_client collation_connection Database Collation
866
+
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS ROW TYPE OF `test`.`t1`
CREATE FUNCTION f1() RETURNS ROW TYPE OF test.t1 RETURN ROW(1,2);
872
+
SHOW CREATE FUNCTION f1;
873
+
Function sql_mode Create Function character_set_client collation_connection Database Collation
874
+
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS ROW TYPE OF `test`.`t1`
CREATE FUNCTION f1() RETURNS ROW TYPE OF test.t1 RETURN (SELECT * FROM t1);
881
+
SHOW CREATE FUNCTION f1;
882
+
Function sql_mode Create Function character_set_client collation_connection Database Collation
883
+
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS ROW TYPE OF `test`.`t1`
884
+
RETURN (SELECT * FROM t1) latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
885
+
CREATE PROCEDURE p1()
886
+
BEGIN
887
+
DECLARE r ROW TYPE OF t1 DEFAULT f1();
888
+
SELECT r.a, r.b;
889
+
END;
890
+
$$
891
+
CALL p1();
892
+
r.a r.b
893
+
NULL NULL
894
+
SELECT f1();
895
+
ERROR 21000: Operand should contain 1 column(s)
896
+
SELECT f1()=ROW(1,'b1') AS c;
897
+
c
898
+
NULL
899
+
SELECT f1()=ROW(NULL,NULL) AS c;
900
+
c
901
+
NULL
902
+
INSERT INTO t1 VALUES (1,'b1');
903
+
CALL p1();
904
+
r.a r.b
905
+
1 b1
906
+
SELECT f1();
907
+
ERROR 21000: Operand should contain 1 column(s)
908
+
SELECT f1()=ROW(1,'b1') AS c;
909
+
c
910
+
1
911
+
SELECT f1()=ROW(1,'') AS c;
912
+
c
913
+
0
914
+
SELECT f1()=ROW(2,'b1') AS c;
915
+
c
916
+
0
917
+
SELECT f1()=ROW(1,NULL) AS c;
918
+
c
919
+
NULL
920
+
SELECT f1()=ROW(NULL,'b1') AS c;
921
+
c
922
+
NULL
923
+
SHOW CREATE FUNCTION f1;
924
+
Function sql_mode Create Function character_set_client collation_connection Database Collation
925
+
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS ROW TYPE OF `test`.`t1`
926
+
RETURN (SELECT * FROM t1) latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
# MDEV-12252 ROW data type for stored function return values
1079
+
#
1080
+
CREATE FUNCTION f1() RETURNS TYPE OF a RETURN 1;
1081
+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'RETURN 1' at line 1
1082
+
CREATE FUNCTION f1() RETURNS TYPE OF t1.a RETURN (SELECT min(a) FROM t1);
1083
+
SHOW CREATE FUNCTION f1;
1084
+
Function sql_mode Create Function character_set_client collation_connection Database Collation
1085
+
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS TYPE OF `test`.`t1`.`a`
1086
+
RETURN (SELECT min(a) FROM t1) latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
1087
+
SELECT f1();
1088
+
ERROR 42S02: Table 'test.t1' doesn't exist
1089
+
CREATE TABLE t1 (b INT);
1090
+
SELECT f1();
1091
+
ERROR 42S22: Unknown column 'a' in 't1'
1092
+
DROP TABLE t1;
1093
+
DROP FUNCTION f1;
1094
+
CREATE DATABASE db1;
1095
+
CREATE FUNCTION db1.f1() RETURNS TYPE OF db1.t1.a
1096
+
BEGIN
1097
+
RETURN (SELECT min(a) FROM t1);
1098
+
END;
1099
+
$$
1100
+
SHOW CREATE FUNCTION db1.f1;
1101
+
Function sql_mode Create Function character_set_client collation_connection Database Collation
1102
+
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS TYPE OF `db1`.`t1`.`a`
1103
+
BEGIN
1104
+
RETURN (SELECT min(a) FROM t1);
1105
+
END latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
1106
+
SELECT db1.f1();
1107
+
ERROR 42S02: Table 'db1.t1' doesn't exist
1108
+
CREATE TABLE db1.t1 (b TIME);
1109
+
SELECT db1.f1();
1110
+
ERROR 42S22: Unknown column 'a' in 't1'
1111
+
DROP TABLE db1.t1;
1112
+
CREATE TABLE db1.t1 (a TIME);
1113
+
SELECT db1.f1();
1114
+
db1.f1()
1115
+
NULL
1116
+
INSERT INTO db1.t1 VALUES ('10:20:30');
1117
+
SELECT db1.f1();
1118
+
db1.f1()
1119
+
10:20:30
1120
+
DROP TABLE db1.t1;
1121
+
DROP FUNCTION db1.f1;
1122
+
DROP DATABASE db1;
1123
+
CREATE TABLE t1 (a TIME);
1124
+
CREATE FUNCTION f1() RETURNS TYPE OF test.t1.a RETURN (SELECT min(a) FROM t1);
1125
+
SHOW CREATE FUNCTION f1;
1126
+
Function sql_mode Create Function character_set_client collation_connection Database Collation
1127
+
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS TYPE OF `test`.`t1`.`a`
1128
+
RETURN (SELECT min(a) FROM t1) latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
1129
+
SELECT f1();
1130
+
f1()
1131
+
NULL
1132
+
DROP FUNCTION f1;
1133
+
DROP TABLE t1;
1134
+
CREATE TABLE t1 (a TIME);
1135
+
CREATE FUNCTION f1() RETURNS TYPE OF t1.a
1136
+
BEGIN
1137
+
RETURN (SELECT min(a) FROM t1);
1138
+
END;
1139
+
$$
1140
+
SHOW CREATE FUNCTION f1;
1141
+
Function sql_mode Create Function character_set_client collation_connection Database Collation
1142
+
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS TYPE OF `test`.`t1`.`a`
1143
+
BEGIN
1144
+
RETURN (SELECT min(a) FROM t1);
1145
+
END latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
0 commit comments