select
single_row_subselect (select with non-mergeable semi-join subselect) as field3
from
...
group by
... field3
having
field3 < 'e' and ...
order by
..., field3, ...
limit ..
Things to note:
- single_row_subselect is uncorrelated
- it is used in select list, group list, order by list.
== Execution ==
Execution proceeds as follows:
- single_row_subselect is put into top-level select's
exec_const_order_group_cond list.
- JOIN::exec calls cur_const_item->val_str, which evaluates the
single_row_subselect:
= single_row_subselect has a non-mergeable semi-join which is executed
as materialized join tab (a temporary table is created, and the
IN-equality is injected into subquery's WHERE condition)
= After the subquery has finished executing, the code for materialized
join_tab makes this call:
#1 in Item_in_subselect::cleanup
#2 in st_join_table::cleanup
#3 in JOIN::cleanup
#4 in JOIN::join_free
#5 in do_select
#6 in JOIN::exec
#7 in subselect_single_select_engine::exec
#8 in Item_subselect::exec
#9 in Item_singlerow_subselect::val_str
...
= single_row_subselect execution is completed. The code for top-level select
makes multiple attempts to evaluate the single_row_subselect but since it
is uncorrelated, any subsequent attempts only fetch the cached value.
- evenually, execution of upper select reaches filesort() which calls
find_all_keys() which runs this line:
An outline of the crashing scenario:
== Query ==
The query has this structure:
select row_subselect (select with non-mergeable
semi- join subselect) as field3
single_
from
...
group by
... field3
having
field3 < 'e' and ...
order by
..., field3, ...
limit ..
Things to note: row_subselect is uncorrelated
- single_
- it is used in select list, group list, order by list.
== Execution == row_subselect is put into top-level select's const_order_ group_cond list. item->val_ str, which evaluates the row_subselect:
Execution proceeds as follows:
- single_
exec_
- JOIN::exec calls cur_const_
single_
= single_ row_subselect has a non-mergeable semi-join which is executed
as materialized join tab (a temporary table is created, and the
IN-equality is injected into subquery's WHERE condition)
= After the subquery has finished executing, the code for materialized
join_tab makes this call:
the stack trace at this point looks as follows:
#1 in Item_in_ subselect: :cleanup table:: cleanup single_ select_ engine: :exec :exec subselect: :val_str
#2 in st_join_
#3 in JOIN::cleanup
#4 in JOIN::join_free
#5 in do_select
#6 in JOIN::exec
#7 in subselect_
#8 in Item_subselect:
#9 in Item_singlerow_
...
= single_ row_subselect execution is completed. The code for top-level select row_subselect but since it
makes multiple attempts to evaluate the single_
is uncorrelated, any subsequent attempts only fetch the cached value.
- evenually, execution of upper select reaches filesort() which calls
find_all_keys() which runs this line:
select- >cond-> walk(&Item: :register_ field_in_ read_map, 1,
(uchar* ) sort_form);
where
select->cond = ((`field3` < 'e') and (`field1` < 242))
where field3 is the single_ row_subselect.
field3- >Item_subselect ::walk is called which will at some point invoke
Item_ field:: register_ field_in_ read_map
for the field object that refers to already-freed temporary table.