Skip to content

Commit fedc3c6

Browse files
committed
MDEV-40790 SELECT INTO row_type_of.field crashes the server
The server crashed on DBUG_ASSERT on a SELECT into: - a `ROW TYPE OF table1` field variable - a `ROW TYPE OF cursor1` field variable Fix: - Adding a class my_var_sp_row_field_by_name - Adding a method sp_rcontext::set_variable_row_field_by_name() - Fixing the DBUG_ASSERT
1 parent 91156c3 commit fedc3c6

5 files changed

Lines changed: 367 additions & 2 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#
2+
# MDEV-40790 SELECT INTO row_type_of.field crashes the server
3+
#
4+
# Into an explicit ROW variable
5+
CREATE TABLE t1 (a INT,b VARCHAR(10));
6+
INSERT INTO t1 VALUES (10,'b10');
7+
CREATE PROCEDURE p1()
8+
BEGIN
9+
DECLARE r0 ROW (a INT, b VARCHAR(10));
10+
SELECT a,b INTO r0 FROM t1;
11+
SELECT r0.a, r0.b;
12+
END;
13+
$$
14+
CALL p1;
15+
r0.a r0.b
16+
10 b10
17+
DROP PROCEDURE p1;
18+
DROP TABLE t1;
19+
# Into an explicit ROW field variable
20+
CREATE TABLE t1 (a INT,b VARCHAR(10));
21+
INSERT INTO t1 VALUES (10,'b10');
22+
CREATE PROCEDURE p1()
23+
BEGIN
24+
DECLARE r0 ROW (a INT, b VARCHAR(10));
25+
SELECT a,b INTO r0.a,r0.b FROM t1;
26+
SELECT r0.a, r0.b;
27+
END;
28+
$$
29+
CALL p1;
30+
r0.a r0.b
31+
10 b10
32+
DROP PROCEDURE p1;
33+
DROP TABLE t1;
34+
# Into an explicit ROW field variable - non-existing field
35+
CREATE TABLE t1 (a INT,b VARCHAR(10));
36+
INSERT INTO t1 VALUES (10,'b10');
37+
CREATE PROCEDURE p1()
38+
BEGIN
39+
DECLARE r0 ROW (a INT, b VARCHAR(10));
40+
SELECT a,b INTO r0.a,r0.b1_non_existing FROM t1;
41+
END;
42+
$$
43+
ERROR HY000: Row variable 'r0' does not have a field 'b1_non_existing'
44+
DROP TABLE t1;
45+
# Into a `ROW TYPE OF table1` variable
46+
CREATE TABLE t1 (a INT,b VARCHAR(10));
47+
INSERT INTO t1 VALUES (10,'b10');
48+
CREATE PROCEDURE p1()
49+
BEGIN
50+
DECLARE r0 ROW TYPE OF t1;
51+
SELECT a,b INTO r0 FROM t1;
52+
SELECT r0.a, r0.b;
53+
END;
54+
$$
55+
CALL p1;
56+
r0.a r0.b
57+
10 b10
58+
DROP PROCEDURE p1;
59+
DROP TABLE t1;
60+
# Into a `ROW TYPE OF table1` field variable
61+
CREATE TABLE t1 (a INT,b VARCHAR(10));
62+
INSERT INTO t1 VALUES (10,'b10');
63+
CREATE PROCEDURE p1()
64+
BEGIN
65+
DECLARE r0 ROW TYPE OF t1;
66+
SELECT a,b INTO r0.a,r0.b FROM t1;
67+
SELECT r0.a, r0.b;
68+
END;
69+
$$
70+
CALL p1;
71+
r0.a r0.b
72+
10 b10
73+
DROP PROCEDURE p1;
74+
DROP TABLE t1;
75+
# Into a `ROW TYPE OF table1` field variable - non-existing field
76+
CREATE TABLE t1 (a INT,b VARCHAR(10));
77+
INSERT INTO t1 VALUES (10,'b10');
78+
CREATE PROCEDURE p1()
79+
BEGIN
80+
DECLARE r0 ROW TYPE OF t1;
81+
SELECT a,b INTO r0.a,r0.b1_non_existing FROM t1;
82+
END;
83+
$$
84+
CALL p1;
85+
ERROR HY000: Row variable 'r0' does not have a field 'b1_non_existing'
86+
DROP PROCEDURE p1;
87+
DROP TABLE t1;
88+
# Into a `ROW TYPE OF cursor1` variable
89+
CREATE TABLE t1 (a INT,b VARCHAR(10));
90+
INSERT INTO t1 VALUES (10,'b10');
91+
CREATE PROCEDURE p1()
92+
BEGIN
93+
DECLARE c1 CURSOR FOR SELECT * FROM t1;
94+
BEGIN
95+
DECLARE r0 ROW TYPE OF c1;
96+
SELECT a,b INTO r0 FROM t1;
97+
SELECT r0.a, r0.b;
98+
END;
99+
END;
100+
$$
101+
CALL p1;
102+
r0.a r0.b
103+
10 b10
104+
DROP PROCEDURE p1;
105+
DROP TABLE t1;
106+
# Into a `ROW TYPE OF cursor1` field variable
107+
CREATE TABLE t1 (a INT,b VARCHAR(10));
108+
INSERT INTO t1 VALUES (10,'b10');
109+
CREATE PROCEDURE p1()
110+
BEGIN
111+
DECLARE c1 CURSOR FOR SELECT * FROM t1;
112+
BEGIN
113+
DECLARE r0 ROW TYPE OF c1;
114+
SELECT a,b INTO r0.a,r0.b FROM t1;
115+
SELECT r0.a, r0.b;
116+
END;
117+
END;
118+
$$
119+
CALL p1;
120+
r0.a r0.b
121+
10 b10
122+
DROP PROCEDURE p1;
123+
DROP TABLE t1;
124+
# Into a `ROW TYPE OF cursor1` field variable - non-existing field
125+
CREATE TABLE t1 (a INT,b VARCHAR(10));
126+
INSERT INTO t1 VALUES (10,'b10');
127+
CREATE PROCEDURE p1()
128+
BEGIN
129+
DECLARE c1 CURSOR FOR SELECT * FROM t1;
130+
BEGIN
131+
DECLARE r0 ROW TYPE OF c1;
132+
SELECT a,b INTO r0.a,r0.b1_non_existing FROM t1;
133+
END;
134+
END;
135+
$$
136+
CALL p1;
137+
ERROR HY000: Row variable 'r0' does not have a field 'b1_non_existing'
138+
DROP PROCEDURE p1;
139+
DROP TABLE t1;
140+
# End of 12.3 tests
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
--echo #
2+
--echo # MDEV-40790 SELECT INTO row_type_of.field crashes the server
3+
--echo #
4+
5+
6+
--echo # Into an explicit ROW variable
7+
8+
CREATE TABLE t1 (a INT,b VARCHAR(10));
9+
INSERT INTO t1 VALUES (10,'b10');
10+
DELIMITER $$;
11+
CREATE PROCEDURE p1()
12+
BEGIN
13+
DECLARE r0 ROW (a INT, b VARCHAR(10));
14+
SELECT a,b INTO r0 FROM t1;
15+
SELECT r0.a, r0.b;
16+
END;
17+
$$
18+
DELIMITER ;$$
19+
CALL p1;
20+
DROP PROCEDURE p1;
21+
DROP TABLE t1;
22+
23+
24+
--echo # Into an explicit ROW field variable
25+
26+
CREATE TABLE t1 (a INT,b VARCHAR(10));
27+
INSERT INTO t1 VALUES (10,'b10');
28+
DELIMITER $$;
29+
CREATE PROCEDURE p1()
30+
BEGIN
31+
DECLARE r0 ROW (a INT, b VARCHAR(10));
32+
SELECT a,b INTO r0.a,r0.b FROM t1;
33+
SELECT r0.a, r0.b;
34+
END;
35+
$$
36+
DELIMITER ;$$
37+
CALL p1;
38+
DROP PROCEDURE p1;
39+
DROP TABLE t1;
40+
41+
42+
--echo # Into an explicit ROW field variable - non-existing field
43+
44+
CREATE TABLE t1 (a INT,b VARCHAR(10));
45+
INSERT INTO t1 VALUES (10,'b10');
46+
DELIMITER $$;
47+
--error ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD
48+
CREATE PROCEDURE p1()
49+
BEGIN
50+
DECLARE r0 ROW (a INT, b VARCHAR(10));
51+
SELECT a,b INTO r0.a,r0.b1_non_existing FROM t1;
52+
END;
53+
$$
54+
DELIMITER ;$$
55+
DROP TABLE t1;
56+
57+
58+
--echo # Into a `ROW TYPE OF table1` variable
59+
60+
CREATE TABLE t1 (a INT,b VARCHAR(10));
61+
INSERT INTO t1 VALUES (10,'b10');
62+
DELIMITER $$;
63+
CREATE PROCEDURE p1()
64+
BEGIN
65+
DECLARE r0 ROW TYPE OF t1;
66+
SELECT a,b INTO r0 FROM t1;
67+
SELECT r0.a, r0.b;
68+
END;
69+
$$
70+
DELIMITER ;$$
71+
CALL p1;
72+
DROP PROCEDURE p1;
73+
DROP TABLE t1;
74+
75+
76+
--echo # Into a `ROW TYPE OF table1` field variable
77+
78+
CREATE TABLE t1 (a INT,b VARCHAR(10));
79+
INSERT INTO t1 VALUES (10,'b10');
80+
DELIMITER $$;
81+
CREATE PROCEDURE p1()
82+
BEGIN
83+
DECLARE r0 ROW TYPE OF t1;
84+
SELECT a,b INTO r0.a,r0.b FROM t1;
85+
SELECT r0.a, r0.b;
86+
END;
87+
$$
88+
DELIMITER ;$$
89+
CALL p1;
90+
DROP PROCEDURE p1;
91+
DROP TABLE t1;
92+
93+
94+
--echo # Into a `ROW TYPE OF table1` field variable - non-existing field
95+
96+
CREATE TABLE t1 (a INT,b VARCHAR(10));
97+
INSERT INTO t1 VALUES (10,'b10');
98+
DELIMITER $$;
99+
CREATE PROCEDURE p1()
100+
BEGIN
101+
DECLARE r0 ROW TYPE OF t1;
102+
SELECT a,b INTO r0.a,r0.b1_non_existing FROM t1;
103+
END;
104+
$$
105+
DELIMITER ;$$
106+
--error ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD
107+
CALL p1;
108+
DROP PROCEDURE p1;
109+
DROP TABLE t1;
110+
111+
112+
--echo # Into a `ROW TYPE OF cursor1` variable
113+
114+
CREATE TABLE t1 (a INT,b VARCHAR(10));
115+
INSERT INTO t1 VALUES (10,'b10');
116+
DELIMITER $$;
117+
CREATE PROCEDURE p1()
118+
BEGIN
119+
DECLARE c1 CURSOR FOR SELECT * FROM t1;
120+
BEGIN
121+
DECLARE r0 ROW TYPE OF c1;
122+
SELECT a,b INTO r0 FROM t1;
123+
SELECT r0.a, r0.b;
124+
END;
125+
END;
126+
$$
127+
DELIMITER ;$$
128+
CALL p1;
129+
DROP PROCEDURE p1;
130+
DROP TABLE t1;
131+
132+
133+
--echo # Into a `ROW TYPE OF cursor1` field variable
134+
135+
CREATE TABLE t1 (a INT,b VARCHAR(10));
136+
INSERT INTO t1 VALUES (10,'b10');
137+
DELIMITER $$;
138+
CREATE PROCEDURE p1()
139+
BEGIN
140+
DECLARE c1 CURSOR FOR SELECT * FROM t1;
141+
BEGIN
142+
DECLARE r0 ROW TYPE OF c1;
143+
SELECT a,b INTO r0.a,r0.b FROM t1;
144+
SELECT r0.a, r0.b;
145+
END;
146+
END;
147+
$$
148+
DELIMITER ;$$
149+
CALL p1;
150+
DROP PROCEDURE p1;
151+
DROP TABLE t1;
152+
153+
154+
--echo # Into a `ROW TYPE OF cursor1` field variable - non-existing field
155+
156+
CREATE TABLE t1 (a INT,b VARCHAR(10));
157+
INSERT INTO t1 VALUES (10,'b10');
158+
DELIMITER $$;
159+
CREATE PROCEDURE p1()
160+
BEGIN
161+
DECLARE c1 CURSOR FOR SELECT * FROM t1;
162+
BEGIN
163+
DECLARE r0 ROW TYPE OF c1;
164+
SELECT a,b INTO r0.a,r0.b1_non_existing FROM t1;
165+
END;
166+
END;
167+
$$
168+
DELIMITER ;$$
169+
--error ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD
170+
CALL p1;
171+
DROP PROCEDURE p1;
172+
DROP TABLE t1;
173+
174+
--echo # End of 12.3 tests

sql/sp_rcontext.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,20 @@ int sp_rcontext::set_variable_row_field(THD *thd, uint var_idx, uint field_idx,
694694
}
695695

696696

697+
int sp_rcontext::set_variable_row_field_by_name(THD *thd, uint var_idx,
698+
const Lex_ident_sys_st &field_name,
699+
Item **value)
700+
{
701+
DBUG_ENTER("sp_rcontext::set_variable_row_field");
702+
DBUG_ASSERT(value);
703+
uint field_idx= 0;
704+
if (find_row_field_by_name_or_error(&field_idx, var_idx, field_name))
705+
DBUG_RETURN(true);
706+
Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx);
707+
DBUG_RETURN(thd->sp_eval_expr(vtable->field[field_idx], value));
708+
}
709+
710+
697711
int sp_rcontext::set_variable_row(THD *thd, uint var_idx, List<Item> &items)
698712
{
699713
DBUG_ENTER("sp_rcontext::set_variable_row");

sql/sp_rcontext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ class sp_rcontext : public Sql_alloc
209209
int set_variable(THD *thd, uint var_idx, Item **value);
210210
int set_variable_row_field(THD *thd, uint var_idx, uint field_idx,
211211
Item **value);
212+
int set_variable_row_field_by_name(THD *thd, uint var_idx,
213+
const Lex_ident_sys_st &field_name,
214+
Item **value);
212215
int set_variable_row(THD *thd, uint var_idx, List<Item> &items);
213216

214217
int set_variable_composite_field_by_key(THD *thd,

0 commit comments

Comments
 (0)