Skip to content
  • Roy Lyseng's avatar
    087909bb
    Bug#32343143: Error at SELECT_LEX::convert_subquery_to_semijoin · 087909bb
    Roy Lyseng authored
    We have a query block with 12 EXISTS subquery predicates that are
    candidates for semijoin transformation. All subqueries except one are
    proper candidates. The last one (number 8) is always false, and is thus
    removed from the sj_candidates array. All remaining subquery predicates
    are transformed to semi-join, except for one (number 11), which is not
    transformed due to having too many tables in its query block.
    While transforming subquery predicate number 2, it is detected that
    the full condition is always false (due to the already transformed
    always false subquery predicate), so the subquery that was not
    transformed is removed from sj_candidates. Thus, the size of
    sj_candidates is down to 10 elements, however, the pointer to the end
    sj_candidates (subq_end) is not updated, and thus we actually meet
    the last subquery predicate twice during semijoin transformation.
    The second time it is inspected, the contents of the subquery has been
    deleted and we try to traverse a pointer that has been reset.
    
    The fix to the problem is to stop deleting subquery predicates from
    sj_candidates within Item_subselect::clean_up_after_removal()
    and rather set a DELETED flag which can be checked in
    Query_block::flatten_subqueries(), thus avoiding objects being
    deleted under our feet.
    
    Another transformation status (DELETED) has been added.
    The transformation status ALWAYS_FALSE is deleted, since we can go
    directly to DELETED.
    
    Query_block::remove_semijoin_candidate() is replaced with a new
    virtual function Item::notify_removal().
    
    Reviewed by: Chaithra Gopalareddy <chaithra.gopalareddy@oracle.com>
    087909bb
    Bug#32343143: Error at SELECT_LEX::convert_subquery_to_semijoin
    Roy Lyseng authored
    We have a query block with 12 EXISTS subquery predicates that are
    candidates for semijoin transformation. All subqueries except one are
    proper candidates. The last one (number 8) is always false, and is thus
    removed from the sj_candidates array. All remaining subquery predicates
    are transformed to semi-join, except for one (number 11), which is not
    transformed due to having too many tables in its query block.
    While transforming subquery predicate number 2, it is detected that
    the full condition is always false (due to the already transformed
    always false subquery predicate), so the subquery that was not
    transformed is removed from sj_candidates. Thus, the size of
    sj_candidates is down to 10 elements, however, the pointer to the end
    sj_candidates (subq_end) is not updated, and thus we actually meet
    the last subquery predicate twice during semijoin transformation.
    The second time it is inspected, the contents of the subquery has been
    deleted and we try to traverse a pointer that has been reset.
    
    The fix to the problem is to stop deleting subquery predicates from
    sj_candidates within Item_subselect::clean_up_after_removal()
    and rather set a DELETED flag which can be checked in
    Query_block::flatten_subqueries(), thus avoiding objects being
    deleted under our feet.
    
    Another transformation status (DELETED) has been added.
    The transformation status ALWAYS_FALSE is deleted, since we can go
    directly to DELETED.
    
    Query_block::remove_semijoin_candidate() is replaced with a new
    virtual function Item::notify_removal().
    
    Reviewed by: Chaithra Gopalareddy <chaithra.gopalareddy@oracle.com>
Loading