diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2012-05-11 18:13:06 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2012-05-11 18:13:06 +0400 |
commit | 6bce336624e84f5ec377926b105ec2002b38c96b (patch) | |
tree | 403415304e99e5f25617e4b75f401938aaae7d83 | |
parent | 6fae4447f0873c159d94d1a3d8deafbd224d8100 (diff) | |
download | mariadb-git-6bce336624e84f5ec377926b105ec2002b38c96b.tar.gz |
MDEV-240: SHOW EXPLAIN: Assertion `this->optimized == 2' failed
- Fix the bug: SHOW EXPLAIN may hit a case where a join is partially
optimized.
- Change JOIN::optimized to use enum instead of numeric constants
-rw-r--r-- | mysql-test/r/show_explain.result | 33 | ||||
-rw-r--r-- | mysql-test/t/show_explain.test | 25 | ||||
-rw-r--r-- | sql/item_subselect.cc | 6 | ||||
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 17 | ||||
-rw-r--r-- | sql/sql_select.h | 8 |
6 files changed, 80 insertions, 11 deletions
diff --git a/mysql-test/r/show_explain.result b/mysql-test/r/show_explain.result index 4f0e89975ff..2051a409178 100644 --- a/mysql-test/r/show_explain.result +++ b/mysql-test/r/show_explain.result @@ -1,4 +1,5 @@ drop table if exists t0, t1, t2; +drop view if exists v1; create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 (a int); @@ -337,4 +338,36 @@ Warnings: Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` join `test`.`t2` group by `test`.`t2`.`a` set debug=''; DROP TABLE t2; +# +# MDEV-240: SHOW EXPLAIN: Assertion `this->optimized == 2' failed in +# JOIN::print_explain on query with a JOIN, TEMPTABLE view, +# +CREATE TABLE t3 (a INT); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t3; +INSERT INTO t3 VALUES (8); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (4),(5),(6),(7),(8),(9); +explain SELECT * FROM v1, t2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> system NULL NULL NULL NULL 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 6 +2 DERIVED t3 system NULL NULL NULL NULL 1 +set @show_explain_probe_select_id=2; +set debug='d,show_explain_probe_join_exec_end'; +SELECT * FROM v1, t2; +show explain for $thr2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Not yet optimized +Warnings: +Note 1003 SELECT * FROM v1, t2 +a b +8 4 +8 5 +8 6 +8 7 +8 8 +8 9 +set debug=''; +DROP VIEW v1; +DROP TABLE t2, t3; drop table t0,t1; diff --git a/mysql-test/t/show_explain.test b/mysql-test/t/show_explain.test index 02850efedd8..36c34c8df5c 100644 --- a/mysql-test/t/show_explain.test +++ b/mysql-test/t/show_explain.test @@ -5,6 +5,7 @@ --disable_warnings drop table if exists t0, t1, t2; +drop view if exists v1; --enable_warnings # @@ -346,6 +347,30 @@ set debug=''; DROP TABLE t2; +--echo # +--echo # MDEV-240: SHOW EXPLAIN: Assertion `this->optimized == 2' failed in +--echo # JOIN::print_explain on query with a JOIN, TEMPTABLE view, +--echo # +CREATE TABLE t3 (a INT); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t3; +INSERT INTO t3 VALUES (8); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (4),(5),(6),(7),(8),(9); +explain SELECT * FROM v1, t2; + +set @show_explain_probe_select_id=2; +set debug='d,show_explain_probe_join_exec_end'; +send SELECT * FROM v1, t2; + +connection default; +--source include/wait_condition.inc +evalp show explain for $thr2; +connection con1; +reap; +set debug=''; +DROP VIEW v1; +DROP TABLE t2, t3; + ## TODO: Test this: have several SHOW EXPLAIN requests be queued up for a ## thread and served together. diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 8b720b350a5..1780953bd7e 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2910,7 +2910,7 @@ int subselect_single_select_engine::exec() SELECT_LEX *save_select= thd->lex->current_select; thd->lex->current_select= select_lex; - if (!join->optimized) + if (join->optimized != JOIN::OPTIMIZATION_DONE) { SELECT_LEX_UNIT *unit= select_lex->master_unit(); @@ -4647,7 +4647,9 @@ int subselect_hash_sj_engine::exec() */ thd->lex->current_select= materialize_engine->select_lex; /* The subquery should be optimized, and materialized only once. */ - DBUG_ASSERT(materialize_join->optimized && !is_materialized); + DBUG_ASSERT(materialize_join->optimized == JOIN::OPTIMIZATION_DONE && + !is_materialized); + materialize_join->exec(); if ((res= test(materialize_join->error || thd->is_fatal_error || thd->is_error()))) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 69bb822f05a..29d0a9e9888 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3750,7 +3750,7 @@ int st_select_lex::print_explain(select_result_sink *output, uint8 explain_flags) { int res; - if (join && join->optimized == 2) + if (join && join->optimized == JOIN::OPTIMIZATION_DONE) { res= join->print_explain(output, explain_flags, TRUE, join->need_tmp, // need_tmp_table diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f48f180d1dd..af7a06e424d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -608,7 +608,7 @@ JOIN::prepare(Item ***rref_pointer_array, DBUG_ENTER("JOIN::prepare"); // to prevent double initialization on EXPLAIN - if (optimized) + if (optimized != JOIN::NOT_OPTIMIZED) DBUG_RETURN(0); conds= conds_init; @@ -936,7 +936,7 @@ err: int JOIN::optimize() { int res= optimize_inner(); - optimized= 2; + optimized= JOIN::OPTIMIZATION_DONE; return res; } /** @@ -960,9 +960,9 @@ JOIN::optimize_inner() DBUG_ENTER("JOIN::optimize"); do_send_rows = (unit->select_limit_cnt) ? 1 : 0; // to prevent double initialization on EXPLAIN - if (optimized) + if (optimized != JOIN::NOT_OPTIMIZED) DBUG_RETURN(0); - optimized= 1; + optimized= JOIN::OPTIMIZATION_IN_PROGRESS; thd_proc_info(thd, "optimizing"); set_allowed_join_cache_types(); @@ -1731,7 +1731,7 @@ int JOIN::init_execution() { DBUG_ENTER("JOIN::init_execution"); - DBUG_ASSERT(optimized); + DBUG_ASSERT(optimized == JOIN::OPTIMIZATION_DONE); DBUG_ASSERT(!(select_options & SELECT_DESCRIBE)); initialized= true; @@ -21187,7 +21187,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(this->optimized == 2); + /* Don't log this into the slow query log */ if (!on_the_fly) @@ -21204,6 +21204,10 @@ int JOIN::print_explain(select_result_sink *result, uint8 explain_flags, { item_list.push_back(new Item_int((int32) join->select_lex->select_number)); + + if (on_the_fly) + join->select_lex->set_explain_type(on_the_fly); + item_list.push_back(new Item_string(join->select_lex->type, strlen(join->select_lex->type), cs)); for (uint i=0 ; i < 7; i++) @@ -21227,6 +21231,7 @@ int JOIN::print_explain(select_result_sink *result, uint8 explain_flags, else if (!join->select_lex->master_unit()->derived || join->select_lex->master_unit()->derived->is_materialized_derived()) { + DBUG_ASSERT(optimized == JOIN::OPTIMIZATION_DONE); table_map used_tables=0; //if (!join->select_lex->type) if (on_the_fly) diff --git a/sql/sql_select.h b/sql/sql_select.h index a15720b4b30..3bb007f0d93 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1178,7 +1178,11 @@ public: const char *zero_result_cause; ///< not 0 if exec must return zero result bool union_part; ///< this subselect is part of union - int optimized; ///< flag to avoid double optimization in EXPLAIN + + enum join_optimization_state { NOT_OPTIMIZED=0, + OPTIMIZATION_IN_PROGRESS=1, + OPTIMIZATION_DONE=2}; + join_optimization_state optimized; ///< flag to avoid double optimization in EXPLAIN bool initialized; ///< flag to avoid double init_execution calls /* @@ -1261,7 +1265,7 @@ public: ref_pointer_array= items0= items1= items2= items3= 0; ref_pointer_array_size= 0; zero_result_cause= 0; - optimized= 0; + optimized= JOIN::NOT_OPTIMIZED; initialized= 0; cond_equal= 0; having_equal= 0; |