Details
-
Bug
-
Status: Closed (View Workflow)
-
Minor
-
Resolution: Cannot Reproduce
-
10.0.9
-
None
-
None
Description
The following revision doesn't seem to be merged into 10.0. Found while analyzing result difference in ps_ddl1.test:
revno: 4591.1.70
|
committer: Guilhem Bichot <guilhem.bichot@oracle.com>
|
branch nick: 5.6-3
|
timestamp: Sat 2012-11-24 15:45:56 +0100
|
message:
|
fix for Bug#13996639 CRASH IN ITEM_REF::FIX_FIELDS ON EXEC OF STORED
|
FUNCTION WITH ONLY_FULL_GROUP_BY. See per-file comments.
|
|
mysql-test/r/ps_ddl1.result:
|
side affect of the bugfix; this is a good change, as the removed comment says.
|
sql/sql_lex.cc:
|
LEX starts clean
|
sql/sql_optimizer.cc:
|
If optimize () fails, tag the Lex as "broken"
|
sql/sql_parse.cc:
|
At first execution of:
|
SELECT stored_func()
|
this happens:
|
1) body of stored_func is read from mysql.proc
|
2) body is parsed (sp_compile()) (for each substatement a LEX and some
|
Items are created)
|
3) parsing went ok so parse trees are cached (sp_cache_insert())
|
4) substatement starts executing (SELECT with a NOT IN (subq))
|
4.1) Item_in_subselect::fix_fields():
|
if (!(res= engine->prepare()))
|
{
|
(*ref)= substitution;
|
engine->prepare() calls JOIN::prepare() on subq, which calls
|
resolve_subquery() which starts IN2EXISTS transformation: adds
|
conditions (using some new Item_ref) to the subquery's WHERE, creates
|
Item_in_optimizer and puts it in 'substitution'. After
|
resolve_subquery(), JOIN::prepare() of subq fails in:
|
|
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
|
ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
|
DBUG_RETURN(-1);
|
|
So far, so good.
|
Thus engine->prepare() fails. Thus we don't do:
|
(*ref)= substitution;
|
i.e. the parent of the subquery continues to have its WHERE point to
|
Item_in_subselect. At this stage we have a broken parse tree, because
|
subq has been transformed but parent query points to pre-transform
|
subq. This mess is not rolled back (IN2EXISTS is a complex transform
|
which does not use change_item_tree()).
|
ER_MIX_OF_GROUP_FUNC_AND_FIELDS is sent to client.
|
So far, so good.
|
|
At 2nd execution of:
|
SELECT stored_func()
|
this happens:
|
1) cached parse trees of stored_func is read from cache
|
2) but this is the broken parse tree!
|
3) as the Item_ref depends on Item_in_optimizer::fix_fields() to set
|
its '*ref', and as Item_in_optimizer was not stored in parent query,
|
Item_in_optimizer::fix_fields() is not called, so
|
Item_ref::fix_fields() crashes.
|
|
Summary: first execution broke Item_in_subselect/LEX, 2nd execution reused it.
|
|
Solution: first execution marks the fact that it
|
broke LEX; 2nd execution sees the mark and asks for a
|
reprepare, which creates new parse trees, and thus works as the first
|
execution.
|
A new member m_broken is added to class LEX. It is set to "true" when
|
JOIN:: prepare () or JOIN:: optimize () fail, because it is possible
|
that those functions were doing transformations. It is set to "false"
|
when the Lex is initialized.
|
sql/sql_resolver.cc:
|
If prepare () fails, tag the Lex as "broken"
|
Attachments
Issue Links
- is part of
-
MDEV-4784 merge test cases from 5.6
- Stalled