1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Fixed bug MDEV-288

CHEAP SQ: Valgrind warnings "Memory lost" with IN and EXISTS nested subquery, materialization+semijoin

Analysis:
The memory leak was a result of the interaction of semi-join optimization
with early optimization of constant subqueries. The function:
setup_jtbm_semi_joins() created a dummy temporary table "dummy_table"
in order to make some JOIN_TAB objects complete. Normally, such temporary
tables are freed inside JOIN_TAB::cleanup.

However, the inner-most subquery is pre-optimized, which allows the
optimization fo the MAX subquery to determine that its WHERE is TRUE,
and thus to compute the result of the MAX during optimization. This
ultimately allows the optimize phase of the outer query to find that
it WHERE clause is FALSE. Once JOIN::optimize finds that the result
set is empty, it sets zero_result_cause, and returns *before* it ever
reached make_join_statistics(). As a result the query plan has no
JOIN_TABs at all. Since the temporary table is supposed to be cleanup
via JOIN_TAB::cleanup, this never happens because there is no JOIN_TAB
for this table. Hence we get a memory leak.

Solution:
Whenever there are no JOIN_TABs, iterate over all table reference in
JOIN::join_list, and free the ones that contain semi-join temporary
tables.
This commit is contained in:
unknown
2012-06-01 14:10:15 +03:00
parent 941018f8d1
commit 7ddd5418d0
7 changed files with 113 additions and 0 deletions

View File

@ -10595,6 +10595,22 @@ void JOIN::cleanup(bool full)
tmp_join->tmp_table_param.save_copy_field= 0;
}
tmp_table_param.cleanup();
if (!join_tab)
{
List_iterator<TABLE_LIST> li(*join_list);
TABLE_LIST *table_ref;
while ((table_ref= li++))
{
if (table_ref->table &&
table_ref->jtbm_subselect &&
table_ref->jtbm_subselect->is_jtbm_const_tab)
{
free_tmp_table(thd, table_ref->table);
table_ref->table= NULL;
}
}
}
}
DBUG_VOID_RETURN;
}