Skip to content

Commit 5518c32

Browse files
MDEV-23178: Qualified asterisk not supported in INSERT .. RETURNING
Analysis: When we have INSERT/REPLACE returning with qualified asterisk in the RETURNING clause, '*' is not resolved properly because of wrong context. context->table_list is NULL or has incorrect table because context->table_list has tables from the FROM clause. For INSERT/REPLACE...SELECT...RETURNING, context->table_list has table we are inserting from. While in other INSERT/REPLACE syntax, context->table_list is NULL because there is no FROM clause. Fix: If filling fields instead of '*' for qualified asterisk in RETURNING, use first_name_resolution_table for correct resolution of item.
1 parent 091743c commit 5518c32

File tree

8 files changed

+283
-17
lines changed

8 files changed

+283
-17
lines changed

mysql-test/main/insert_returning.result

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ total val1 id1 && id1 id1 UPPER(val1) f(id1)
8989
ANALYZE INSERT INTO t1(id1,val1) VALUES(13,'l') RETURNING *;
9090
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
9191
1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
92+
INSERT INTO t1(id1,val1) VALUES(14,'m') RETURNING t1.*;
93+
id1 val1
94+
14 m
9295
TRUNCATE TABLE t1;
9396
#
9497
# Multiple values in one insert statement...RETURNING
@@ -182,6 +185,9 @@ id val1 id1 && id1 id1|id1 UPPER(val1) f(id1)
182185
ANALYZE INSERT INTO t1 VALUES(25,'a'),(26,'b') RETURNING *;
183186
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
184187
1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
188+
ANALYZE INSERT INTO t1 VALUES(27,'c'),(28,'d') RETURNING t1.*;
189+
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
190+
1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
185191
#
186192
# INSERT...ON DUPLICATE KEY UPDATE...RETURNING
187193
#
@@ -250,10 +256,14 @@ ANALYZE INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE
250256
val='k' RETURNING *;
251257
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
252258
1 INSERT ins_duplicate ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
259+
INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE
260+
val='l' RETURNING ins_duplicate.*;
261+
id val
262+
2 l
253263
SELECT * FROM ins_duplicate;
254264
id val
255265
1 a
256-
2 k
266+
2 l
257267
3 c
258268
4 d
259269
#
@@ -327,6 +337,9 @@ total val1 id1 && id1 id1|id1 UPPER(val1) f(id1)
327337
ANALYZE INSERT INTO t1 SET id1=12, val1='l' RETURNING *;
328338
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
329339
1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
340+
INSERT INTO t1 SET id1= 13, val1= 'm' RETURNING t1.*;
341+
id1 val1
342+
13 m
330343
SELECT * FROM t1;
331344
id1 val1
332345
1 a
@@ -339,6 +352,7 @@ id1 val1
339352
8 n
340353
26 Z
341354
12 l
355+
13 m
342356
#
343357
# INSERT...SELECT...RETURNING
344358
#
@@ -372,6 +386,7 @@ id1 val1
372386
8 n
373387
26 Z
374388
12 l
389+
13 m
375390
EXECUTE stmt;
376391
(SELECT id1 FROM t1 WHERE val1='b')
377392
2
@@ -407,6 +422,7 @@ id2 val2
407422
5 e
408423
26 Z
409424
12 l
425+
13 m
410426
Warnings:
411427
Warning 1062 Duplicate entry '1' for key 'PRIMARY'
412428
Warning 1062 Duplicate entry '2' for key 'PRIMARY'
@@ -430,6 +446,18 @@ id2 val2
430446
5 e
431447
26 Z
432448
12 l
449+
13 m
450+
TRUNCATE TABLE t2;
451+
INSERT INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING t2.*;
452+
id2 val2
453+
1 a
454+
INSERT INTO t2 SELECT t1.* FROM t1 WHERE id1=2 RETURNING t2.*;
455+
id2 val2
456+
2 b
457+
SELECT * FROM t2;
458+
id2 val2
459+
1 a
460+
2 b
433461
DROP TABLE t1;
434462
DROP TABLE t2;
435463
DROP TABLE ins_duplicate;
@@ -460,6 +488,8 @@ t1 WHERE id1=1)
460488
5 6
461489
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
462490
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
491+
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
492+
ERROR 42S02: Unknown table 'test.t1'
463493
#
464494
# Multiple rows in single insert statement
465495
#
@@ -481,6 +511,8 @@ t1 WHERE id1=1)
481511
12 13
482512
INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2);
483513
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
514+
INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*;
515+
ERROR 42S02: Unknown table 'test.t1'
484516
#
485517
# INSERT ... SET
486518
#
@@ -501,6 +533,8 @@ WHERE id1=1)
501533
5 6
502534
INSERT INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2);
503535
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
536+
INSERT INTO t2 SET id2=5, val2='f' RETURNING t1.*;
537+
ERROR 42S02: Unknown table 'test.t1'
504538
#
505539
# INSERT...ON DUPLICATE KEY UPDATE
506540
#
@@ -525,6 +559,9 @@ ERROR 42S22: Unknown column 'id2' in 'field list'
525559
INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b'
526560
RETURNING (SELECT id FROM ins_duplicate);
527561
ERROR HY000: Table 'ins_duplicate' is specified twice, both as a target for 'INSERT' and as a separate source for data
562+
INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b'
563+
RETURNING t1.*;
564+
ERROR 42S02: Unknown table 'test.t1'
528565
#
529566
# INSERT...SELECT
530567
#
@@ -544,6 +581,8 @@ ERROR 21000: Operand should contain 1 column(s)
544581
INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
545582
id2 FROM t2);
546583
ERROR 21000: Subquery returns more than 1 row
584+
INSERT INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*;
585+
ERROR 42S02: Unknown table 'test.t1'
547586
#
548587
# TRIGGER
549588
#

mysql-test/main/insert_returning.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ SELECT * FROM t1;
4141
INSERT INTO v1(id1, val1) VALUES (12, 'a') RETURNING id1+id1 as total,val1,
4242
id1 && id1, id1 id1, UPPER(val1),f(id1);
4343
ANALYZE INSERT INTO t1(id1,val1) VALUES(13,'l') RETURNING *;
44+
INSERT INTO t1(id1,val1) VALUES(14,'m') RETURNING t1.*;
4445
TRUNCATE TABLE t1;
4546

4647
--echo #
@@ -68,6 +69,7 @@ SELECT * FROM t1;
6869
INSERT INTO v1 VALUES(23,'y'),(24,'z') RETURNING id1 as id,val1,
6970
id1 && id1, id1|id1, UPPER(val1),f(id1);
7071
ANALYZE INSERT INTO t1 VALUES(25,'a'),(26,'b') RETURNING *;
72+
ANALYZE INSERT INTO t1 VALUES(27,'c'),(28,'d') RETURNING t1.*;
7173

7274
--echo #
7375
--echo # INSERT...ON DUPLICATE KEY UPDATE...RETURNING
@@ -101,6 +103,8 @@ val1='d' RETURNING id1+id1 AS total, val1, id1 && id1, id1|id1, UPPER(val1),
101103
f(id1);
102104
ANALYZE INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE
103105
val='k' RETURNING *;
106+
INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE
107+
val='l' RETURNING ins_duplicate.*;
104108
SELECT * FROM ins_duplicate;
105109

106110
--echo #
@@ -130,6 +134,7 @@ EXPLAIN FORMAT="json" INSERT INTO t1 SET id1=11, val1='k' RETURNING val1;
130134
INSERT INTO v1 SET id1=26, val1='Z' RETURNING id1+id1 AS total,val1,
131135
id1 && id1, id1|id1, UPPER(val1),f(id1);
132136
ANALYZE INSERT INTO t1 SET id1=12, val1='l' RETURNING *;
137+
INSERT INTO t1 SET id1= 13, val1= 'm' RETURNING t1.*;
133138
SELECT * FROM t1;
134139

135140
--echo #
@@ -158,6 +163,10 @@ INSERT IGNORE INTO t2 SELECT * FROM t1 WHERE id1=8 RETURNING *;
158163
INSERT IGNORE INTO v2 SELECT * FROM v1 RETURNING *;
159164
ANALYZE INSERT INTO t2 SELECT * FROM t1 WHERE id1=11 RETURNING *;
160165
SELECT * FROM t2;
166+
TRUNCATE TABLE t2;
167+
INSERT INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING t2.*;
168+
INSERT INTO t2 SELECT t1.* FROM t1 WHERE id1=2 RETURNING t2.*;
169+
SELECT * FROM t2;
161170

162171
DROP TABLE t1;
163172
DROP TABLE t2;
@@ -190,6 +199,8 @@ INSERT INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM
190199
t1 WHERE id1=1);
191200
--error ER_UPDATE_TABLE_USED
192201
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
202+
--error ER_BAD_TABLE_ERROR
203+
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
193204

194205
--echo #
195206
--echo # Multiple rows in single insert statement
@@ -208,6 +219,8 @@ INSERT INTO t2 VALUES(11,'e'),(12,'f') RETURNING id2, (SELECT id1+id2 FROM
208219
t1 WHERE id1=1);
209220
--error ER_UPDATE_TABLE_USED
210221
INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2);
222+
--error ER_BAD_TABLE_ERROR
223+
INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*;
211224

212225
--echo #
213226
--echo # INSERT ... SET
@@ -226,6 +239,8 @@ INSERT INTO t2 SET id2=5, val2='e' RETURNING id2, (SELECT id1+id2 FROM t1
226239
WHERE id1=1);
227240
--error ER_UPDATE_TABLE_USED
228241
INSERT INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2);
242+
--error ER_BAD_TABLE_ERROR
243+
INSERT INTO t2 SET id2=5, val2='f' RETURNING t1.*;
229244

230245
--echo #
231246
--echo # INSERT...ON DUPLICATE KEY UPDATE
@@ -251,6 +266,9 @@ RETURNING id2, (SELECT id1+id FROM t1 WHERE id1=1);
251266
--error ER_UPDATE_TABLE_USED
252267
INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b'
253268
RETURNING (SELECT id FROM ins_duplicate);
269+
--error ER_BAD_TABLE_ERROR
270+
INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b'
271+
RETURNING t1.*;
254272

255273
--echo #
256274
--echo # INSERT...SELECT
@@ -271,6 +289,8 @@ INSERT INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT
271289
--error ER_SUBQUERY_NO_1_ROW
272290
INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
273291
id2 FROM t2);
292+
--error ER_BAD_TABLE_ERROR
293+
INSERT INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*;
274294

275295
--echo #
276296
--echo # TRIGGER

mysql-test/main/replace_returning.result

Lines changed: 115 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ EXECUTE stmt;
3333
id1 (SELECT id2 FROM t2 WHERE val2='b')
3434
1 2
3535
DEALLOCATE PREPARE stmt;
36+
REPLACE INTO t1 (id1, val1) VALUES (1, 'g') RETURNING t1.*;
37+
id1 val1
38+
1 g
3639
SELECT * FROM t1;
3740
id1 val1
38-
1 f
41+
1 g
3942
TRUNCATE TABLE t1;
4043
#
4144
# Multiple values in one replace statement...RETURNING
@@ -69,10 +72,14 @@ id1 (SELECT id2 FROM t2 WHERE val2='b')
6972
1 2
7073
2 2
7174
DEALLOCATE PREPARE stmt;
75+
REPLACE INTO t1 VALUES (1,'u'),(2,'v') RETURNING t1.*;
76+
id1 val1
77+
1 u
78+
2 v
7279
SELECT * FROM t1;
7380
id1 val1
74-
1 s
75-
2 t
81+
1 u
82+
2 v
7683
TRUNCATE TABLE t1;
7784
#
7885
# REPLACE...SET...RETURNING
@@ -101,9 +108,12 @@ EXECUTE stmt;
101108
id1 (SELECT id2 FROM t2 WHERE val2='b')
102109
3 2
103110
DEALLOCATE PREPARE stmt;
111+
REPLACE INTO t1 SET id1=1, val1 = 'o' RETURNING t1.*;
112+
id1 val1
113+
1 o
104114
SELECT * FROM t1;
105115
id1 val1
106-
1 i
116+
1 o
107117
2 j
108118
3 k
109119
#
@@ -113,7 +123,7 @@ TRUNCATE TABLE t2;
113123
REPLACE INTO t2(id2,val2) SELECT * FROM t1;
114124
REPLACE INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING *;
115125
id2 val2
116-
1 i
126+
1 o
117127
REPLACE INTO t2 SELECT * FROM t1 WHERE id1=2 RETURNING id2+id2 AS total,
118128
id2&&id2, id2|id2,UPPER(val2),f(id2);
119129
total id2&&id2 id2|id2 UPPER(val2) f(id2)
@@ -122,7 +132,7 @@ REPLACE INTO t2 SELECT * FROM t1 WHERE id1=3 RETURNING (SELECT
122132
GROUP_CONCAT(val1) FROM t1 WHERE id1=1);
123133
(SELECT
124134
GROUP_CONCAT(val1) FROM t1 WHERE id1=1)
125-
i
135+
o
126136
REPLACE INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING (SELECT
127137
GROUP_CONCAT(val1) FROM t1 GROUP BY id1 HAVING id1=id1+1);
128138
(SELECT
@@ -144,11 +154,109 @@ FROM t2 WHERE id2=0);
144154
(SELECT id1+id2
145155
FROM t2 WHERE id2=0)
146156
NULL
157+
REPLACE INTO t2 SELECT * FROM t1 WHERE id1=2 RETURNING t2.*;
158+
id2 val2
159+
2 j
147160
SELECT * FROM t2;
148161
id2 val2
149-
1 i
162+
1 o
150163
2 j
151164
3 k
152165
DROP TABLE t1;
153166
DROP TABLE t2;
154167
DROP FUNCTION f;
168+
#
169+
# checking errors
170+
#
171+
CREATE TABLE t1(id1 INT,val1 VARCHAR(1));
172+
CREATE TABLE t2(id2 INT,val2 VARCHAR(1));
173+
REPLACE INTO t1 VALUES(1,'a'),(2,'b'),(3,'c');
174+
#
175+
# SIMLPE REPLACE STATEMENT
176+
#
177+
REPLACE INTO t2(id2,val2) VALUES(1,'a') RETURNING id1;
178+
ERROR 42S22: Unknown column 'id1' in 'field list'
179+
REPLACE INTO t2(id2,val2) values(2,'b') RETURNING SUM(id2);
180+
ERROR HY000: Invalid use of group function
181+
REPLACE INTO t2(id2,val2) VALUES(3,'c') RETURNING (SELECT id1 FROM t1);
182+
ERROR 21000: Subquery returns more than 1 row
183+
REPLACE INTO t2(id2,val2) VALUES(4,'d') RETURNING (SELECT * FROM t1);
184+
ERROR 21000: Operand should contain 1 column(s)
185+
REPLACE INTO t2(id2,val2) VALUES(4,'d') RETURNING (SELECT * FROM t2);
186+
ERROR 21000: Operand should contain 1 column(s)
187+
REPLACE INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM
188+
t1 WHERE id1=1);
189+
id2 (SELECT id1+id2 FROM
190+
t1 WHERE id1=1)
191+
5 6
192+
REPLACE INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
193+
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
194+
REPLACE INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
195+
ERROR 42S02: Unknown table 'test.t1'
196+
#
197+
# Multiple rows in single insert statement
198+
#
199+
REPLACE INTO t2 VALUES(1,'a'),(2,'b') RETURNING id1;
200+
ERROR 42S22: Unknown column 'id1' in 'field list'
201+
REPLACE INTO t2 VALUES(3,'c'),(4,'d') RETURNING MAX(id2);
202+
ERROR HY000: Invalid use of group function
203+
REPLACE INTO t2 VALUES(5,'c'),(6,'f') RETURNING (SELECT id1 FROM t1);
204+
ERROR 21000: Subquery returns more than 1 row
205+
REPLACE INTO t2 VALUES(7,'g'),(8,'h') RETURNING (SELECT * FROM t1);
206+
ERROR 21000: Operand should contain 1 column(s)
207+
REPLACE INTO t2 VALUES(9,'g'),(10,'h') RETURNING (SELECT * FROM t2);
208+
ERROR 21000: Operand should contain 1 column(s)
209+
REPLACE INTO t2 VALUES(11,'e'),(12,'f') RETURNING id2, (SELECT id1+id2 FROM
210+
t1 WHERE id1=1);
211+
id2 (SELECT id1+id2 FROM
212+
t1 WHERE id1=1)
213+
11 12
214+
12 13
215+
REPLACE INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2);
216+
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
217+
REPLACE INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*;
218+
ERROR 42S02: Unknown table 'test.t1'
219+
#
220+
# REPLACE ... SET
221+
#
222+
REPLACE INTO t2 SET id2=1, val2='a' RETURNING id1;
223+
ERROR 42S22: Unknown column 'id1' in 'field list'
224+
REPLACE INTO t2 SET id2=2, val2='b' RETURNING COUNT(id2);
225+
ERROR HY000: Invalid use of group function
226+
REPLACE INTO t2 SET id2=3, val2='c' RETURNING (SELECT id1 FROM t1);
227+
ERROR 21000: Subquery returns more than 1 row
228+
REPLACE INTO t2 SET id2=4, val2='d' RETURNING (SELECT * FROM t1);
229+
ERROR 21000: Operand should contain 1 column(s)
230+
REPLACE INTO t2 SET id2=4, val2='d' RETURNING (SELECT * FROM t2);
231+
ERROR 21000: Operand should contain 1 column(s)
232+
REPLACE INTO t2 SET id2=5, val2='e' RETURNING id2, (SELECT id1+id2 FROM t1
233+
WHERE id1=1);
234+
id2 (SELECT id1+id2 FROM t1
235+
WHERE id1=1)
236+
5 6
237+
REPLACE INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2);
238+
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
239+
REPLACE INTO t2 SET id2=5, val2='f' RETURNING t1.*;
240+
ERROR 42S02: Unknown table 'test.t1'
241+
#
242+
# REPLACE...SELECT
243+
#
244+
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=1 RETURNING id1;
245+
ERROR 42S22: Unknown column 'id1' in 'field list'
246+
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING MAX(id2);
247+
ERROR HY000: Invalid use of group function
248+
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
249+
id1 FROM t1);
250+
ERROR 21000: Subquery returns more than 1 row
251+
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
252+
* FROM t1);
253+
ERROR 21000: Operand should contain 1 column(s)
254+
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT
255+
* FROM t2);
256+
ERROR 21000: Operand should contain 1 column(s)
257+
REPLACE INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
258+
id2 FROM t2);
259+
ERROR 21000: Subquery returns more than 1 row
260+
REPLACE INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*;
261+
ERROR 42S02: Unknown table 'test.t1'
262+
DROP TABLE t1,t2;

0 commit comments

Comments
 (0)