diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2013-09-12 13:53:13 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2013-09-12 13:53:13 +0400 |
commit | 7e4845beea1a86dc53dc67908a2779ea2f0190a2 (patch) | |
tree | 4fbee6ef7d564e4361de43378b519a86c951da13 /sql/opt_subselect.cc | |
parent | c2b38529a9ca2ea09dfa73186d9350a0d6dcd6ac (diff) | |
download | mariadb-git-7e4845beea1a86dc53dc67908a2779ea2f0190a2.tar.gz |
MDEV-5011: ERROR Plugin 'MEMORY' has ref_count=1 after shutdown for SJM queries
- Provide a special execution path for cleanup of degenerate
non-merged semi-join children of degenerate selects.
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r-- | sql/opt_subselect.cc | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index b0d84fe5400..bedf770d3d9 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -5174,6 +5174,12 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list, DBUG_RETURN(1); table->table= dummy_table; table->table->pos_in_table_list= table; + /* + Note: the table created above may be freed by: + 1. JOIN_TAB::cleanup(), when the parent join is a regular join. + 2. cleanup_empty_jtbm_semi_joins(), when the parent join is a + degenerate join (e.g. one with "Impossible where"). + */ setup_table_map(table->table, table, table->jtbm_table_no); } else @@ -5206,6 +5212,42 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list, } +/* + Cleanup non-merged semi-joins (JBMs) that have empty. + + This function is to cleanups for a special case: + Consider a query like + + select * from t1 where 1=2 AND t1.col IN (select max(..) ... having 1=2) + + For this query, optimization of subquery will short-circuit, and + setup_jtbm_semi_joins() will call create_dummy_tmp_table() so that we have + empty, constant temp.table to stand in as materialized temp. table. + + Now, suppose that the upper join is also found to be degenerate. In that + case, no JOIN_TAB array will be produced, and hence, JOIN::cleanup() will + have a problem with cleaning up empty JTBMs (non-empty ones are cleaned up + through Item::cleanup() calls). +*/ + +void cleanup_empty_jtbm_semi_joins(JOIN *join) +{ + List_iterator<TABLE_LIST> li(*join->join_list); + TABLE_LIST *table; + while ((table= li++)) + { + if ((table->jtbm_subselect && table->jtbm_subselect->is_jtbm_const_tab)) + { + if (table->table) + { + free_tmp_table(join->thd, table->table); + table->table= NULL; + } + } + } +} + + /** Choose an optimal strategy to execute an IN/ALL/ANY subquery predicate based on cost. |