diff options
author | Sergey Glukhov <Sergey.Glukhov@sun.com> | 2009-05-15 12:03:34 +0500 |
---|---|---|
committer | Sergey Glukhov <Sergey.Glukhov@sun.com> | 2009-05-15 12:03:34 +0500 |
commit | f024bde47392053b7e0801310ff235c4965aede7 (patch) | |
tree | c83f6124be299756d10d2cca2430ee5dc5cd04da /sql/sql_union.cc | |
parent | 1ae3d2ac68c7af9a431fee8177df13c319463544 (diff) | |
download | mariadb-git-f024bde47392053b7e0801310ff235c4965aede7.tar.gz |
Bug#43612 crash with explain extended, union, order by
In UNION if we use last SELECT without braces and this
SELECT have ORDER BY clause, such clause belongs to
global UNION. It is parsed like last SELECT
part and used further as 'unit->global_parameters->order_list' value.
During DESCRIBE EXTENDED we call select_lex->print_order() for
last SELECT where order fields refer to tmp table
which already freed. It leads to crash.
The fix is clean up global_parameters->order_list
instead of fake_select_lex->order_list.
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r-- | sql/sql_union.cc | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 2875aefbd97..fca5c205610 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -653,10 +653,22 @@ bool st_select_lex_unit::cleanup() join->tables= 0; } error|= fake_select_lex->cleanup(); - if (fake_select_lex->order_list.elements) + /* + There are two cases when we should clean order items: + 1. UNION with SELECTs which all enclosed into braces + in this case global_parameters == fake_select_lex + 2. UNION where last SELECT is not enclosed into braces + in this case global_parameters == 'last select' + So we should use global_parameters->order_list for + proper order list clean up. + Note: global_parameters and fake_select_lex are always + initialized for UNION + */ + DBUG_ASSERT(global_parameters); + if (global_parameters->order_list.elements) { ORDER *ord; - for (ord= (ORDER*)fake_select_lex->order_list.first; ord; ord= ord->next) + for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next) (*ord->item)->cleanup(); } } |