mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(), went over all nested joins and called cleanup/join_free for them. For that: - split recursive and non-recursive parts of JOIN::cleanup() and JOIN::join_free() - rename JOIN::cleanup to JOIN::destroy, as it actually destroys its argument - move the recursive part of JOIN::cleanup to st_select_lex::cleanup - move the non-recursive part of JOIN::join_free to the introduced method JOIN::cleanup().
This commit is contained in:
@ -553,7 +553,6 @@ bool st_select_lex_unit::exec()
|
||||
bool st_select_lex_unit::cleanup()
|
||||
{
|
||||
int error= 0;
|
||||
JOIN *join;
|
||||
DBUG_ENTER("st_select_lex_unit::cleanup");
|
||||
|
||||
if (cleaned)
|
||||
@ -572,29 +571,17 @@ bool st_select_lex_unit::cleanup()
|
||||
}
|
||||
|
||||
for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select())
|
||||
error|= sl->cleanup();
|
||||
|
||||
if (fake_select_lex)
|
||||
{
|
||||
if ((join= sl->join))
|
||||
JOIN *join;
|
||||
if ((join= fake_select_lex->join))
|
||||
{
|
||||
error|= sl->join->cleanup();
|
||||
delete join;
|
||||
join->tables_list= 0;
|
||||
join->tables= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// it can be DO/SET with subqueries
|
||||
for (SELECT_LEX_UNIT *lex_unit= sl->first_inner_unit();
|
||||
lex_unit != 0;
|
||||
lex_unit= lex_unit->next_unit())
|
||||
{
|
||||
error|= lex_unit->cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fake_select_lex && (join= fake_select_lex->join))
|
||||
{
|
||||
join->tables_list= 0;
|
||||
join->tables= 0;
|
||||
error|= join->cleanup();
|
||||
delete join;
|
||||
error|= fake_select_lex->cleanup();
|
||||
}
|
||||
|
||||
DBUG_RETURN(error);
|
||||
@ -650,3 +637,24 @@ bool st_select_lex_unit::change_result(select_subselect *result,
|
||||
res= fake_select_lex->join->change_result(result);
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
||||
bool st_select_lex::cleanup()
|
||||
{
|
||||
bool error= FALSE;
|
||||
DBUG_ENTER("st_select_lex::cleanup()");
|
||||
|
||||
if (join)
|
||||
{
|
||||
error|= join->destroy();
|
||||
delete join;
|
||||
join= 0;
|
||||
}
|
||||
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
|
||||
lex_unit= lex_unit->next_unit())
|
||||
{
|
||||
error|= lex_unit->cleanup();
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user