• Gleb Shchepa's avatar
    backport of bug #54476 fix from 5.1-bugteam to 5.0-bugteam. · d92a7eb1
    Gleb Shchepa authored
    Original revid: alexey.kopytov@sun.com-20100723115254-jjwmhq97b9wl932l
    
     > Bug #54476: crash when group_concat and 'with rollup' in
     >                      prepared statements
     >
     > Using GROUP_CONCAT() together with the WITH ROLLUP modifier
     > could crash the server.
     >
     > The reason was a combination of several facts:
     >
     > 1. The Item_func_group_concat class stores pointers to ORDER
     > objects representing the columns in the ORDER BY clause of
     > GROUP_CONCAT().
     >
     > 2. find_order_in_list() called from
     > Item_func_group_concat::setup() modifies the ORDER objects so
     > that their 'item' member points to the arguments list
     > allocated in the Item_func_group_concat constructor.
     >
     > 3. In some cases (e.g. in JOIN::rollup_make_fields) a copy of
     > the original Item_func_group_concat object could be created by
     > using the Item_func_group_concat::Item_func_group_concat(THD
     > *thd, Item_func_group_concat *item) copy constructor. The
     > latter essentially creates a shallow copy of the source
     > object. Memory for the arguments array is allocated on
     > thd->mem_root, but the pointers for arguments and ORDER are
     > copied verbatim.
     >
     > What happens in the test case is that when executing the query
     > for the first time, after a copy of the original
     > Item_func_group_concat object has been created by
     > JOIN::rollup_make_fields(), find_order_in_list() is called for
     > this new object. It then resolves ORDER BY by modifying the
     > ORDER objects so that they point to elements of the arguments
     > array which is local to the cloned object. When thd->mem_root
     > is freed upon completing the execution, pointers in the ORDER
     > objects become invalid. Those ORDER objects, however, are also
     > shared with the original Item_func_group_concat object which is
     > preserved between executions of a prepared statement. So the
     > first call to find_order_in_list() for the original object on
     > the second execution tries to dereference an invalid pointer.
     >
     > The solution is to create copies of the ORDER objects when
     > copying Item_func_group_concat to not leave any stale pointers
     > in other instances with different lifecycles.
    
    
    mysql-test/r/func_gconcat.result:
      Test case for bug #54476.
    mysql-test/t/func_gconcat.test:
      Test case for bug #54476.
    sql/item_sum.cc:
      Copy the ORDER objects pointed to by the elements of the
      'order' array in the copy constructor of
      Item_func_group_concat.
    sql/table.h:
      Removed the unused 'item_copy' member of the ORDER class.
    d92a7eb1
func_gconcat.test 23.5 KB