Skip to content
  • Norvald H. Ryeng's avatar
    4491e146
    Bug#16509874 ASSERTION FAILED: SL->JOIN == 0, FILE SQL_PREPARE.CC, · 4491e146
    Norvald H. Ryeng authored
    LINE 2484
    
    This is a regression caused by the fix for bug #16318585.
    
    Problem: The server crashes when a clause containing an Item_ref
    pointing to a subquery is removed.
    
    When remove_redundant_subquery_clauses() removes a subtree of the item
    tree for a query, a walk with the Item::clean_up_after_removal()
    processor is done to do necessary cleanup in some items of the removed
    subtree.
    
    As part of this cleanup, Item_subselect::clean_up_after_removal()
    unlinks the st_select_lexes of subqueries from
    LEX::all_selects_list by calling unit->exclude_tree(). If the walk
    encounters an Item_ref pointing to an Item_subselect, it follows the
    ref pointer and calls the processor on that Item_subselect.
    
    If the Item_subselect pointed to by the Item_ref is a part of the
    removed subtree, st_select_lex_unit::exclude_tree() is called twice,
    once when the walk finds the Item_subselect and once when the walk
    traverses the Item_ref to find the Item_subselect. If the
    Item_subselect is not part of the removed subtree, it is still
    unlinked from LEX::all_selects_list, even if it is still part of the
    remaining item tree.
    
    Fix: Set pointers to other st_select_lex_nodes to NULL in
    st_select_lex_unit::exclude_tree() and
    st_select_lex_unit::exclude_level(), and make it safe to run the
    functions on a unit that has already been removed from the tree.
    
    To avoid unlinking outer subqueries, pass the pointer to the
    st_select_lex that contains the clause that is removed to
    Item_subselect::clean_up_after_removal(), and call
    st_select_lex_unit::exclude_tree() only for subqueries that are
    descendants of that st_select_lex.
    
    Nulling out the st_select_lex_node pointers triggers a bug in how
    subselect_single_select_engine::exclude() unlinks st_select_lex_unit
    and st_select_lex objects. If there is a prepared statement with a
    hierarchy of subqueries, and one of the middle subqueries are
    eliminated, the Name_resolution_context for the corresponding
    st_select_lex is still in the chain of contexts for inner items. When
    the query is executed, Item_field::fix_outer_field() dereferences the
    nulled st_select_lex::master pointer.
    
    Fix: Change the context.outer_context of inner subqueries of a
    subquery that is removed by st_select_lex_unit::exclude_level() to
    point to the outer_context of the removed subquery's context, i.e.,
    skipping the context of the removed subquery.
    4491e146
    Bug#16509874 ASSERTION FAILED: SL->JOIN == 0, FILE SQL_PREPARE.CC,
    Norvald H. Ryeng authored
    LINE 2484
    
    This is a regression caused by the fix for bug #16318585.
    
    Problem: The server crashes when a clause containing an Item_ref
    pointing to a subquery is removed.
    
    When remove_redundant_subquery_clauses() removes a subtree of the item
    tree for a query, a walk with the Item::clean_up_after_removal()
    processor is done to do necessary cleanup in some items of the removed
    subtree.
    
    As part of this cleanup, Item_subselect::clean_up_after_removal()
    unlinks the st_select_lexes of subqueries from
    LEX::all_selects_list by calling unit->exclude_tree(). If the walk
    encounters an Item_ref pointing to an Item_subselect, it follows the
    ref pointer and calls the processor on that Item_subselect.
    
    If the Item_subselect pointed to by the Item_ref is a part of the
    removed subtree, st_select_lex_unit::exclude_tree() is called twice,
    once when the walk finds the Item_subselect and once when the walk
    traverses the Item_ref to find the Item_subselect. If the
    Item_subselect is not part of the removed subtree, it is still
    unlinked from LEX::all_selects_list, even if it is still part of the
    remaining item tree.
    
    Fix: Set pointers to other st_select_lex_nodes to NULL in
    st_select_lex_unit::exclude_tree() and
    st_select_lex_unit::exclude_level(), and make it safe to run the
    functions on a unit that has already been removed from the tree.
    
    To avoid unlinking outer subqueries, pass the pointer to the
    st_select_lex that contains the clause that is removed to
    Item_subselect::clean_up_after_removal(), and call
    st_select_lex_unit::exclude_tree() only for subqueries that are
    descendants of that st_select_lex.
    
    Nulling out the st_select_lex_node pointers triggers a bug in how
    subselect_single_select_engine::exclude() unlinks st_select_lex_unit
    and st_select_lex objects. If there is a prepared statement with a
    hierarchy of subqueries, and one of the middle subqueries are
    eliminated, the Name_resolution_context for the corresponding
    st_select_lex is still in the chain of contexts for inner items. When
    the query is executed, Item_field::fix_outer_field() dereferences the
    nulled st_select_lex::master pointer.
    
    Fix: Change the context.outer_context of inner subqueries of a
    subquery that is removed by st_select_lex_unit::exclude_level() to
    point to the outer_context of the removed subquery's context, i.e.,
    skipping the context of the removed subquery.
Loading