diff --git a/sql/item.h b/sql/item.h index bb341959103..56d103af168 100644 --- a/sql/item.h +++ b/sql/item.h @@ -89,6 +89,7 @@ public: const char *dbug_print_item(Item *item); +class Virtual_tmp_table; class sp_head; class Protocol; struct TABLE_LIST; @@ -2093,16 +2094,12 @@ public: class Item_spvar_args: public Item_args { - TABLE *m_table; + Virtual_tmp_table *m_table; public: Item_spvar_args():Item_args(), m_table(NULL) { } ~Item_spvar_args(); bool row_create_items(THD *thd, List *list); - Field *get_row_field(uint i) const - { - DBUG_ASSERT(m_table); - return m_table->field[i]; - } + Field *get_row_field(uint i) const; }; diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 43a42b579bd..8290a927a77 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -51,9 +51,7 @@ sp_rcontext::sp_rcontext(const sp_pcontext *root_parsing_ctx, sp_rcontext::~sp_rcontext() { - if (m_var_table) - free_blobs(m_var_table); - + delete m_var_table; // Leave m_handlers, m_handler_call_stack, m_var_items, m_cstack // and m_case_expr_holders untouched. // They are allocated in mem roots and will be freed accordingly. @@ -375,10 +373,16 @@ bool Item_spvar_args::row_create_items(THD *thd, List *list) } +Field *Item_spvar_args::get_row_field(uint i) const +{ + DBUG_ASSERT(m_table); + return m_table->field[i]; +} + + Item_spvar_args::~Item_spvar_args() { - if (m_table) - free_blobs(m_table); + delete m_table; } diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 93c8cacc70a..9a4a8e27032 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -34,6 +34,7 @@ class sp_instr_cpush; class Query_arena; class sp_head; class Item_cache; +class Virtual_tmp_table; /* @@ -365,7 +366,7 @@ private: const sp_pcontext *m_root_parsing_ctx; /// Virtual table for storing SP-variables. - TABLE *m_var_table; + Virtual_tmp_table *m_var_table; /// Collection of Item_field proxies, each of them points to the /// corresponding field in m_var_table. diff --git a/sql/sql_select.h b/sql/sql_select.h index 9f91733ae9c..b6b8deb99f5 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -2013,7 +2013,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, class Virtual_tmp_table: public TABLE { /** - Destruct collected fields. This method is called on errors only, + Destruct collected fields. This method can be called on errors, when we could not make the virtual temporary table completely, e.g. when some of the fields could not be created or added. @@ -2024,7 +2024,10 @@ class Virtual_tmp_table: public TABLE void destruct_fields() { for (uint i= 0; i < s->fields; i++) + { + field[i]->free(); delete field[i]; // to invoke the field destructor + } s->fields= 0; // safety } @@ -2144,7 +2147,7 @@ public: TABLE object ready for read and write in case of success */ -inline TABLE * +inline Virtual_tmp_table * create_virtual_tmp_table(THD *thd, List &field_list) { Virtual_tmp_table *table;