summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorOleg Smirnov <olernov@gmail.com>2022-10-19 13:26:19 +0400
committerOleg Smirnov <olernov@gmail.com>2022-10-31 19:20:17 +0400
commit0d927a57d2bfb32384dd024b9b4d1009fa22555a (patch)
tree681166ec47285ff9f253cd1fb457b37824beff60 /sql/sql_select.cc
parentce443c855478e931b77058f3a7108c07500220d7 (diff)
downloadmariadb-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.cc34
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());
}