summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-08-24 14:35:48 +0400
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-08-24 14:35:48 +0400
commitcd4ca4b7a3d8e2971f76858895b36829d27fe845 (patch)
treee632c3ba6d403157c6e6c9a0fb13660b8dcd7183 /sql
parent9ab59902a96e22e827fc2bb7681a7cf178c6c7f1 (diff)
downloadmariadb-git-cd4ca4b7a3d8e2971f76858895b36829d27fe845.tar.gz
Bug #55568: user variable assignments crash server when used
within query The server could crash after materializing a derived table which requires a temporary table for grouping. When destroying the temporary table used to execute a query for a derived table, JOIN::destroy() did not clean up Item_fields pointing to fields in the temporary table. This led to dereferencing a dangling pointer when printing out the items tree later in the outer SELECT. The solution is an addendum to the patch for bug37362: in addition to cleaning up items in tmp_all_fields3, do the same for items in tmp_all_fields1, since now we have an example where this is necessary. mysql-test/r/join.result: Added test cases for bug#55568 and a duplicate bug #54468. mysql-test/t/join.test: Added test cases for bug#55568 and a duplicate bug #54468. sql/field.cc: Make sure field->table_name is not set to NULL in Field::make_field() to avoid assertion failure in Item_field::make_field() after cleaning up items (the assertion fired in udf.test when running the test suite with the patch applied). sql/sql_select.cc: In addition to cleaning up items in tmp_all_fields3, do the same for items in tmp_all_fields1. Introduce a new helper function to avoid code duplication. sql/sql_select.h: Introduce a new helper function to avoid code duplication in JOIN::destroy().
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc2
-rw-r--r--sql/sql_select.cc22
-rw-r--r--sql/sql_select.h1
3 files changed, 17 insertions, 8 deletions
diff --git a/sql/field.cc b/sql/field.cc
index c887a5f1c9b..619e6a780da 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1535,7 +1535,7 @@ void Field::make_field(Send_field *field)
}
else
field->org_table_name= field->db_name= "";
- if (orig_table)
+ if (orig_table && orig_table->alias)
{
field->table_name= orig_table->alias;
field->org_col_name= field_name;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2fc287bbe66..fc137f5fd90 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2378,13 +2378,8 @@ JOIN::destroy()
cleanup(1);
/* Cleanup items referencing temporary table columns */
- if (!tmp_all_fields3.is_empty())
- {
- List_iterator_fast<Item> it(tmp_all_fields3);
- Item *item;
- while ((item= it++))
- item->cleanup();
- }
+ cleanup_item_list(tmp_all_fields1);
+ cleanup_item_list(tmp_all_fields3);
if (exec_tmp_table1)
free_tmp_table(thd, exec_tmp_table1);
if (exec_tmp_table2)
@@ -2395,6 +2390,19 @@ JOIN::destroy()
DBUG_RETURN(error);
}
+
+void JOIN::cleanup_item_list(List<Item> &items) const
+{
+ if (!items.is_empty())
+ {
+ List_iterator_fast<Item> it(items);
+ Item *item;
+ while ((item= it++))
+ item->cleanup();
+ }
+}
+
+
/**
An entry point to single-unit select (a select without UNION).
diff --git a/sql/sql_select.h b/sql/sql_select.h
index b39827ef61b..007dc91957c 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -577,6 +577,7 @@ private:
*/
bool implicit_grouping;
bool make_simple_join(JOIN *join, TABLE *tmp_table);
+ void cleanup_item_list(List<Item> &items) const;
};