summaryrefslogtreecommitdiff
path: root/sql/sql_select.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-03-31 15:18:28 +0400
committerAlexander Barkov <bar@mariadb.org>2017-03-31 15:18:28 +0400
commit2f3d4bd566b5e377fe8a1749c14050b0a0e083d0 (patch)
treee8bc0341840e4b5499153c086101fbc07cd2190d /sql/sql_select.h
parenta0c79bcf0062adc2489f0b0bed98b05d4db8f476 (diff)
downloadmariadb-git-2f3d4bd566b5e377fe8a1749c14050b0a0e083d0.tar.gz
MDEV-12416 OOM in create_virtual_tmp_table() makes the server crash
Diffstat (limited to 'sql/sql_select.h')
-rw-r--r--sql/sql_select.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 0d4570fbe47..4327646cdee 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1993,7 +1993,7 @@ class Virtual_tmp_table: public TABLE
This is needed to avoid memory leaks, as some fields can be BLOB
variants and thus can have String onboard. Strings must be destructed
- as they store data not the heap (not on MEM_ROOT).
+ as they store data on the heap (not on MEM_ROOT).
*/
void destruct_fields()
{
@@ -2025,6 +2025,7 @@ public:
@param thd - Current thread.
*/
static void *operator new(size_t size, THD *thd) throw();
+ static void operator delete(void *ptr, size_t size) { TRASH(ptr, size); }
Virtual_tmp_table(THD *thd)
{
@@ -2035,7 +2036,8 @@ public:
~Virtual_tmp_table()
{
- destruct_fields();
+ if (s)
+ destruct_fields();
}
/**
@@ -2120,6 +2122,17 @@ create_virtual_tmp_table(THD *thd, List<Column_definition> &field_list)
Virtual_tmp_table *table;
if (!(table= new(thd) Virtual_tmp_table(thd)))
return NULL;
+
+ /*
+ If "simulate_create_virtual_tmp_table_out_of_memory" debug option
+ is enabled, we now enable "simulate_out_of_memory". This effectively
+ makes table->init() fail on OOM inside multi_alloc_root().
+ This is done to test that ~Virtual_tmp_table() called from the "delete"
+ below correcly handles OOM.
+ */
+ DBUG_EXECUTE_IF("simulate_create_virtual_tmp_table_out_of_memory",
+ DBUG_SET("+d,simulate_out_of_memory"););
+
if (table->init(field_list.elements) ||
table->add(field_list) ||
table->open())