diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_select.h | 17 | ||||
-rw-r--r-- | sql/sql_show.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 8 |
3 files changed, 21 insertions, 6 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()) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 32e7d6f140b..d1d1410d51a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4667,7 +4667,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table, table_list.view= (LEX*) share->is_view; res= schema_table->process_table(thd, &table_list, table, res, db_name, table_name); - free_root(&tbl.mem_root, MYF(0)); + closefrm(&tbl); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 412fcce8625..fdb40407ffb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6013,8 +6013,8 @@ field_list_item: ; column_def: - field_spec opt_check_constraint - { $$= $1; $$->check_constraint= $2; } + field_spec + { $$= $1; } | field_spec references { $$= $1; } ; @@ -6152,11 +6152,13 @@ field_spec: lex->init_last_field(f, $1.str, NULL); $<create_field>$= f; } - field_type_or_serial + field_type_or_serial opt_check_constraint { LEX *lex=Lex; $$= $<create_field>2; + $$->check_constraint= $4; + if ($$->check(thd)) MYSQL_YYABORT; |