Comment 4 for bug 860580

Revision history for this message
Sergey Petrunia (sergefp) wrote :

An outline of the crashing scenario:

== Query ==
The query has this structure:

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:

        table->pos_in_table_list->jtbm_subselect->cleanup();

    the stack trace at this point looks as follows:

        #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:

    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.