mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Crash in INSERT...SELECT..RETURNING with subquery
Underlying causes of all bugs mentioned below are same. This patch fixes all of them: 1) MDEV-25028: ASAN use-after-poison in base_list_iterator::next or Assertion `sl->join == 0' upon INSERT .. RETURNING via PS 2) MDEV-25187: Assertion `inited == NONE || table->open_by_handler' failed or Direct leak in init_dynamic_array2 upon INSERT .. RETURNING and memory leak in init_dynamic_array2 3) MDEV-28740: crash in INSERT RETURNING subquery in prepared statements 4) MDEV-27165: crash in base_list_iterator::next 5) MDEV-29686: Assertion `slave == 0' failed in st_select_lex_node::attach_single Analysis: consider this statement: INSERT(1)...SELECT(2)...(SELECT(3)...) RETURNING (SELECT(4)...) When RETURNING is encountered, add_slave() changes how selects are linked. It makes the builtin_select(1) slave of SELECT(2). This causes losing of already existing slave(3) (which is nested select of SELECT of INSERT...SELECT). When really, builtin_select (1) shouldn't be slave to SELECT(2) because it is not nested within it. Also, push_select() to use correct context also changed how select are linked. During reinit_stmt_before_use(), we expect the selects to be cleaned-up and have join=0. Since these selects are not linked correctly, clean-up doesn't happen correctly so join is not NULL. Hence the crash. Fix: IF we are parsing RETURNING, make is_parsing_returning= true for current select. get rid of add_slave(). In place of push_select(), used push_context() to have correct context (the context of builtin_select) to resolve items in item_list. And add these items to item_list of builtin_select.
This commit is contained in:
@ -326,3 +326,73 @@ DROP TABLE ins_duplicate;
|
||||
DROP VIEW v1;
|
||||
DROP VIEW v2;
|
||||
DROP FUNCTION f;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-25028: ASAN use-after-poison in base_list_iterator::next or
|
||||
--echo # Assertion `sl->join == 0' upon INSERT .. RETURNING via PS
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT);
|
||||
CREATE TABLE t2 (b INT);
|
||||
|
||||
PREPARE stmt1 FROM "INSERT INTO t1 SELECT * FROM t1 WHERE a IN (SELECT b FROM t2) RETURNING a";
|
||||
EXECUTE stmt1;
|
||||
|
||||
PREPARE stmt2 FROM "INSERT INTO t1 SELECT * FROM t1 WHERE a IN (SELECT b FROM t2) RETURNING (SELECT b FROM t2)";
|
||||
EXECUTE stmt2;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-25187: Assertion `inited == NONE || table->open_by_handler'
|
||||
--echo # failed or Direct leak in init_dynamic_array2 upon INSERT .. RETURNING
|
||||
--echo # and memory leak in init_dynamic_array2
|
||||
--echo #
|
||||
CREATE TABLE t (a INT, KEY (a));
|
||||
CREATE TABLE t1 (f INT);
|
||||
|
||||
INSERT INTO t VALUES (1),(2);
|
||||
|
||||
INSERT INTO t1 SELECT a FROM t WHERE 1 NOT IN (SELECT a FROM t) RETURNING f;
|
||||
|
||||
# Cleanup
|
||||
DROP TABLE t, t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-28740: crash in INSERT RETURNING subquery in prepared statements
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER NOT NULL,
|
||||
data VARCHAR(30),
|
||||
PRIMARY KEY (id)
|
||||
)ENGINE=MyISAM;
|
||||
|
||||
EXECUTE IMMEDIATE 'INSERT INTO t1 (id, data) VALUES ((SELECT CAST(1 AS SIGNED INTEGER) AS anon_1), ?) RETURNING t1.id' using 'hi';
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-27165: crash in base_list_iterator::next
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 ( id int, a int);
|
||||
CREATE TABLE t2 ( id int);
|
||||
|
||||
--error ER_WARN_DATA_OUT_OF_RANGE
|
||||
INSERT INTO t1 VALUES (( SELECT 1 from t2),999999999999) RETURNING id;
|
||||
--error ER_WARN_DATA_OUT_OF_RANGE
|
||||
EXECUTE immediate "INSERT INTO t1 VALUES (( SELECT 1 from t2),999999999999) RETURNING id ";
|
||||
|
||||
EXECUTE immediate "INSERT INTO t1 VALUES (( SELECT 1 from t2),9) RETURNING id ";
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-29686: Assertion `slave == 0' failed in
|
||||
--echo # st_select_lex_node::attach_single
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t (a INT);
|
||||
INSERT t WITH cte AS (SELECT 1) SELECT * FROM cte RETURNING *;
|
||||
|
||||
DROP TABLE t;
|
||||
|
Reference in New Issue
Block a user