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 | ed418461614d912fbb114053508b3fb09b1fc2f0 (patch) | |
tree | 0be98efd7bd42720d221310b7c3a8949439296df /sql/sql_prepare.cc | |
parent | d1809a5c85bf76136aa7645c152e9f723fd4250b (diff) | |
download | mariadb-git-ed418461614d912fbb114053508b3fb09b1fc2f0.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_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 8390594c2eb..d0bfecebc82 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2422,6 +2422,14 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) DBUG_ASSERT(sl->join == 0); ORDER *order; /* Fix GROUP list */ + if (sl->group_list_ptrs && sl->group_list_ptrs->size() > 0) + { + for (uint ix= 0; ix < sl->group_list_ptrs->size() - 1; ++ix) + { + order= sl->group_list_ptrs->at(ix); + order->next= sl->group_list_ptrs->at(ix+1); + } + } for (order= sl->group_list.first; order; order= order->next) order->item= &order->item_ptr; /* Fix ORDER list */ |