diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2016-06-22 11:17:44 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2016-07-22 17:35:39 +0200 |
commit | a52d3aa831454aa2e7dd4dfde9c65d4b87532caa (patch) | |
tree | 3f6d0dcc44e5e0d31b96b98780abd49fcaf5da70 /sql/item_subselect.cc | |
parent | e6a64e8f0ea36f12bd24ba906aa1f4e2e367a8e0 (diff) | |
download | mariadb-git-a52d3aa831454aa2e7dd4dfde9c65d4b87532caa.tar.gz |
MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
Do not set 'optimized' flag until whole optimization procedure is finished.
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r-- | sql/item_subselect.cc | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 301856ea3b8..2999e01d166 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -560,6 +560,21 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent, bool Item_subselect::is_expensive() { double examined_rows= 0; + bool all_are_simple= true; + + /* check extremely simple select */ + if (!unit->first_select()->next_select()) // no union + { + /* + such single selects works even without optimization because + can not makes loops + */ + SELECT_LEX *sl= unit->first_select(); + JOIN *join = sl->join; + if (join && !join->tables_list && !sl->first_inner_unit()) + return false; + } + for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) { @@ -569,23 +584,27 @@ bool Item_subselect::is_expensive() if (!cur_join) return true; - /* very simple subquery */ - if (!cur_join->tables_list && !sl->first_inner_unit()) - return false; - /* If the subquery is not optimised or in the process of optimization it supposed to be expensive */ - if (!cur_join->optimized) + if (cur_join->optimization_state != JOIN::OPTIMIZATION_DONE) return true; + if (!cur_join->tables_list && !sl->first_inner_unit()) + continue; + /* Subqueries whose result is known after optimization are not expensive. Such subqueries have all tables optimized away, thus have no join plan. */ if ((cur_join->zero_result_cause || !cur_join->tables_list)) - return false; + continue; + + /* + This is not simple SELECT in union so we can not go by simple condition + */ + all_are_simple= false; /* If a subquery is not optimized we cannot estimate its cost. A subquery is @@ -606,7 +625,8 @@ bool Item_subselect::is_expensive() examined_rows+= cur_join->get_examined_rows(); } - return (examined_rows > thd->variables.expensive_subquery_limit); + return !all_are_simple && + (examined_rows > thd->variables.expensive_subquery_limit); } @@ -3672,7 +3692,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->optimization_state == JOIN::NOT_OPTIMIZED) { SELECT_LEX_UNIT *unit= select_lex->master_unit(); @@ -5321,7 +5341,8 @@ 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->optimization_state == JOIN::OPTIMIZATION_DONE && + !is_materialized); materialize_join->exec(); if ((res= MY_TEST(materialize_join->error || thd->is_fatal_error || thd->is_error()))) |