-
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.
Norvald H. Ryeng authoredLINE 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