Skip to content

Commit 2cb0e55

Browse files
committed
MDEV-37430 sql_mode=ORACLE: TYPE definitions in PACKAGE BODY
Adding support for TYPE declarations for RECORDs and assoc arrays.
1 parent 033471a commit 2cb0e55

File tree

9 files changed

+306
-6
lines changed

9 files changed

+306
-6
lines changed

mysql-test/suite/compat/oracle/r/sp-record.result

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,3 +773,39 @@ $$
773773
r0 t1 r2
774774
1a 1a 1a
775775
# End of 11.8 tests
776+
# Start of 12.2 tests
777+
#
778+
# MDEV-37430 sql_mode=ORACLE: TYPE definitions in PACKAGE BODY
779+
#
780+
#
781+
# PACKAGE BODY wide record declarations
782+
#
783+
SET sql_mode=ORACLE;
784+
CREATE PACKAGE pkg1 AS
785+
PROCEDURE p1;
786+
END;
787+
$$
788+
CREATE PACKAGE BODY pkg1 AS
789+
TYPE record_t IS RECORD (a INT, b VARCHAR(32));
790+
PROCEDURE p1 AS
791+
r record_t;
792+
BEGIN
793+
r.a:= 10;
794+
r.b:= 'test';
795+
CREATE TABLE t1 AS SELECT r.a AS a, r.b AS b;
796+
SELECT * FROM t1;
797+
SHOW CREATE TABLE t1;
798+
DROP TABLE t1;
799+
END;
800+
END;
801+
$$
802+
CALL pkg1.p1;
803+
a b
804+
10 test
805+
Table Create Table
806+
t1 CREATE TABLE "t1" (
807+
"a" int(11) DEFAULT NULL,
808+
"b" varchar(32) DEFAULT NULL
809+
)
810+
DROP PACKAGE pkg1;
811+
# End of 12.2 tests

mysql-test/suite/compat/oracle/t/sp-record.test

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,3 +838,40 @@ $$
838838
DELIMITER ;$$
839839

840840
--echo # End of 11.8 tests
841+
842+
843+
--echo # Start of 12.2 tests
844+
845+
--echo #
846+
--echo # MDEV-37430 sql_mode=ORACLE: TYPE definitions in PACKAGE BODY
847+
--echo #
848+
849+
--echo #
850+
--echo # PACKAGE BODY wide record declarations
851+
--echo #
852+
853+
SET sql_mode=ORACLE;
854+
DELIMITER $$;
855+
CREATE PACKAGE pkg1 AS
856+
PROCEDURE p1;
857+
END;
858+
$$
859+
CREATE PACKAGE BODY pkg1 AS
860+
TYPE record_t IS RECORD (a INT, b VARCHAR(32));
861+
PROCEDURE p1 AS
862+
r record_t;
863+
BEGIN
864+
r.a:= 10;
865+
r.b:= 'test';
866+
CREATE TABLE t1 AS SELECT r.a AS a, r.b AS b;
867+
SELECT * FROM t1;
868+
SHOW CREATE TABLE t1;
869+
DROP TABLE t1;
870+
END;
871+
END;
872+
$$
873+
DELIMITER ;$$
874+
CALL pkg1.p1;
875+
DROP PACKAGE pkg1;
876+
877+
--echo # End of 12.2 tests
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--echo #
2+
--echo # MDEV-37430 sql_mode=ORACLE: TYPE definitions in PACKAGE BODY
3+
--echo # TYPEs in PACKAGE BODY, variables in PROCEDURE
4+
--echo #
5+
6+
DELIMITER $$;
7+
CREATE PACKAGE pkg1 AS
8+
PROCEDURE p1;
9+
END;
10+
$$
11+
CREATE PACKAGE BODY pkg1 AS
12+
TYPE record_t IS RECORD (a INT, b VARCHAR(32));
13+
TYPE assoc0_t IS TABLE OF record_t INDEX BY INT;
14+
TYPE assoc1_t IS TABLE OF VARCHAR(32) INDEX BY INT;
15+
PROCEDURE p1 AS
16+
a0 assoc0_t;
17+
a1 assoc1_t;
18+
BEGIN
19+
20+
a0(10):= record_t(10,'test');
21+
SELECT a0(10).a AS a, a0(10).b AS b;
22+
CREATE TABLE t1 AS SELECT a0(10).a AS a, a0(10).b AS b;
23+
SELECT * FROM t1;
24+
SHOW CREATE TABLE t1;
25+
SELECT * FROM t1;
26+
DROP TABLE t1;
27+
28+
a1(10):= 'test';
29+
SELECT a1(10) AS a1;
30+
CREATE TABLE t1 AS SELECT a1(10) AS a;
31+
SELECT * FROM t1;
32+
SHOW CREATE TABLE t1;
33+
SELECT * FROM t1;
34+
DROP TABLE t1;
35+
END;
36+
END;
37+
$$
38+
DELIMITER ;$$
39+
40+
CALL pkg1.p1;
41+
42+
DROP PACKAGE pkg1;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--echo #
2+
--echo # MDEV-37430 sql_mode=ORACLE: TYPE definitions in PACKAGE BODY
3+
--echo # TYPEs in PACKAGE BODY, variables in PACKAGE BODY
4+
--echo #
5+
6+
DELIMITER $$;
7+
CREATE PACKAGE pkg1 AS
8+
PROCEDURE p1;
9+
END;
10+
$$
11+
CREATE PACKAGE BODY pkg1 AS
12+
TYPE record_t IS RECORD (a INT, b VARCHAR(32));
13+
TYPE assoc0_t IS TABLE OF record_t INDEX BY INT;
14+
TYPE assoc1_t IS TABLE OF VARCHAR(32) INDEX BY INT;
15+
a0 assoc0_t;
16+
a1 assoc1_t;
17+
PROCEDURE p1 AS
18+
BEGIN
19+
20+
a0(10):= record_t(10,'test');
21+
SELECT a0(10).a AS a, a0(10).b AS b;
22+
CREATE TABLE t1 AS SELECT a0(10).a AS a, a0(10).b AS b;
23+
SELECT * FROM t1;
24+
SHOW CREATE TABLE t1;
25+
SELECT * FROM t1;
26+
DROP TABLE t1;
27+
28+
a1(10):= 'test';
29+
SELECT a1(10) AS a1;
30+
CREATE TABLE t1 AS SELECT a1(10) AS a;
31+
SELECT * FROM t1;
32+
SHOW CREATE TABLE t1;
33+
SELECT * FROM t1;
34+
DROP TABLE t1;
35+
END;
36+
END;
37+
$$
38+
DELIMITER ;$$
39+
40+
CALL pkg1.p1;
41+
42+
DROP PACKAGE pkg1;

plugin/type_assoc_array/mysql-test/type_assoc_array/sp-assoc-array-package.result

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,115 @@ x02a
6565
marks(v2)
6666
x02b
6767
DROP PACKAGE pkg;
68+
#
69+
# MDEV-37430 sql_mode=ORACLE: TYPE definitions in PACKAGE BODY
70+
# TYPEs in PACKAGE BODY, variables in PROCEDURE
71+
#
72+
CREATE PACKAGE pkg1 AS
73+
PROCEDURE p1;
74+
END;
75+
$$
76+
CREATE PACKAGE BODY pkg1 AS
77+
TYPE record_t IS RECORD (a INT, b VARCHAR(32));
78+
TYPE assoc0_t IS TABLE OF record_t INDEX BY INT;
79+
TYPE assoc1_t IS TABLE OF VARCHAR(32) INDEX BY INT;
80+
PROCEDURE p1 AS
81+
a0 assoc0_t;
82+
a1 assoc1_t;
83+
BEGIN
84+
a0(10):= record_t(10,'test');
85+
SELECT a0(10).a AS a, a0(10).b AS b;
86+
CREATE TABLE t1 AS SELECT a0(10).a AS a, a0(10).b AS b;
87+
SELECT * FROM t1;
88+
SHOW CREATE TABLE t1;
89+
SELECT * FROM t1;
90+
DROP TABLE t1;
91+
a1(10):= 'test';
92+
SELECT a1(10) AS a1;
93+
CREATE TABLE t1 AS SELECT a1(10) AS a;
94+
SELECT * FROM t1;
95+
SHOW CREATE TABLE t1;
96+
SELECT * FROM t1;
97+
DROP TABLE t1;
98+
END;
99+
END;
100+
$$
101+
CALL pkg1.p1;
102+
a b
103+
10 test
104+
a b
105+
10 test
106+
Table Create Table
107+
t1 CREATE TABLE "t1" (
108+
"a" int(11) DEFAULT NULL,
109+
"b" varchar(32) DEFAULT NULL
110+
)
111+
a b
112+
10 test
113+
a1
114+
test
115+
a
116+
test
117+
Table Create Table
118+
t1 CREATE TABLE "t1" (
119+
"a" varchar(32) DEFAULT NULL
120+
)
121+
a
122+
test
123+
DROP PACKAGE pkg1;
124+
#
125+
# MDEV-37430 sql_mode=ORACLE: TYPE definitions in PACKAGE BODY
126+
# TYPEs in PACKAGE BODY, variables in PACKAGE BODY
127+
#
128+
CREATE PACKAGE pkg1 AS
129+
PROCEDURE p1;
130+
END;
131+
$$
132+
CREATE PACKAGE BODY pkg1 AS
133+
TYPE record_t IS RECORD (a INT, b VARCHAR(32));
134+
TYPE assoc0_t IS TABLE OF record_t INDEX BY INT;
135+
TYPE assoc1_t IS TABLE OF VARCHAR(32) INDEX BY INT;
136+
a0 assoc0_t;
137+
a1 assoc1_t;
138+
PROCEDURE p1 AS
139+
BEGIN
140+
a0(10):= record_t(10,'test');
141+
SELECT a0(10).a AS a, a0(10).b AS b;
142+
CREATE TABLE t1 AS SELECT a0(10).a AS a, a0(10).b AS b;
143+
SELECT * FROM t1;
144+
SHOW CREATE TABLE t1;
145+
SELECT * FROM t1;
146+
DROP TABLE t1;
147+
a1(10):= 'test';
148+
SELECT a1(10) AS a1;
149+
CREATE TABLE t1 AS SELECT a1(10) AS a;
150+
SELECT * FROM t1;
151+
SHOW CREATE TABLE t1;
152+
SELECT * FROM t1;
153+
DROP TABLE t1;
154+
END;
155+
END;
156+
$$
157+
CALL pkg1.p1;
158+
a b
159+
10 test
160+
a b
161+
10 test
162+
Table Create Table
163+
t1 CREATE TABLE "t1" (
164+
"a" int(11) DEFAULT NULL,
165+
"b" varchar(32) DEFAULT NULL
166+
)
167+
a b
168+
10 test
169+
a1
170+
test
171+
a
172+
test
173+
Table Create Table
174+
t1 CREATE TABLE "t1" (
175+
"a" varchar(32) DEFAULT NULL
176+
)
177+
a
178+
test
179+
DROP PACKAGE pkg1;

plugin/type_assoc_array/mysql-test/type_assoc_array/sp-assoc-array-package.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ SET NAMES utf8mb4;
77

88
--source sp-assoc-array-package-00.inc
99
--source sp-assoc-array-package-01.inc
10+
--source sp-assoc-array-package-02.inc
11+
--source sp-assoc-array-package-03.inc

sql/sql_lex.cc

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6759,6 +6759,27 @@ void LEX::set_stmt_init()
67596759
};
67606760

67616761

6762+
/**
6763+
Find a local or a package body type declaration by name
6764+
@param IN name - the data type name
6765+
@retval - the data type (if found), or NULL otherwise.
6766+
*/
6767+
const sp_type_def *LEX::find_type_def(const LEX_CSTRING &name) const
6768+
{
6769+
DBUG_ASSERT(spcont);
6770+
const sp_type_def *def= spcont->find_type_def(name, false);
6771+
if (def)
6772+
return def;
6773+
if (sphead->m_parent)
6774+
{
6775+
// Find a package body type definition
6776+
return sphead->m_parent->get_parse_context()->
6777+
child_context(0)->find_type_def(name, true);
6778+
}
6779+
return nullptr;
6780+
}
6781+
6782+
67626783
/**
67636784
Find a local or a package body variable by name.
67646785
@param IN name - the variable name
@@ -10176,8 +10197,9 @@ bool LEX::call_statement_start_or_lvalue_assign(THD *thd,
1017610197
Qualified_ident *ident)
1017710198
{
1017810199
sp_variable *spv;
10200+
const Sp_rcontext_handler *rh;
1017910201
if (spcont &&
10180-
(spv= spcont->find_variable(&ident->part(0), false)) &&
10202+
(spv= find_variable(&ident->part(0), &rh)) &&
1018110203
(likely(spv->field_def.type_handler()->has_methods())))
1018210204
{
1018310205
ident->set_spvar(spv);
@@ -12992,7 +13014,7 @@ bool LEX::set_field_type_typedef(Lex_field_type_st *type,
1299213014
*is_typedef= false;
1299313015
if (spcont)
1299413016
{
12995-
if (const sp_type_def *composite= spcont->find_type_def(name, false))
13017+
if (const sp_type_def *composite= find_type_def(name))
1299613018
{
1299713019
type->set(composite->type_handler(), NULL);
1299813020
last_field->set_attr_const_void_ptr(0, composite);

sql/sql_lex.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3929,6 +3929,7 @@ struct LEX: public Query_tables_list
39293929
bool direct_call(THD *thd, const Qualified_ident *ident, List<Item> *args);
39303930

39313931
bool assoc_assign_start(THD *thd, Qualified_ident *ident);
3932+
const sp_type_def *find_type_def(const LEX_CSTRING &name) const;
39323933
sp_variable *find_variable(const LEX_CSTRING *name,
39333934
sp_pcontext **ctx,
39343935
const Sp_rcontext_handler **rh) const;

sql/sql_yacc.yy

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,7 @@ rule:
20392039
%type <spblock> opt_sp_decl_body_list
20402040
%type <spblock> sp_decl_variable_list
20412041
%type <spblock> sp_decl_variable_list_anchored
2042+
%type <spblock> sp_decl_type
20422043
%type <spblock> sp_decl_non_handler
20432044
%type <spblock> sp_decl_non_handler_list
20442045
%type <spblock> sp_decl_handler
@@ -11045,6 +11046,7 @@ function_call_generic:
1104511046
Item *item= NULL;
1104611047
const sp_type_def *tdef= NULL;
1104711048
const Lex_ident_sys ident(thd, &$1);
11049+
const Sp_rcontext_handler *rh;
1104811050
sp_variable *spv= NULL;
1104911051
bool allow_field_accessor= false;
1105011052

@@ -11083,13 +11085,12 @@ function_call_generic:
1108311085
{
1108411086
// Found a constructor with a proper argument count
1108511087
}
11086-
else if (Lex->spcont &&
11087-
(tdef= Lex->spcont->find_type_def(ident, false)))
11088+
else if (Lex->spcont && (tdef= Lex->find_type_def(ident)))
1108811089
{
1108911090
item= tdef->make_constructor_item(thd, $4);
1109011091
}
1109111092
else if (Lex->spcont &&
11092-
(spv= Lex->spcont->find_variable(&ident, false)) &&
11093+
(spv= Lex->find_variable(&ident, &rh)) &&
1109311094
spv->type_handler()->has_functors())
1109411095
{
1109511096
const char *end= $6.str ? $6.end() : $5.end();
@@ -19574,6 +19575,7 @@ sf_return_type:
1957419575

1957519576
package_implementation_item_declaration:
1957619577
sp_decl_variable_list ';'
19578+
| sp_decl_type ';'
1957719579
;
1957819580

1957919581
sp_package_function_body:
@@ -20460,7 +20462,11 @@ sp_decl_non_handler:
2046020462
$$.vars= $$.conds= $$.hndlrs= 0;
2046120463
$$.curs= 1;
2046220464
}
20463-
| typed_ident IS RECORD_SYM rec_type_body
20465+
| sp_decl_type
20466+
;
20467+
20468+
sp_decl_type:
20469+
typed_ident IS RECORD_SYM rec_type_body
2046420470
{
2046520471
if (unlikely(Lex->declare_type_record(thd, $1, $4)))
2046620472
MYSQL_YYABORT;

0 commit comments

Comments
 (0)