From 0d927a57d2bfb32384dd024b9b4d1009fa22555a Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Wed, 19 Oct 2022 13:26:19 +0400 Subject: MDEV-29624 MDEV-29655 Fix ASAN errors on pushdown of derived table Deallocation of TABLE_LIST::dt_handler and TABLE_LIST::pushdown_derived was performed in multiple places if code. This not only made the code more difficult to maintain but also led to memory leaks and ASAN heap-use-after-free errors. This commit puts deallocation of TABLE_LIST::dt_handler and TABLE_LIST::pushdown_derived to the single point - JOIN::cleanup() --- sql/sql_select.cc | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5ec88e5259c..c7a0bfe93ac 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -68,6 +68,7 @@ #include "select_handler.h" #include "my_json_writer.h" #include "opt_trace.h" +#include "derived_handler.h" /* A key part number that means we're using a fulltext scan. @@ -14086,6 +14087,7 @@ void JOIN::cleanup(bool full) } } } + free_pushdown_handlers(*join_list); } /* Restore ref array to original state */ if (current_ref_ptrs != items0) @@ -14096,6 +14098,32 @@ void JOIN::cleanup(bool full) DBUG_VOID_RETURN; } +/** + Clean up all derived pushdown handlers in this join. + + @detail + Note that dt_handler is picked at the prepare stage (as opposed + to optimization stage where one could expect this). + Because of that, we have to do cleanups in this function that is called + from JOIN::cleanup() and not in JOIN_TAB::cleanup. + */ +void JOIN::free_pushdown_handlers(List& join_list) +{ + List_iterator li(join_list); + TABLE_LIST *table_ref; + while ((table_ref= li++)) + { + if (table_ref->nested_join) + free_pushdown_handlers(table_ref->nested_join->join_list); + if (table_ref->pushdown_derived) + { + delete table_ref->pushdown_derived; + table_ref->pushdown_derived= NULL; + } + delete table_ref->dt_handler; + table_ref->dt_handler= NULL; + } +} /** Remove the following expressions from ORDER BY and GROUP BY: @@ -27400,12 +27428,6 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) result, unit, first); } - if (unit->derived && unit->derived->pushdown_derived) - { - delete unit->derived->pushdown_derived; - unit->derived->pushdown_derived= NULL; - } - DBUG_RETURN(res || thd->is_error()); } -- cgit v1.2.1