From fd3e9c53c1b3c50ae85d020551915d5a31cd3044 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 1 Aug 2012 15:51:52 +0400 Subject: [PATCH] MDEV-423: SHOW EXPLAIN: 'Using where' for a subquery is shown in EXPLAIN, but not in SHOW EXPLAIN - Take into account that the optimizer may run the subquery, delete it, and then make a JOIN::optimize call again. --- mysql-test/r/show_explain.result | 34 +++++++++++++++++++++++++++++ mysql-test/t/show_explain.test | 37 ++++++++++++++++++++++++++++++++ sql/sql_select.cc | 10 +++++++-- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/show_explain.result b/mysql-test/r/show_explain.result index 6ff9a0d0f4e..2f7de62e7fe 100644 --- a/mysql-test/r/show_explain.result +++ b/mysql-test/r/show_explain.result @@ -998,5 +998,39 @@ Note 1003 SELECT b AS field1, b AS field2 FROM t1, t2, t3 WHERE d = b ORDER BY f field1 field2 set debug_dbug=''; DROP TABLE t1,t2,t3; +# +# MDEV-423: SHOW EXPLAIN: 'Using where' for a subquery is shown in EXPLAIN, but not in SHOW EXPLAIN output +# +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (7),(0),(9),(3),(4),(2),(5),(7),(0),(9),(3),(4),(2),(5); +CREATE TABLE t2 (b INT, c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES +(0,4),(8,6),(1,3),(8,5),(9,3),(24,246),(6,2),(1,9),(6,3),(2,8), +(4,1),(8,8),(4,8),(4,5),(7,7),(4,5),(1,1),(9,6),(4,2),(8,9); +create table t3 like t2; +insert into t3 select * from t2; +explain +SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias +WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 +1 PRIMARY t2 ALL NULL NULL NULL NULL 20 +3 SUBQUERY t3 ALL NULL NULL NULL NULL 20 Using where +set @show_explain_probe_select_id=1; +set debug_dbug='d,show_explain_probe_join_exec_start'; +SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias +WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10; +show explain for $thr2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 +1 PRIMARY t2 ALL NULL NULL NULL NULL 20 +3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Query plan already deleted +Warnings: +Note 1003 SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias +WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10 +max(a+b+c) +279 +set debug_dbug=''; +DROP TABLE t1,t2,t3; # End drop table t0; diff --git a/mysql-test/t/show_explain.test b/mysql-test/t/show_explain.test index 24b01402287..485bda84cf5 100644 --- a/mysql-test/t/show_explain.test +++ b/mysql-test/t/show_explain.test @@ -1026,5 +1026,42 @@ set debug_dbug=''; DROP TABLE t1,t2,t3; + +--echo # +--echo # MDEV-423: SHOW EXPLAIN: 'Using where' for a subquery is shown in EXPLAIN, but not in SHOW EXPLAIN output +--echo # +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (7),(0),(9),(3),(4),(2),(5),(7),(0),(9),(3),(4),(2),(5); + +CREATE TABLE t2 (b INT, c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES +(0,4),(8,6),(1,3),(8,5),(9,3),(24,246),(6,2),(1,9),(6,3),(2,8), +(4,1),(8,8),(4,8),(4,5),(7,7),(4,5),(1,1),(9,6),(4,2),(8,9); + +create table t3 like t2; +insert into t3 select * from t2; + +explain +SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias +WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10; + +set @show_explain_probe_select_id=1; +set debug_dbug='d,show_explain_probe_join_exec_start'; + +send +SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias +WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10; + +connection default; +--source include/wait_condition.inc +evalp show explain for $thr2; + +connection con1; +reap; + +set debug_dbug=''; + +DROP TABLE t1,t2,t3; + --echo # End drop table t0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 02be522290d..89765ab44db 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -987,7 +987,13 @@ err: int JOIN::optimize() { int res= optimize_inner(); - if (!res) + /* + If we're inside a non-correlated subquery, this function may be + called for the second time after the subquery has been executed + and deleted. The second call will not produce a valid query plan, it will + short-circuit because optimized==TRUE. + */ + if (!res && have_query_plan != QEP_DELETED) have_query_plan= QEP_AVAILABLE; return res; } @@ -21630,7 +21636,7 @@ int JOIN::print_explain(select_result_sink *result, uint8 explain_flags, DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s", (ulong)join->select_lex, join->select_lex->type, message ? message : "NULL")); - DBUG_ASSERT(have_query_plan == QEP_AVAILABLE); + DBUG_ASSERT(on_the_fly? have_query_plan == QEP_AVAILABLE: TRUE); /* Don't log this into the slow query log */ if (!on_the_fly)