Skip to content

Commit

Permalink
MDEV-23178: Qualified asterisk not supported in INSERT .. RETURNING
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mariadb-RuchaDeodhar committed Jul 22, 2021
1 parent 091743c commit 5518c32
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 17 deletions.
41 changes: 40 additions & 1 deletion mysql-test/main/insert_returning.result
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ total val1 id1 && id1 id1 UPPER(val1) f(id1)
ANALYZE INSERT INTO t1(id1,val1) VALUES(13,'l') RETURNING *;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
INSERT INTO t1(id1,val1) VALUES(14,'m') RETURNING t1.*;
id1 val1
14 m
TRUNCATE TABLE t1;
#
# Multiple values in one insert statement...RETURNING
Expand Down Expand Up @@ -182,6 +185,9 @@ id val1 id1 && id1 id1|id1 UPPER(val1) f(id1)
ANALYZE INSERT INTO t1 VALUES(25,'a'),(26,'b') RETURNING *;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
ANALYZE INSERT INTO t1 VALUES(27,'c'),(28,'d') RETURNING t1.*;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
#
# INSERT...ON DUPLICATE KEY UPDATE...RETURNING
#
Expand Down Expand Up @@ -250,10 +256,14 @@ ANALYZE INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE
val='k' RETURNING *;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 INSERT ins_duplicate ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE
val='l' RETURNING ins_duplicate.*;
id val
2 l
SELECT * FROM ins_duplicate;
id val
1 a
2 k
2 l
3 c
4 d
#
Expand Down Expand Up @@ -327,6 +337,9 @@ total val1 id1 && id1 id1|id1 UPPER(val1) f(id1)
ANALYZE INSERT INTO t1 SET id1=12, val1='l' RETURNING *;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL
INSERT INTO t1 SET id1= 13, val1= 'm' RETURNING t1.*;
id1 val1
13 m
SELECT * FROM t1;
id1 val1
1 a
Expand All @@ -339,6 +352,7 @@ id1 val1
8 n
26 Z
12 l
13 m
#
# INSERT...SELECT...RETURNING
#
Expand Down Expand Up @@ -372,6 +386,7 @@ id1 val1
8 n
26 Z
12 l
13 m
EXECUTE stmt;
(SELECT id1 FROM t1 WHERE val1='b')
2
Expand Down Expand Up @@ -407,6 +422,7 @@ id2 val2
5 e
26 Z
12 l
13 m
Warnings:
Warning 1062 Duplicate entry '1' for key 'PRIMARY'
Warning 1062 Duplicate entry '2' for key 'PRIMARY'
Expand All @@ -430,6 +446,18 @@ id2 val2
5 e
26 Z
12 l
13 m
TRUNCATE TABLE t2;
INSERT INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING t2.*;
id2 val2
1 a
INSERT INTO t2 SELECT t1.* FROM t1 WHERE id1=2 RETURNING t2.*;
id2 val2
2 b
SELECT * FROM t2;
id2 val2
1 a
2 b
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE ins_duplicate;
Expand Down Expand Up @@ -460,6 +488,8 @@ t1 WHERE id1=1)
5 6
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#
# Multiple rows in single insert statement
#
Expand All @@ -481,6 +511,8 @@ t1 WHERE id1=1)
12 13
INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2);
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#
# INSERT ... SET
#
Expand All @@ -501,6 +533,8 @@ WHERE id1=1)
5 6
INSERT INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2);
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t2 SET id2=5, val2='f' RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#
# INSERT...ON DUPLICATE KEY UPDATE
#
Expand All @@ -525,6 +559,9 @@ ERROR 42S22: Unknown column 'id2' in 'field list'
INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b'
RETURNING (SELECT id FROM ins_duplicate);
ERROR HY000: Table 'ins_duplicate' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b'
RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#
# INSERT...SELECT
#
Expand All @@ -544,6 +581,8 @@ ERROR 21000: Operand should contain 1 column(s)
INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
id2 FROM t2);
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#
# TRIGGER
#
Expand Down
20 changes: 20 additions & 0 deletions mysql-test/main/insert_returning.test
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ SELECT * FROM t1;
INSERT INTO v1(id1, val1) VALUES (12, 'a') RETURNING id1+id1 as total,val1,
id1 && id1, id1 id1, UPPER(val1),f(id1);
ANALYZE INSERT INTO t1(id1,val1) VALUES(13,'l') RETURNING *;
INSERT INTO t1(id1,val1) VALUES(14,'m') RETURNING t1.*;
TRUNCATE TABLE t1;

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

--echo #
--echo # INSERT...ON DUPLICATE KEY UPDATE...RETURNING
Expand Down Expand Up @@ -101,6 +103,8 @@ val1='d' RETURNING id1+id1 AS total, val1, id1 && id1, id1|id1, UPPER(val1),
f(id1);
ANALYZE INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE
val='k' RETURNING *;
INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE
val='l' RETURNING ins_duplicate.*;
SELECT * FROM ins_duplicate;

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

--echo #
Expand Down Expand Up @@ -158,6 +163,10 @@ INSERT IGNORE INTO t2 SELECT * FROM t1 WHERE id1=8 RETURNING *;
INSERT IGNORE INTO v2 SELECT * FROM v1 RETURNING *;
ANALYZE INSERT INTO t2 SELECT * FROM t1 WHERE id1=11 RETURNING *;
SELECT * FROM t2;
TRUNCATE TABLE t2;
INSERT INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING t2.*;
INSERT INTO t2 SELECT t1.* FROM t1 WHERE id1=2 RETURNING t2.*;
SELECT * FROM t2;

DROP TABLE t1;
DROP TABLE t2;
Expand Down Expand Up @@ -190,6 +199,8 @@ INSERT INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM
t1 WHERE id1=1);
--error ER_UPDATE_TABLE_USED
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
--error ER_BAD_TABLE_ERROR
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;

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

--echo #
--echo # INSERT ... SET
Expand All @@ -226,6 +239,8 @@ INSERT INTO t2 SET id2=5, val2='e' RETURNING id2, (SELECT id1+id2 FROM t1
WHERE id1=1);
--error ER_UPDATE_TABLE_USED
INSERT INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2);
--error ER_BAD_TABLE_ERROR
INSERT INTO t2 SET id2=5, val2='f' RETURNING t1.*;

--echo #
--echo # INSERT...ON DUPLICATE KEY UPDATE
Expand All @@ -251,6 +266,9 @@ RETURNING id2, (SELECT id1+id FROM t1 WHERE id1=1);
--error ER_UPDATE_TABLE_USED
INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b'
RETURNING (SELECT id FROM ins_duplicate);
--error ER_BAD_TABLE_ERROR
INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b'
RETURNING t1.*;

--echo #
--echo # INSERT...SELECT
Expand All @@ -271,6 +289,8 @@ INSERT INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT
--error ER_SUBQUERY_NO_1_ROW
INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
id2 FROM t2);
--error ER_BAD_TABLE_ERROR
INSERT INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*;

--echo #
--echo # TRIGGER
Expand Down
122 changes: 115 additions & 7 deletions mysql-test/main/replace_returning.result
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ EXECUTE stmt;
id1 (SELECT id2 FROM t2 WHERE val2='b')
1 2
DEALLOCATE PREPARE stmt;
REPLACE INTO t1 (id1, val1) VALUES (1, 'g') RETURNING t1.*;
id1 val1
1 g
SELECT * FROM t1;
id1 val1
1 f
1 g
TRUNCATE TABLE t1;
#
# Multiple values in one replace statement...RETURNING
Expand Down Expand Up @@ -69,10 +72,14 @@ id1 (SELECT id2 FROM t2 WHERE val2='b')
1 2
2 2
DEALLOCATE PREPARE stmt;
REPLACE INTO t1 VALUES (1,'u'),(2,'v') RETURNING t1.*;
id1 val1
1 u
2 v
SELECT * FROM t1;
id1 val1
1 s
2 t
1 u
2 v
TRUNCATE TABLE t1;
#
# REPLACE...SET...RETURNING
Expand Down Expand Up @@ -101,9 +108,12 @@ EXECUTE stmt;
id1 (SELECT id2 FROM t2 WHERE val2='b')
3 2
DEALLOCATE PREPARE stmt;
REPLACE INTO t1 SET id1=1, val1 = 'o' RETURNING t1.*;
id1 val1
1 o
SELECT * FROM t1;
id1 val1
1 i
1 o
2 j
3 k
#
Expand All @@ -113,7 +123,7 @@ TRUNCATE TABLE t2;
REPLACE INTO t2(id2,val2) SELECT * FROM t1;
REPLACE INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING *;
id2 val2
1 i
1 o
REPLACE INTO t2 SELECT * FROM t1 WHERE id1=2 RETURNING id2+id2 AS total,
id2&&id2, id2|id2,UPPER(val2),f(id2);
total id2&&id2 id2|id2 UPPER(val2) f(id2)
Expand All @@ -122,7 +132,7 @@ REPLACE INTO t2 SELECT * FROM t1 WHERE id1=3 RETURNING (SELECT
GROUP_CONCAT(val1) FROM t1 WHERE id1=1);
(SELECT
GROUP_CONCAT(val1) FROM t1 WHERE id1=1)
i
o
REPLACE INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING (SELECT
GROUP_CONCAT(val1) FROM t1 GROUP BY id1 HAVING id1=id1+1);
(SELECT
Expand All @@ -144,11 +154,109 @@ FROM t2 WHERE id2=0);
(SELECT id1+id2
FROM t2 WHERE id2=0)
NULL
REPLACE INTO t2 SELECT * FROM t1 WHERE id1=2 RETURNING t2.*;
id2 val2
2 j
SELECT * FROM t2;
id2 val2
1 i
1 o
2 j
3 k
DROP TABLE t1;
DROP TABLE t2;
DROP FUNCTION f;
#
# checking errors
#
CREATE TABLE t1(id1 INT,val1 VARCHAR(1));
CREATE TABLE t2(id2 INT,val2 VARCHAR(1));
REPLACE INTO t1 VALUES(1,'a'),(2,'b'),(3,'c');
#
# SIMLPE REPLACE STATEMENT
#
REPLACE INTO t2(id2,val2) VALUES(1,'a') RETURNING id1;
ERROR 42S22: Unknown column 'id1' in 'field list'
REPLACE INTO t2(id2,val2) values(2,'b') RETURNING SUM(id2);
ERROR HY000: Invalid use of group function
REPLACE INTO t2(id2,val2) VALUES(3,'c') RETURNING (SELECT id1 FROM t1);
ERROR 21000: Subquery returns more than 1 row
REPLACE INTO t2(id2,val2) VALUES(4,'d') RETURNING (SELECT * FROM t1);
ERROR 21000: Operand should contain 1 column(s)
REPLACE INTO t2(id2,val2) VALUES(4,'d') RETURNING (SELECT * FROM t2);
ERROR 21000: Operand should contain 1 column(s)
REPLACE INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM
t1 WHERE id1=1);
id2 (SELECT id1+id2 FROM
t1 WHERE id1=1)
5 6
REPLACE INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
REPLACE INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#
# Multiple rows in single insert statement
#
REPLACE INTO t2 VALUES(1,'a'),(2,'b') RETURNING id1;
ERROR 42S22: Unknown column 'id1' in 'field list'
REPLACE INTO t2 VALUES(3,'c'),(4,'d') RETURNING MAX(id2);
ERROR HY000: Invalid use of group function
REPLACE INTO t2 VALUES(5,'c'),(6,'f') RETURNING (SELECT id1 FROM t1);
ERROR 21000: Subquery returns more than 1 row
REPLACE INTO t2 VALUES(7,'g'),(8,'h') RETURNING (SELECT * FROM t1);
ERROR 21000: Operand should contain 1 column(s)
REPLACE INTO t2 VALUES(9,'g'),(10,'h') RETURNING (SELECT * FROM t2);
ERROR 21000: Operand should contain 1 column(s)
REPLACE INTO t2 VALUES(11,'e'),(12,'f') RETURNING id2, (SELECT id1+id2 FROM
t1 WHERE id1=1);
id2 (SELECT id1+id2 FROM
t1 WHERE id1=1)
11 12
12 13
REPLACE INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2);
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
REPLACE INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#
# REPLACE ... SET
#
REPLACE INTO t2 SET id2=1, val2='a' RETURNING id1;
ERROR 42S22: Unknown column 'id1' in 'field list'
REPLACE INTO t2 SET id2=2, val2='b' RETURNING COUNT(id2);
ERROR HY000: Invalid use of group function
REPLACE INTO t2 SET id2=3, val2='c' RETURNING (SELECT id1 FROM t1);
ERROR 21000: Subquery returns more than 1 row
REPLACE INTO t2 SET id2=4, val2='d' RETURNING (SELECT * FROM t1);
ERROR 21000: Operand should contain 1 column(s)
REPLACE INTO t2 SET id2=4, val2='d' RETURNING (SELECT * FROM t2);
ERROR 21000: Operand should contain 1 column(s)
REPLACE INTO t2 SET id2=5, val2='e' RETURNING id2, (SELECT id1+id2 FROM t1
WHERE id1=1);
id2 (SELECT id1+id2 FROM t1
WHERE id1=1)
5 6
REPLACE INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2);
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
REPLACE INTO t2 SET id2=5, val2='f' RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#
# REPLACE...SELECT
#
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=1 RETURNING id1;
ERROR 42S22: Unknown column 'id1' in 'field list'
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING MAX(id2);
ERROR HY000: Invalid use of group function
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
id1 FROM t1);
ERROR 21000: Subquery returns more than 1 row
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
* FROM t1);
ERROR 21000: Operand should contain 1 column(s)
REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT
* FROM t2);
ERROR 21000: Operand should contain 1 column(s)
REPLACE INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
id2 FROM t2);
ERROR 21000: Subquery returns more than 1 row
REPLACE INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
DROP TABLE t1,t2;
Loading

0 comments on commit 5518c32

Please sign in to comment.