diff options
author | Oleg Smirnov <olernov@gmail.com> | 2022-10-19 13:26:19 +0400 |
---|---|---|
committer | Oleg Smirnov <olernov@gmail.com> | 2022-10-31 19:20:17 +0400 |
commit | 0d927a57d2bfb32384dd024b9b4d1009fa22555a (patch) | |
tree | 681166ec47285ff9f253cd1fb457b37824beff60 /sql/sql_select.cc | |
parent | ce443c855478e931b77058f3a7108c07500220d7 (diff) | |
download | mariadb-git-0d927a57d2bfb32384dd024b9b4d1009fa22555a.tar.gz |
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()
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 34 |
1 files changed, 28 insertions, 6 deletions
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<TABLE_LIST>& join_list) +{ + List_iterator<TABLE_LIST> 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()); } |