void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
                           List<Item> &fields, Item **ref, 
                           uint split_flags)
{
  if (unlikely(type() == SUM_FUNC_ITEM))
  {
    /* An item of type Item_sum is registered if ref_by != 0 */
    if ((split_flags & SPLIT_SUM_SKIP_REGISTERED) && 
        ((Item_sum *) this)->ref_by)
      return;
  }
  else if (type() == WINDOW_FUNC_ITEM || with_window_func)
  {
    /*
      Skip the else part, window functions are very special functions: 
      they need to have their own fields in the temp. table, but they
      need to be proceessed differently than regular aggregate functions

      Call split_sum_func here so that each argument gets its fields to
      point to the temporary table.
    */
    split_sum_func(thd, ref_pointer_array, fields, split_flags);
    if (type() == FUNC_ITEM) {
      return;
    }
  }
  else
  {
    /* Not a SUM() function */
    if (unlikely((!with_sum_func && !(split_flags & SPLIT_SUM_SELECT))))
    {
      /*
        This is not a SUM function and there are no SUM functions inside.
        Nothing more to do.
      */
      return;
    }
    if (likely(with_sum_func ||
               (type() == FUNC_ITEM &&
                (((Item_func *) this)->functype() ==
                 Item_func::ISNOTNULLTEST_FUNC ||
                 ((Item_func *) this)->functype() ==
                 Item_func::TRIG_COND_FUNC))))
    {
      /* Will call split_sum_func2() for all items */
      split_sum_func(thd, ref_pointer_array, fields, split_flags);
      return;
    }

    if (unlikely((!(used_tables() & ~PARAM_TABLE_BIT) ||
                  (type() == REF_ITEM &&
                   ((Item_ref*)this)->ref_type() != Item_ref::VIEW_REF))))
        return;
  }

  /*
    Replace item with a reference so that we can easily calculate
    it (in case of sum functions) or copy it (in case of fields)

    The test above is to ensure we don't do a reference for things
    that are constants (PARAM_TABLE_BIT is in effect a constant)
    or already referenced (for example an item in HAVING)
    Exception is Item_direct_view_ref which we need to convert to
    Item_ref to allow fields from view being stored in tmp table.
  */
  Item_ref *item_ref;
  uint el= fields.elements;
  /*
    If this is an item_ref, get the original item
    This is a safety measure if this is called for things that is
    already a reference.
  */
  Item *real_itm= real_item();
  ref_pointer_array[el]= real_itm;
  if (type() == WINDOW_FUNC_ITEM)
  {
    if (!(item_ref= (new (thd->mem_root)
                     Item_direct_ref(thd,
                                     &thd->lex->current_select->context,
                                     &ref_pointer_array[el], 0,
                                     &name))))
      return;                                   // fatal_error is set
  }
  else
  {
    if (!(item_ref= (new (thd->mem_root)
                     Item_aggregate_ref(thd,
                                        &thd->lex->current_select->context,
                                        &ref_pointer_array[el], 0,
                                        &name))))
      return;                                   // fatal_error is set
  }
  if (type() == SUM_FUNC_ITEM)
    item_ref->depended_from= ((Item_sum *) this)->depended_from();
  fields.push_front(real_itm);
  thd->change_item_tree(ref, item_ref);
}
void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
                           List<Item> &fields, Item **ref, 
                           uint split_flags)
{
  if (unlikely(type() == SUM_FUNC_ITEM))
  {
     
    if ((split_flags & SPLIT_SUM_SKIP_REGISTERED) && 
        ((Item_sum *) this)->ref_by)
      return;
  }
  else if (type() == WINDOW_FUNC_ITEM || with_window_func)
  {
     
    split_sum_func(thd, ref_pointer_array, fields, split_flags);
    if (type() == FUNC_ITEM) {
      return;
    }
  }
  else
  {
     
    if (unlikely((!with_sum_func && !(split_flags & SPLIT_SUM_SELECT))))
    {
       
      return;
    }
    if (likely(with_sum_func ||
               (type() == FUNC_ITEM &&
                (((Item_func *) this)->functype() ==
                 Item_func::ISNOTNULLTEST_FUNC ||
                 ((Item_func *) this)->functype() ==
                 Item_func::TRIG_COND_FUNC))))
    {
       
      split_sum_func(thd, ref_pointer_array, fields, split_flags);
      return;
    }

    if (unlikely((!(used_tables() & ~PARAM_TABLE_BIT) ||
                  (type() == REF_ITEM &&
                   ((Item_ref*)this)->ref_type() != Item_ref::VIEW_REF))))
        return;
  }

   
  Item_ref *item_ref;
  uint el= fields.elements;
   
  Item *real_itm= real_item();
  ref_pointer_array[el]= real_itm;
  if (type() == WINDOW_FUNC_ITEM)
  {
    if (!(item_ref= (new (thd->mem_root)
                     Item_direct_ref(thd,
                                     &thd->lex->current_select->context,
                                     &ref_pointer_array[el], 0,
                                     &name))))
      return;                                    
  }
  else
  {
    if (!(item_ref= (new (thd->mem_root)
                     Item_aggregate_ref(thd,
                                        &thd->lex->current_select->context,
                                        &ref_pointer_array[el], 0,
                                        &name))))
      return;                                    
  }
  if (type() == SUM_FUNC_ITEM)
    item_ref->depended_from= ((Item_sum *) this)->depended_from();
  fields.push_front(real_itm);
  thd->change_item_tree(ref, item_ref);
}