diff options
author | Tor Didriksen <tor.didriksen@oracle.com> | 2012-03-29 15:07:54 +0200 |
---|---|---|
committer | Tor Didriksen <tor.didriksen@oracle.com> | 2012-03-29 15:07:54 +0200 |
commit | 71261282b183d07a2b0281d668fd8218170f06e9 (patch) | |
tree | 0be98efd7bd42720d221310b7c3a8949439296df /sql/sql_lex.h | |
parent | 90436a096c4ec21376752713a89d2b8997b15757 (diff) | |
download | mariadb-git-71261282b183d07a2b0281d668fd8218170f06e9.tar.gz |
Patch for Bug#13805127: Stored program cache produces wrong result in same THD.
Background:
- as described in MySQL Internals Prepared Stored
(http://forge.mysql.com/wiki/MySQL_Internals_Prepared_Stored),
the Optimizer sometimes does destructive changes to the parsed
LEX-object (Item-tree), which makes it impossible to re-use
that tree for PS/SP re-execution.
- in order to be able to re-use the Item-tree, the destructive
changes are remembered and rolled back after the statement execution.
The problem, discovered by this bug, was that the objects representing
GROUP-BY clause did not restored after query execution. So, the GROUP-BY
part of the statement could not be properly re-initialized for re-execution
after destructive changes.
Those objects do not take part in the Item-tree, so they can not be saved
using the approach for Item-tree.
The fix is as follows:
- introduce a new array in st_select_lex to store the original
ORDER pointers, representing the GROUP-BY clause;
- Initialize this array in fix_prepare_information().
- restore the list of GROUP-BY items in reinit_stmt_before_use().
Diffstat (limited to 'sql/sql_lex.h')
-rw-r--r-- | sql/sql_lex.h | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c89057a4f75..6d004d0fa24 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -24,6 +24,7 @@ #include "sql_trigger.h" #include "item.h" /* From item_subselect.h: subselect_union_engine */ #include "thr_lock.h" /* thr_lock_type, TL_UNLOCK */ +#include "mem_root_array.h" /* YACC and LEX Definitions */ @@ -258,6 +259,7 @@ enum enum_drop_mode #define TL_OPTION_ALIAS 8 typedef List<Item> List_item; +typedef Mem_root_array<ORDER*, true> Group_list_ptrs; /* SERVERS CACHE CHANGES */ typedef struct st_lex_server_options @@ -693,7 +695,16 @@ public: enum olap_type olap; /* FROM clause - points to the beginning of the TABLE_LIST::next_local list. */ SQL_I_List<TABLE_LIST> table_list; - SQL_I_List<ORDER> group_list; /* GROUP BY clause. */ + + /* + GROUP BY clause. + This list may be mutated during optimization (by remove_const()), + so for prepared statements, we keep a copy of the ORDER.next pointers in + group_list_ptrs, and re-establish the original list before each execution. + */ + SQL_I_List<ORDER> group_list; + Group_list_ptrs *group_list_ptrs; + List<Item> item_list; /* list of fields & expressions */ List<String> interval_list; bool is_item_list_lookup; @@ -870,7 +881,8 @@ public: bool test_limit(); friend void lex_start(THD *thd); - st_select_lex() : n_sum_items(0), n_child_sum_items(0) {} + st_select_lex() : group_list_ptrs(NULL), n_sum_items(0), n_child_sum_items(0) + {} void make_empty_select() { init_query(); |