Skip to content

Commit 1289794

Browse files
committed
Fix for MDEV-8321, MDEV-6223
EXPLAIN INSERT ... SELECT tried to use SELECT's execution path. This caused a collection of problems: - SELECT_DESCRIBE flag was not put into select_lex->options, which means it was not in JOIN::select_options either (except for the first member of the UNION). - This caused UNION members to be executed. They would attempt to write join output rows to the output. - (Actual cause of the crash) second join sibling would call result->send_eof() when finished execution. Then, Explain_query::print_explain would attempt to write to query output again, and cause an assertion due to non-empty query output.
1 parent a7dd24c commit 1289794

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

mysql-test/r/explain_non_select.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,29 @@ CHECK TABLE t1;
247247
Table Op Msg_type Msg_text
248248
test.t1 check status OK
249249
DROP TABLE t1, t2;
250+
#
251+
# MDEV-8321: Assertion `! is_set()' failed in Diagnostics_area::set_eof_status on EXPLAIN INSERT ... UNION
252+
#
253+
CREATE TABLE t1 (a INT);
254+
CREATE TABLE t2 (b INT);
255+
CREATE TABLE t3 (c INT);
256+
INSERT INTO t1 VALUES (1),(2);
257+
INSERT INTO t2 VALUES (3),(4);
258+
INSERT INTO t3 VALUES (5),(6);
259+
EXPLAIN INSERT INTO t1 SELECT * FROM t2 UNION SELECT * FROM t3;
260+
id select_type table type possible_keys key key_len ref rows Extra
261+
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
262+
2 UNION t3 ALL NULL NULL NULL NULL 2
263+
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
264+
drop table t1,t2,t3;
265+
#
266+
# MDEV-6223: Assertion `! is_set()' fails in Diagnostics_area::set_eof_status on EXPLAIN INSERT executed as a PS
267+
#
268+
CREATE TABLE t1 (a INT) ENGINE = MyISAM;
269+
CREATE TABLE t2 (b INT) ENGINE = MyISAM;
270+
INSERT INTO t2 VALUES (1),(2);
271+
PREPARE stmt FROM 'EXPLAIN INSERT INTO t1 SELECT * FROM t2';
272+
EXECUTE stmt;
273+
id select_type table type possible_keys key key_len ref rows Extra
274+
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
275+
drop table t1,t2;

mysql-test/t/explain_non_select.test

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,29 @@ CHECK TABLE t1;
224224

225225
DROP TABLE t1, t2;
226226

227+
--echo #
228+
--echo # MDEV-8321: Assertion `! is_set()' failed in Diagnostics_area::set_eof_status on EXPLAIN INSERT ... UNION
229+
--echo #
230+
231+
CREATE TABLE t1 (a INT);
232+
CREATE TABLE t2 (b INT);
233+
CREATE TABLE t3 (c INT);
234+
235+
# Data is not necessary, tables can be empty as well
236+
INSERT INTO t1 VALUES (1),(2);
237+
INSERT INTO t2 VALUES (3),(4);
238+
INSERT INTO t3 VALUES (5),(6);
239+
240+
EXPLAIN INSERT INTO t1 SELECT * FROM t2 UNION SELECT * FROM t3;
241+
drop table t1,t2,t3;
242+
243+
--echo #
244+
--echo # MDEV-6223: Assertion `! is_set()' fails in Diagnostics_area::set_eof_status on EXPLAIN INSERT executed as a PS
245+
--echo #
246+
CREATE TABLE t1 (a INT) ENGINE = MyISAM;
247+
CREATE TABLE t2 (b INT) ENGINE = MyISAM;
248+
INSERT INTO t2 VALUES (1),(2);
249+
PREPARE stmt FROM 'EXPLAIN INSERT INTO t1 SELECT * FROM t2';
250+
EXECUTE stmt;
251+
drop table t1,t2;
252+

sql/sql_parse.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3533,7 +3533,10 @@ case SQLCOM_PREPARE:
35333533
lex->duplicates,
35343534
lex->ignore)))
35353535
{
3536-
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
3536+
if (explain)
3537+
res= mysql_explain_union(thd, &thd->lex->unit, sel_result);
3538+
else
3539+
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
35373540
/*
35383541
Invalidate the table in the query cache if something changed
35393542
after unlocking when changes become visible.

sql/sql_union.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
286286
{
287287
if (!(tmp_result= union_result= new select_union))
288288
goto err;
289-
if (describe)
290-
tmp_result= sel_result;
291289
}
292290
else
293291
tmp_result= sel_result;

0 commit comments

Comments
 (0)