Skip to content
  • Norvald H. Ryeng's avatar
    ec6c6c05
    Bug#14601837 CRASH IN ITEM_REF::UPDATE_USED_TABLES ON RE-EXECUTE OF SP · ec6c6c05
    Norvald H. Ryeng authored
    This is a regression caused by the fix for bug #11761078.
    
    Problem: Stored procedures with a HAVING clause using a grouping field
    and ORDER BY the same field twice may cause the server to crash on
    second execution.
    
    During JOIN::prepare() for the first execution, select_lex->order_list
    and select_lex->group_list are traversed when setup_without_group()
    calls setup_order() and setup_group(), respectively. During this
    setup, the ORDER::item pointers are set to point to elements of
    JOIN::ref_ptrs, which again are set to point to the same items as
    ORDER::item_ptr.
    
    When the HAVING clause is resolved, it contains Item_refs for
    references to fields in the GROUP BY list. Item_ref::fix_fields()
    resolves the fields to the Item_field in group_list and copies the
    ORDER::item pointer to Item_ref::ref. I.e., Item_ref::ref now points
    to the element in JOIN::ref_ptrs pointing to the correct Item_field.
    
    JOIN::prepare() calls select_lex->fix_prepare_information() to save
    copies of variables that may be modified during optimization or
    execution and that must be restored before the next execution,
    including the next pointers of group_list. The next pointers of
    order_list, however, are not saved.
    
    Later JOIN::optimize() calls remove_const() to simplify the GROUP BY
    and ORDER BY lists. Since the ORDER BY list orders has the same field
    repeated twice, it can (because of the fix for bug #11761078) be
    simplified by removing one of these fields.
    
    The query then executes for the first time.
    
    When preparing for second execution, the group_list is
    restored. Again, setup_without_group() is called to set up pointers in
    ref_ptrs and pointers to ref_ptrs from order_list and
    group_list. Because the order_list now is one element shorter, all
    subsequent items are placed one position earlier in ref_ptrs.  When
    items of the HAVING clause are resolved again, the Item_ref still has
    its ref pointer, so there is no need to re-resolve. Because of the
    shift in ref_ptrs, the Item_ref's ref pointer now points to the wrong
    element.
    
    During second execution, the ref_ptrs element that is incorrectly
    pointed to by the Item_ref changes, causing a crash when dereferencing
    the Item_ref's ref pointer.
    
    Fix: Save and restore a copy of order_list next pointers in the same
    way as is done for group_list.
    ec6c6c05
    Bug#14601837 CRASH IN ITEM_REF::UPDATE_USED_TABLES ON RE-EXECUTE OF SP
    Norvald H. Ryeng authored
    This is a regression caused by the fix for bug #11761078.
    
    Problem: Stored procedures with a HAVING clause using a grouping field
    and ORDER BY the same field twice may cause the server to crash on
    second execution.
    
    During JOIN::prepare() for the first execution, select_lex->order_list
    and select_lex->group_list are traversed when setup_without_group()
    calls setup_order() and setup_group(), respectively. During this
    setup, the ORDER::item pointers are set to point to elements of
    JOIN::ref_ptrs, which again are set to point to the same items as
    ORDER::item_ptr.
    
    When the HAVING clause is resolved, it contains Item_refs for
    references to fields in the GROUP BY list. Item_ref::fix_fields()
    resolves the fields to the Item_field in group_list and copies the
    ORDER::item pointer to Item_ref::ref. I.e., Item_ref::ref now points
    to the element in JOIN::ref_ptrs pointing to the correct Item_field.
    
    JOIN::prepare() calls select_lex->fix_prepare_information() to save
    copies of variables that may be modified during optimization or
    execution and that must be restored before the next execution,
    including the next pointers of group_list. The next pointers of
    order_list, however, are not saved.
    
    Later JOIN::optimize() calls remove_const() to simplify the GROUP BY
    and ORDER BY lists. Since the ORDER BY list orders has the same field
    repeated twice, it can (because of the fix for bug #11761078) be
    simplified by removing one of these fields.
    
    The query then executes for the first time.
    
    When preparing for second execution, the group_list is
    restored. Again, setup_without_group() is called to set up pointers in
    ref_ptrs and pointers to ref_ptrs from order_list and
    group_list. Because the order_list now is one element shorter, all
    subsequent items are placed one position earlier in ref_ptrs.  When
    items of the HAVING clause are resolved again, the Item_ref still has
    its ref pointer, so there is no need to re-resolve. Because of the
    shift in ref_ptrs, the Item_ref's ref pointer now points to the wrong
    element.
    
    During second execution, the ref_ptrs element that is incorrectly
    pointed to by the Item_ref changes, causing a crash when dereferencing
    the Item_ref's ref pointer.
    
    Fix: Save and restore a copy of order_list next pointers in the same
    way as is done for group_list.
Loading