summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sql_derived.cc2
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_select.cc66
-rw-r--r--sql/sql_select.h2
-rw-r--r--sql/sql_union.cc6
6 files changed, 50 insertions, 30 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 6e70fdd46d5..0e04316a2e7 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -204,6 +204,8 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
table->file->info(HA_STATUS_VARIABLE);
}
+ if (!lex->describe)
+ unit->cleanup();
if (res)
free_tmp_table(thd, table);
else
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 62f255ea178..65357328927 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -988,6 +988,7 @@ void st_select_lex_unit::init_query()
union_result= 0;
table= 0;
fake_select_lex= 0;
+ cleaned= 0;
}
void st_select_lex::init_query()
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 3b1b3873706..3f56be18c4a 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -305,7 +305,8 @@ protected:
ulong found_rows_for_union;
bool prepared, // prepare phase already performed for UNION (unit)
optimized, // optimize phase already performed for UNION (unit)
- executed; // already executed
+ executed, // already executed
+ cleaned;
public:
// list of fields which points to temporary table for union
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 082a06d97de..ea5050f2550 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1510,12 +1510,7 @@ JOIN::cleanup()
JOIN_TAB *tab, *end;
for (tab= join_tab, end= tab+tables ; tab != end ; tab++)
{
- delete tab->select;
- delete tab->quick;
- tab->select=0;
- tab->quick=0;
- x_free(tab->cache.buff);
- tab->cache.buff= 0;
+ tab->cleanup();
}
}
tmp_join->tmp_join= 0;
@@ -3760,6 +3755,41 @@ bool error_if_full_join(JOIN *join)
/*
+ cleanup JOIN_TAB
+
+ SYNOPSIS
+ JOIN_TAB::cleanup()
+*/
+
+void JOIN_TAB::cleanup()
+{
+ delete select;
+ select= 0;
+ delete quick;
+ quick= 0;
+ x_free(cache.buff);
+ cache.buff= 0;
+ if (table)
+ {
+ if (table->key_read)
+ {
+ table->key_read= 0;
+ table->file->extra(HA_EXTRA_NO_KEYREAD);
+ }
+ /* Don't free index if we are using read_record */
+ if (!read_record.table)
+ table->file->index_end();
+ /*
+ We need to reset this for next select
+ (Tested in part_of_refkey)
+ */
+ table->reginfo.join_tab= 0;
+ }
+ end_read_record(&read_record);
+}
+
+
+/*
Free resources of given join
SYNOPSIS
@@ -3803,29 +3833,7 @@ JOIN::join_free(bool full)
{
for (tab= join_tab, end= tab+tables; tab != end; tab++)
{
- delete tab->select;
- delete tab->quick;
- tab->select=0;
- tab->quick=0;
- x_free(tab->cache.buff);
- tab->cache.buff= 0;
- if (tab->table)
- {
- if (tab->table->key_read)
- {
- tab->table->key_read= 0;
- tab->table->file->extra(HA_EXTRA_NO_KEYREAD);
- }
- /* Don't free index if we are using read_record */
- if (!tab->read_record.table)
- tab->table->file->index_end();
- /*
- We need to reset this for next select
- (Tested in part_of_refkey)
- */
- tab->table->reginfo.join_tab= 0;
- }
- end_read_record(&tab->read_record);
+ tab->cleanup();
}
table= 0;
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index a463378006b..36526bee066 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -108,6 +108,8 @@ typedef struct st_join_table {
TABLE_REF ref;
JOIN_CACHE cache;
JOIN *join;
+
+ void cleanup();
} JOIN_TAB;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 226086d0d24..75fd9be88bd 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -442,6 +442,12 @@ int st_select_lex_unit::cleanup()
int error= 0;
DBUG_ENTER("st_select_lex_unit::cleanup");
+ if (cleaned)
+ {
+ DBUG_RETURN(0);
+ }
+ cleaned= 0;
+
if (union_result)
{
delete union_result;