Commit 12897947 authored by Sergei Petrunia's avatar Sergei Petrunia

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.
parent a7dd24cd
...@@ -247,3 +247,29 @@ CHECK TABLE t1; ...@@ -247,3 +247,29 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
DROP TABLE t1, t2; DROP TABLE t1, t2;
#
# MDEV-8321: Assertion `! is_set()' failed in Diagnostics_area::set_eof_status on EXPLAIN INSERT ... UNION
#
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
CREATE TABLE t3 (c INT);
INSERT INTO t1 VALUES (1),(2);
INSERT INTO t2 VALUES (3),(4);
INSERT INTO t3 VALUES (5),(6);
EXPLAIN INSERT INTO t1 SELECT * FROM t2 UNION SELECT * FROM t3;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 UNION t3 ALL NULL NULL NULL NULL 2
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
drop table t1,t2,t3;
#
# MDEV-6223: Assertion `! is_set()' fails in Diagnostics_area::set_eof_status on EXPLAIN INSERT executed as a PS
#
CREATE TABLE t1 (a INT) ENGINE = MyISAM;
CREATE TABLE t2 (b INT) ENGINE = MyISAM;
INSERT INTO t2 VALUES (1),(2);
PREPARE stmt FROM 'EXPLAIN INSERT INTO t1 SELECT * FROM t2';
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
drop table t1,t2;
...@@ -224,3 +224,29 @@ CHECK TABLE t1; ...@@ -224,3 +224,29 @@ CHECK TABLE t1;
DROP TABLE t1, t2; DROP TABLE t1, t2;
--echo #
--echo # MDEV-8321: Assertion `! is_set()' failed in Diagnostics_area::set_eof_status on EXPLAIN INSERT ... UNION
--echo #
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
CREATE TABLE t3 (c INT);
# Data is not necessary, tables can be empty as well
INSERT INTO t1 VALUES (1),(2);
INSERT INTO t2 VALUES (3),(4);
INSERT INTO t3 VALUES (5),(6);
EXPLAIN INSERT INTO t1 SELECT * FROM t2 UNION SELECT * FROM t3;
drop table t1,t2,t3;
--echo #
--echo # MDEV-6223: Assertion `! is_set()' fails in Diagnostics_area::set_eof_status on EXPLAIN INSERT executed as a PS
--echo #
CREATE TABLE t1 (a INT) ENGINE = MyISAM;
CREATE TABLE t2 (b INT) ENGINE = MyISAM;
INSERT INTO t2 VALUES (1),(2);
PREPARE stmt FROM 'EXPLAIN INSERT INTO t1 SELECT * FROM t2';
EXECUTE stmt;
drop table t1,t2;
...@@ -3533,7 +3533,10 @@ case SQLCOM_PREPARE: ...@@ -3533,7 +3533,10 @@ case SQLCOM_PREPARE:
lex->duplicates, lex->duplicates,
lex->ignore))) lex->ignore)))
{ {
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE); if (explain)
res= mysql_explain_union(thd, &thd->lex->unit, sel_result);
else
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
/* /*
Invalidate the table in the query cache if something changed Invalidate the table in the query cache if something changed
after unlocking when changes become visible. after unlocking when changes become visible.
......
...@@ -286,8 +286,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -286,8 +286,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
{ {
if (!(tmp_result= union_result= new select_union)) if (!(tmp_result= union_result= new select_union))
goto err; goto err;
if (describe)
tmp_result= sel_result;
} }
else else
tmp_result= sel_result; tmp_result= sel_result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment