diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 1cd41e5b3a4..81167bc85c0 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -5487,5 +5487,27 @@ a DEALLOCATE PREPARE stmt; DROP VIEW v1; DROP TABLE t1; +# +# MDEV-19631: Assertion `0' failed in st_select_lex_unit::optimize or +# different plan upon 2nd execution of PS with EXPLAIN +# +CREATE TABLE t1 (a INT); +PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1 HAVING 6 IN ( SELECT 6 UNION SELECT 5 )'; +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +# Without the patch the second execution of the 'stmt' prepared statement +# would result in server crash. +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +DEALLOCATE PREPARE stmt; +DROP TABLE t1; # End of 10.2 tests # diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 4097d28a949..81d8e8e0fed 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -4976,6 +4976,19 @@ DEALLOCATE PREPARE stmt; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # MDEV-19631: Assertion `0' failed in st_select_lex_unit::optimize or +--echo # different plan upon 2nd execution of PS with EXPLAIN +--echo # +CREATE TABLE t1 (a INT); +PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1 HAVING 6 IN ( SELECT 6 UNION SELECT 5 )'; +EXECUTE stmt; +--echo # Without the patch the second execution of the 'stmt' prepared statement +--echo # would result in server crash. +EXECUTE stmt; +# Cleanup +DEALLOCATE PREPARE stmt; +DROP TABLE t1; --echo # End of 10.2 tests --echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a3e8b453897..22d3597de16 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -25400,14 +25400,20 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) if (unit->is_union() || unit->fake_select_lex) { + ulonglong save_options= 0; + if (unit->union_needs_tmp_table() && unit->fake_select_lex) { + save_options= unit->fake_select_lex->options; unit->fake_select_lex->select_number= FAKE_SELECT_LEX_ID; // just for initialization unit->fake_select_lex->type= "UNION RESULT"; unit->fake_select_lex->options|= SELECT_DESCRIBE; } if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE))) res= unit->exec(); + + if (unit->union_needs_tmp_table() && unit->fake_select_lex) + unit->fake_select_lex->options= save_options; } else {