summaryrefslogtreecommitdiff
path: root/sql/item_subselect.cc
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2016-06-22 11:17:44 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2016-07-22 17:35:39 +0200
commita52d3aa831454aa2e7dd4dfde9c65d4b87532caa (patch)
tree3f6d0dcc44e5e0d31b96b98780abd49fcaf5da70 /sql/item_subselect.cc
parente6a64e8f0ea36f12bd24ba906aa1f4e2e367a8e0 (diff)
downloadmariadb-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.cc39
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())))