diff options
author | Alexey Kopytov <Alexey.Kopytov@Sun.com> | 2010-08-24 14:35:48 +0400 |
---|---|---|
committer | Alexey Kopytov <Alexey.Kopytov@Sun.com> | 2010-08-24 14:35:48 +0400 |
commit | cd4ca4b7a3d8e2971f76858895b36829d27fe845 (patch) | |
tree | e632c3ba6d403157c6e6c9a0fb13660b8dcd7183 /sql | |
parent | 9ab59902a96e22e827fc2bb7681a7cf178c6c7f1 (diff) | |
download | mariadb-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.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 22 | ||||
-rw-r--r-- | sql/sql_select.h | 1 |
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; }; |