item_sum.cc 88.7 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2000-2003 MySQL AB
unknown's avatar
unknown committed
2

unknown's avatar
unknown committed
3 4
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
5
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
6

unknown's avatar
unknown committed
7 8 9 10
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
unknown's avatar
unknown committed
11

unknown's avatar
unknown committed
12 13 14 15 16
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


unknown's avatar
unknown committed
17 18 19 20 21 22
/**
  @file

  @brief
  Sum functions (COUNT, MIN...)
*/
unknown's avatar
unknown committed
23

24
#ifdef USE_PRAGMA_IMPLEMENTATION
unknown's avatar
unknown committed
25 26 27 28
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
29
#include "sql_select.h"
unknown's avatar
unknown committed
30

unknown's avatar
unknown committed
31 32
/**
  Prepare an aggregate function item for checking context conditions.
unknown's avatar
unknown committed
33 34 35 36 37 38 39

    The function initializes the members of the Item_sum object created
    for a set function that are used to check validity of the set function
    occurrence.
    If the set function is not allowed in any subquery where it occurs
    an error is reported immediately.

unknown's avatar
unknown committed
40 41 42
  @param thd      reference to the thread context info

  @note
unknown's avatar
unknown committed
43 44 45 46
    This function is to be called for any item created for a set function
    object when the traversal of trees built for expressions used in the query
    is performed at the phase of context analysis. This function is to
    be invoked at the descent of this traversal.
unknown's avatar
unknown committed
47 48 49
  @retval
    TRUE   if an error is reported
  @retval
unknown's avatar
unknown committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    FALSE  otherwise
*/
 
bool Item_sum::init_sum_func_check(THD *thd)
{
  if (!thd->lex->allow_sum_func)
  {
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
               MYF(0));
    return TRUE;
  }
  /* Set a reference to the nesting set function if there is  any */
  in_sum_func= thd->lex->in_sum_func;
  /* Save a pointer to object to be used in items for nested set functions */
  thd->lex->in_sum_func= this;
  nest_level= thd->lex->current_select->nest_level;
  ref_by= 0;
  aggr_level= -1;
68
  aggr_sel= NULL;
unknown's avatar
unknown committed
69 70
  max_arg_level= -1;
  max_sum_func_level= -1;
71
  outer_fields.empty();
unknown's avatar
unknown committed
72 73 74
  return FALSE;
}

unknown's avatar
unknown committed
75 76
/**
  Check constraints imposed on a usage of a set function.
unknown's avatar
unknown committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

    The method verifies whether context conditions imposed on a usage
    of any set function are met for this occurrence.
    It checks whether the set function occurs in the position where it
    can be aggregated and, when it happens to occur in argument of another
    set function, the method checks that these two functions are aggregated in
    different subqueries.
    If the context conditions are not met the method reports an error.
    If the set function is aggregated in some outer subquery the method
    adds it to the chain of items for such set functions that is attached
    to the the st_select_lex structure for this subquery.

    A number of designated members of the object are used to check the
    conditions. They are specified in the comment before the Item_sum
    class declaration.
    Additionally a bitmap variable called allow_sum_func is employed.
    It is included into the thd->lex structure.
    The bitmap contains 1 at n-th position if the set function happens
    to occur under a construct of the n-th level subquery where usage
    of set functions are allowed (i.e either in the SELECT list or
    in the HAVING clause of the corresponding subquery)
    Consider the query:
unknown's avatar
unknown committed
99 100 101 102 103
    @code
       SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
         HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
                t1.a > (SELECT MIN(t2.d) FROM t2);
    @endcode
unknown's avatar
unknown committed
104
    allow_sum_func will contain: 
unknown's avatar
unknown committed
105 106 107 108 109 110 111 112 113 114 115 116
    - for SUM(t1.b) - 1 at the first position 
    - for AVG(t1.b) - 1 at the first position, 0 at the second position
    - for MIN(t2.d) - 1 at the first position, 1 at the second position.

  @param thd  reference to the thread context info
  @param ref  location of the pointer to this item in the embedding expression

  @note
    This function is to be called for any item created for a set function
    object when the traversal of trees built for expressions used in the query
    is performed at the phase of context analysis. This function is to
    be invoked at the ascent of this traversal.
unknown's avatar
unknown committed
117

unknown's avatar
unknown committed
118 119 120
  @retval
    TRUE   if an error is reported
  @retval
unknown's avatar
unknown committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
    FALSE  otherwise
*/
 
bool Item_sum::check_sum_func(THD *thd, Item **ref)
{
  bool invalid= FALSE;
  nesting_map allow_sum_func= thd->lex->allow_sum_func;
  /*  
    The value of max_arg_level is updated if an argument of the set function
    contains a column reference resolved  against a subquery whose level is
    greater than the current value of max_arg_level.
    max_arg_level cannot be greater than nest level.
    nest level is always >= 0  
  */ 
  if (nest_level == max_arg_level)
  {
    /*
      The function must be aggregated in the current subquery, 
      If it is there under a construct where it is not allowed 
      we report an error. 
    */ 
    invalid= !(allow_sum_func & (1 << max_arg_level));
  }
  else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
  {
    /*
      The set function can be aggregated only in outer subqueries.
      Try to find a subquery where it can be aggregated;
      If we fail to find such a subquery report an error.
    */
    if (register_sum_func(thd, ref))
      return TRUE;
    invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
unknown's avatar
unknown committed
154 155
    if (!invalid && thd->variables.sql_mode & MODE_ANSI)
      invalid= aggr_level < 0 && max_arg_level < nest_level;
unknown's avatar
unknown committed
156 157
  }
  if (!invalid && aggr_level < 0)
158
  {
unknown's avatar
unknown committed
159
    aggr_level= nest_level;
160 161
    aggr_sel= thd->lex->current_select;
  }
unknown's avatar
unknown committed
162 163 164 165 166 167 168 169 170
  /*
    By this moment we either found a subquery where the set function is
    to be aggregated  and assigned a value that is  >= 0 to aggr_level,
    or set the value of 'invalid' to TRUE to report later an error. 
  */
  /* 
    Additionally we have to check whether possible nested set functions
    are acceptable here: they are not, if the level of aggregation of
    some of them is less than aggr_level.
unknown's avatar
unknown committed
171 172 173
  */
  if (!invalid) 
    invalid= aggr_level <= max_sum_func_level;
unknown's avatar
unknown committed
174 175 176 177 178 179
  if (invalid)  
  {
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
               MYF(0));
    return TRUE;
  }
180

unknown's avatar
unknown committed
181
  if (in_sum_func)
unknown's avatar
unknown committed
182 183 184 185
  {
    /*
      If the set function is nested adjust the value of
      max_sum_func_level for the nesting set function.
unknown's avatar
unknown committed
186 187 188 189 190 191 192 193 194 195
      We take into account only enclosed set functions that are to be 
      aggregated on the same level or above of the nest level of 
      the enclosing set function.
      But we must always pass up the max_sum_func_level because it is
      the maximum nested level of all directly and indirectly enclosed
      set functions. We must do that even for set functions that are
      aggregated inside of their enclosing set function's nest level
      because the enclosing function may contain another enclosing
      function that is to be aggregated outside or on the same level
      as its parent's nest level.
unknown's avatar
unknown committed
196
    */
unknown's avatar
unknown committed
197 198 199
    if (in_sum_func->nest_level >= aggr_level)
      set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
    set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level);
unknown's avatar
unknown committed
200
  }
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262

  /*
    Check that non-aggregated fields and sum functions aren't mixed in the
    same select in the ONLY_FULL_GROUP_BY mode.
  */
  if (outer_fields.elements)
  {
    Item_field *field;
    /*
      Here we compare the nesting level of the select to which an outer field
      belongs to with the aggregation level of the sum function. All fields in
      the outer_fields list are checked.

      If the nesting level is equal to the aggregation level then the field is
        aggregated by this sum function.
      If the nesting level is less than the aggregation level then the field
        belongs to an outer select. In this case if there is an embedding sum
        function add current field to functions outer_fields list. If there is
        no embedding function then the current field treated as non aggregated
        and the select it belongs to is marked accordingly.
      If the nesting level is greater than the aggregation level then it means
        that this field was added by an inner sum function.
        Consider an example:

          select avg ( <-- we are here, checking outer.f1
            select (
              select sum(outer.f1 + inner.f1) from inner
            ) from outer)
          from most_outer;

        In this case we check that no aggregate functions are used in the
        select the field belongs to. If there are some then an error is
        raised.
    */
    List_iterator<Item_field> of(outer_fields);
    while ((field= of++))
    {
      SELECT_LEX *sel= field->cached_table->select_lex;
      if (sel->nest_level < aggr_level)
      {
        if (in_sum_func)
        {
          /*
            Let upper function decide whether this field is a non
            aggregated one.
          */
          in_sum_func->outer_fields.push_back(field);
        }
        else
          sel->full_group_by_flag|= NON_AGG_FIELD_USED;
      }
      if (sel->nest_level > aggr_level &&
          (sel->full_group_by_flag & SUM_FUNC_USED) &&
          !sel->group_list.elements)
      {
        my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
                   ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
        return TRUE;
      }
    }
  }
  aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
unknown's avatar
unknown committed
263
  update_used_tables();
unknown's avatar
unknown committed
264 265 266 267
  thd->lex->in_sum_func= in_sum_func;
  return FALSE;
}

unknown's avatar
unknown committed
268 269
/**
  Attach a set function to the subquery where it must be aggregated.
unknown's avatar
unknown committed
270 271 272 273 274 275 276 277

    The function looks for an outer subquery where the set function must be
    aggregated. If it finds such a subquery then aggr_level is set to
    the nest level of this subquery and the item for the set function
    is added to the list of set functions used in nested subqueries
    inner_sum_func_list defined for each subquery. When the item is placed 
    there the field 'ref_by' is set to ref.

unknown's avatar
unknown committed
278
  @note
unknown's avatar
unknown committed
279 280 281 282 283
    Now we 'register' only set functions that are aggregated in outer
    subqueries. Actually it makes sense to link all set function for
    a subquery in one chain. It would simplify the process of 'splitting'
    for set functions.

unknown's avatar
unknown committed
284 285 286 287
  @param thd  reference to the thread context info
  @param ref  location of the pointer to this item in the embedding expression

  @retval
unknown's avatar
unknown committed
288
    FALSE  if the executes without failures (currently always)
unknown's avatar
unknown committed
289
  @retval
unknown's avatar
unknown committed
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
    TRUE   otherwise
*/  

bool Item_sum::register_sum_func(THD *thd, Item **ref)
{
  SELECT_LEX *sl;
  nesting_map allow_sum_func= thd->lex->allow_sum_func;
  for (sl= thd->lex->current_select->master_unit()->outer_select() ;
       sl && sl->nest_level > max_arg_level;
       sl= sl->master_unit()->outer_select() )
  {
    if (aggr_level < 0 && (allow_sum_func & (1 << sl->nest_level)))
    {
      /* Found the most nested subquery where the function can be aggregated */
      aggr_level= sl->nest_level;
305
      aggr_sel= sl;
unknown's avatar
unknown committed
306 307 308 309 310 311 312 313 314 315
    }
  }
  if (sl && (allow_sum_func & (1 << sl->nest_level)))
  {
    /* 
      We reached the subquery of level max_arg_level and checked
      that the function can be aggregated here. 
      The set function will be aggregated in this subquery.
    */   
    aggr_level= sl->nest_level;
316 317
    aggr_sel= sl;

unknown's avatar
unknown committed
318 319 320 321
  }
  if (aggr_level >= 0)
  {
    ref_by= ref;
322 323
    /* Add the object to the list of registered objects assigned to aggr_sel */
    if (!aggr_sel->inner_sum_func_list)
unknown's avatar
unknown committed
324 325 326
      next= this;
    else
    {
327 328
      next= aggr_sel->inner_sum_func_list->next;
      aggr_sel->inner_sum_func_list->next= this;
unknown's avatar
unknown committed
329
    }
330 331
    aggr_sel->inner_sum_func_list= this;
    aggr_sel->with_sum_func= 1;
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348

    /* 
      Mark Item_subselect(s) as containing aggregate function all the way up
      to aggregate function's calculation context.
      Note that we must not mark the Item of calculation context itself
      because with_sum_func on the calculation context st_select_lex is
      already set above.

      with_sum_func being set for an Item means that this Item refers 
      (somewhere in it, e.g. one of its arguments if it's a function) directly
      or through intermediate items to an aggregate function that is calculated
      in a context "outside" of the Item (e.g. in the current or outer select).

      with_sum_func being set for an st_select_lex means that this st_select_lex
      has aggregate functions directly referenced (i.e. not through a sub-select).
    */
    for (sl= thd->lex->current_select; 
349
         sl && sl != aggr_sel && sl->master_unit()->item;
350 351
         sl= sl->master_unit()->outer_select() )
      sl->master_unit()->item->with_sum_func= 1;
unknown's avatar
unknown committed
352
  }
353
  thd->lex->current_select->mark_as_dependent(aggr_sel);
unknown's avatar
unknown committed
354 355 356 357
  return FALSE;
}


unknown's avatar
unknown committed
358 359
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), 
  forced_const(FALSE)
unknown's avatar
unknown committed
360 361 362 363
{
  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
  {
    uint i=0;
unknown's avatar
unknown committed
364
    List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
365 366 367 368 369 370 371
    Item *item;

    while ((item=li++))
    {
      args[i++]= item;
    }
  }
372 373 374 375
  if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count)))
  {
    args= NULL;
  }
376
  mark_as_sum_func();
unknown's avatar
unknown committed
377 378 379
  list.empty();					// Fields are used
}

unknown's avatar
unknown committed
380

unknown's avatar
unknown committed
381 382
/**
  Constructor used in processing select with temporary tebles.
unknown's avatar
unknown committed
383 384
*/

385
Item_sum::Item_sum(THD *thd, Item_sum *item):
386
  Item_result_field(thd, item),
387
  aggr_sel(item->aggr_sel),
unknown's avatar
unknown committed
388
  nest_level(item->nest_level), aggr_level(item->aggr_level),
389 390 391
  quick_group(item->quick_group),
  arg_count(item->arg_count), orig_args(NULL),
  used_tables_cache(item->used_tables_cache),
392
  forced_const(item->forced_const) 
393 394
{
  if (arg_count <= 2)
395
  {
396
    args=tmp_args;
397 398
    orig_args=tmp_orig_args;
  }
399
  else
400
  {
unknown's avatar
unknown committed
401
    if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
402
      return;
403 404 405
    if (!(orig_args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
      return;
  }
unknown's avatar
unknown committed
406
  memcpy(args, item->args, sizeof(Item*)*arg_count);
407
  memcpy(orig_args, item->orig_args, sizeof(Item*)*arg_count);
unknown's avatar
unknown committed
408 409 410
}


411
void Item_sum::mark_as_sum_func()
412
{
413 414 415
  SELECT_LEX *cur_select= current_thd->lex->current_select;
  cur_select->n_sum_items++;
  cur_select->with_sum_func= 1;
unknown's avatar
unknown committed
416
  with_sum_func= 1;
417
}
unknown's avatar
unknown committed
418

419

unknown's avatar
unknown committed
420 421 422 423
void Item_sum::make_field(Send_field *tmp_field)
{
  if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
  {
424
    ((Item_field*) args[0])->field->make_field(tmp_field);
425 426 427 428 429 430 431
    /* For expressions only col_name should be non-empty string. */
    char *empty_string= (char*)"";
    tmp_field->db_name= empty_string;
    tmp_field->org_table_name= empty_string;
    tmp_field->table_name= empty_string;
    tmp_field->org_col_name= empty_string;
    tmp_field->col_name= name;
432 433
    if (maybe_null)
      tmp_field->flags&= ~NOT_NULL_FLAG;
unknown's avatar
unknown committed
434
  }
435 436
  else
    init_make_field(tmp_field, field_type());
unknown's avatar
unknown committed
437 438
}

439

440
void Item_sum::print(String *str, enum_query_type query_type)
unknown's avatar
unknown committed
441
{
442 443
  /* orig_args is not filled with valid values until fix_fields() */
  Item **pargs= fixed ? orig_args : args;
unknown's avatar
unknown committed
444 445 446 447 448
  str->append(func_name());
  for (uint i=0 ; i < arg_count ; i++)
  {
    if (i)
      str->append(',');
449
    pargs[i]->print(str, query_type);
unknown's avatar
unknown committed
450 451 452 453 454 455 456 457 458 459 460 461
  }
  str->append(')');
}

void Item_sum::fix_num_length_and_dec()
{
  decimals=0;
  for (uint i=0 ; i < arg_count ; i++)
    set_if_bigger(decimals,args[i]->decimals);
  max_length=float_length(decimals);
}

462
Item *Item_sum::get_tmp_table_item(THD *thd)
463
{
464
  Item_sum* sum_item= (Item_sum *) copy_or_same(thd);
465 466
  if (sum_item && sum_item->result_field)	   // If not a const sum func
  {
467
    Field *result_field_tmp= sum_item->result_field;
468 469 470 471 472 473
    for (uint i=0 ; i < sum_item->arg_count ; i++)
    {
      Item *arg= sum_item->args[i];
      if (!arg->const_item())
      {
	if (arg->type() == Item::FIELD_ITEM)
474
	  ((Item_field*) arg)->field= result_field_tmp++;
475
	else
476
	  sum_item->args[i]= new Item_field(result_field_tmp++);
477 478 479 480 481
      }
    }
  }
  return sum_item;
}
unknown's avatar
unknown committed
482

unknown's avatar
unknown committed
483

484
bool Item_sum::walk (Item_processor processor, bool walk_subquery,
485
                     uchar *argument)
486 487 488 489 490 491
{
  if (arg_count)
  {
    Item **arg,**arg_end;
    for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
    {
492
      if ((*arg)->walk(processor, walk_subquery, argument))
493 494 495 496 497 498
	return 1;
    }
  }
  return (this->*processor)(argument);
}

499

unknown's avatar
unknown committed
500 501 502
Field *Item_sum::create_tmp_field(bool group, TABLE *table,
                                  uint convert_blob_length)
{
unknown's avatar
unknown committed
503
  Field *field;
unknown's avatar
unknown committed
504 505
  switch (result_type()) {
  case REAL_RESULT:
506
    field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
unknown's avatar
unknown committed
507
    break;
unknown's avatar
unknown committed
508
  case INT_RESULT:
unknown's avatar
unknown committed
509 510
    field= new Field_longlong(max_length, maybe_null, name, unsigned_flag);
    break;
unknown's avatar
unknown committed
511
  case STRING_RESULT:
512
    if (max_length/collation.collation->mbmaxlen <= 255 ||
513
        convert_blob_length > Field_varstring::MAX_SIZE ||
514
        !convert_blob_length)
unknown's avatar
unknown committed
515 516 517 518
      return make_string_field(table);
    field= new Field_varstring(convert_blob_length, maybe_null,
                               name, table->s, collation.collation);
    break;
unknown's avatar
unknown committed
519
  case DECIMAL_RESULT:
unknown's avatar
unknown committed
520
    field= new Field_new_decimal(max_length, maybe_null, name,
unknown's avatar
unknown committed
521
                                 decimals, unsigned_flag);
unknown's avatar
unknown committed
522
    break;
unknown's avatar
unknown committed
523 524 525 526 527 528
  case ROW_RESULT:
  default:
    // This case should never be choosen
    DBUG_ASSERT(0);
    return 0;
  }
unknown's avatar
unknown committed
529 530 531
  if (field)
    field->init(table);
  return field;
unknown's avatar
unknown committed
532 533 534
}


unknown's avatar
unknown committed
535 536 537 538 539 540 541 542 543 544 545 546 547 548
void Item_sum::update_used_tables ()
{
  if (!forced_const)
  {
    used_tables_cache= 0;
    for (uint i=0 ; i < arg_count ; i++)
    {
      args[i]->update_used_tables();
      used_tables_cache|= args[i]->used_tables();
    }
  }
}


549 550 551 552 553 554 555
Item *Item_sum::set_arg(int i, THD *thd, Item *new_val) 
{
  thd->change_item_tree(args + i, new_val);
  return new_val;
}


unknown's avatar
unknown committed
556 557 558
String *
Item_sum_num::val_str(String *str)
{
559
  return val_string_from_real(str);
unknown's avatar
unknown committed
560 561 562
}


unknown's avatar
unknown committed
563 564
my_decimal *Item_sum_num::val_decimal(my_decimal *decimal_value)
{
565
  return val_decimal_from_real(decimal_value);
unknown's avatar
unknown committed
566 567 568
}


unknown's avatar
unknown committed
569 570 571
String *
Item_sum_int::val_str(String *str)
{
572 573 574 575 576 577 578
  return val_string_from_int(str);
}


my_decimal *Item_sum_int::val_decimal(my_decimal *decimal_value)
{
  return val_decimal_from_int(decimal_value);
unknown's avatar
unknown committed
579 580 581 582
}


bool
583
Item_sum_num::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
584
{
585
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
586

unknown's avatar
unknown committed
587
  if (init_sum_func_check(thd))
unknown's avatar
unknown committed
588
    return TRUE;
unknown's avatar
unknown committed
589

unknown's avatar
unknown committed
590 591 592 593
  decimals=0;
  maybe_null=0;
  for (uint i=0 ; i < arg_count ; i++)
  {
594
    if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
unknown's avatar
unknown committed
595
      return TRUE;
unknown's avatar
unknown committed
596
    set_if_bigger(decimals, args[i]->decimals);
unknown's avatar
unknown committed
597 598 599 600 601 602
    maybe_null |= args[i]->maybe_null;
  }
  result_field=0;
  max_length=float_length(decimals);
  null_value=1;
  fix_length_and_dec();
unknown's avatar
unknown committed
603 604 605 606

  if (check_sum_func(thd, ref))
    return TRUE;

607
  memcpy (orig_args, args, sizeof (Item *) * arg_count);
608
  fixed= 1;
unknown's avatar
unknown committed
609
  return FALSE;
unknown's avatar
unknown committed
610 611 612
}


unknown's avatar
unknown committed
613 614 615
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
  :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
  hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
unknown's avatar
unknown committed
616
  was_values(item->was_values)
unknown's avatar
unknown committed
617
{
618 619
  /* copy results from old value */
  switch (hybrid_type) {
unknown's avatar
unknown committed
620 621 622 623 624 625 626 627 628
  case INT_RESULT:
    sum_int= item->sum_int;
    break;
  case DECIMAL_RESULT:
    my_decimal2decimal(&item->sum_dec, &sum_dec);
    break;
  case REAL_RESULT:
    sum= item->sum;
    break;
unknown's avatar
unknown committed
629 630 631 632 633 634
  case STRING_RESULT:
    /*
      This can happen with ROLLUP. Note that the value is already
      copied at function call.
    */
    break;
unknown's avatar
unknown committed
635 636 637 638 639 640 641
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
  }
  collation.set(item->collation);
}

unknown's avatar
unknown committed
642
bool
643
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
644
{
645
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
646

647
  Item *item= args[0];
unknown's avatar
unknown committed
648 649

  if (init_sum_func_check(thd))
unknown's avatar
unknown committed
650
    return TRUE;
651 652

  // 'item' can be changed during fix_fields
653
  if ((!item->fixed && item->fix_fields(thd, args)) ||
654
      (item= args[0])->check_cols(1))
unknown's avatar
unknown committed
655
    return TRUE;
unknown's avatar
unknown committed
656
  decimals=item->decimals;
657

658
  switch (hybrid_type= item->result_type()) {
unknown's avatar
unknown committed
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677
  case INT_RESULT:
    max_length= 20;
    sum_int= 0;
    break;
  case DECIMAL_RESULT:
    max_length= item->max_length;
    my_decimal_set_zero(&sum_dec);
    break;
  case REAL_RESULT:
    max_length= float_length(decimals);
    sum= 0.0;
    break;
  case STRING_RESULT:
    max_length= item->max_length;
    break;
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
  };
678 679
  /* MIN/MAX can return NULL for empty set indepedent of the used column */
  maybe_null= 1;
680
  unsigned_flag=item->unsigned_flag;
681
  collation.set(item->collation);
unknown's avatar
unknown committed
682 683 684
  result_field=0;
  null_value=1;
  fix_length_and_dec();
685
  item= item->real_item();
686 687 688 689
  if (item->type() == Item::FIELD_ITEM)
    hybrid_field_type= ((Item_field*) item)->field->type();
  else
    hybrid_field_type= Item::field_type();
unknown's avatar
unknown committed
690 691 692 693

  if (check_sum_func(thd, ref))
    return TRUE;

694
  orig_args[0]= args[0];
695
  fixed= 1;
unknown's avatar
unknown committed
696
  return FALSE;
unknown's avatar
unknown committed
697 698
}

699 700 701
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
					 uint convert_blob_length)
{
unknown's avatar
unknown committed
702
  Field *field;
703 704
  if (args[0]->type() == Item::FIELD_ITEM)
  {
unknown's avatar
unknown committed
705
    field= ((Item_field*) args[0])->field;
706
    
unknown's avatar
unknown committed
707 708
    if ((field= create_tmp_field_from_field(current_thd, field, name, table,
					    NULL, convert_blob_length)))
709 710 711
      field->flags&= ~NOT_NULL_FLAG;
    return field;
  }
712 713 714 715 716 717 718
  /*
    DATE/TIME fields have STRING_RESULT result types.
    In order to preserve field type, it's needed to handle DATE/TIME
    fields creations separately.
  */
  switch (args[0]->field_type()) {
  case MYSQL_TYPE_DATE:
719
    field= new Field_newdate(maybe_null, name, collation.collation);
unknown's avatar
unknown committed
720
    break;
721
  case MYSQL_TYPE_TIME:
unknown's avatar
unknown committed
722 723
    field= new Field_time(maybe_null, name, collation.collation);
    break;
724 725
  case MYSQL_TYPE_TIMESTAMP:
  case MYSQL_TYPE_DATETIME:
unknown's avatar
unknown committed
726
    field= new Field_datetime(maybe_null, name, collation.collation);
727
    break;
unknown's avatar
unknown committed
728 729
  default:
    return Item_sum::create_tmp_field(group, table, convert_blob_length);
730
  }
unknown's avatar
unknown committed
731 732 733
  if (field)
    field->init(table);
  return field;
734 735
}

unknown's avatar
unknown committed
736 737 738 739 740

/***********************************************************************
** reset and add of sum_func
***********************************************************************/

unknown's avatar
unknown committed
741 742 743 744
/**
  @todo
  check if the following assignments are really needed
*/
unknown's avatar
unknown committed
745 746 747 748
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item) 
  :Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
   curr_dec_buff(item->curr_dec_buff)
{
749
  /* TODO: check if the following assignments are really needed */
unknown's avatar
unknown committed
750 751 752 753 754 755 756 757 758
  if (hybrid_type == DECIMAL_RESULT)
  {
    my_decimal2decimal(item->dec_buffs, dec_buffs);
    my_decimal2decimal(item->dec_buffs + 1, dec_buffs + 1);
  }
  else
    sum= item->sum;
}

759
Item *Item_sum_sum::copy_or_same(THD* thd)
unknown's avatar
unknown committed
760
{
unknown's avatar
unknown committed
761
  return new (thd->mem_root) Item_sum_sum(thd, this);
unknown's avatar
unknown committed
762 763
}

764

765
void Item_sum_sum::clear()
766
{
unknown's avatar
unknown committed
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
  DBUG_ENTER("Item_sum_sum::clear");
  null_value=1;
  if (hybrid_type == DECIMAL_RESULT)
  {
    curr_dec_buff= 0;
    my_decimal_set_zero(dec_buffs);
  }
  else
    sum= 0.0;
  DBUG_VOID_RETURN;
}


void Item_sum_sum::fix_length_and_dec()
{
  DBUG_ENTER("Item_sum_sum::fix_length_and_dec");
  maybe_null=null_value=1;
  decimals= args[0]->decimals;
785
  switch (args[0]->result_type()) {
unknown's avatar
unknown committed
786 787 788 789 790 791 792
  case REAL_RESULT:
  case STRING_RESULT:
    hybrid_type= REAL_RESULT;
    sum= 0.0;
    break;
  case INT_RESULT:
  case DECIMAL_RESULT:
unknown's avatar
unknown committed
793
  {
unknown's avatar
unknown committed
794
    /* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
unknown's avatar
unknown committed
795 796 797
    int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
    max_length= my_decimal_precision_to_length(precision, decimals,
                                               unsigned_flag);
unknown's avatar
unknown committed
798 799 800 801
    curr_dec_buff= 0;
    hybrid_type= DECIMAL_RESULT;
    my_decimal_set_zero(dec_buffs);
    break;
unknown's avatar
unknown committed
802
  }
unknown's avatar
unknown committed
803 804 805 806 807 808 809 810 811 812 813 814
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
  }
  DBUG_PRINT("info", ("Type: %s (%d, %d)",
                      (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
                       hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
                       hybrid_type == INT_RESULT ? "INT_RESULT" :
                       "--ILLEGAL!!!--"),
                      max_length,
                      (int)decimals));
  DBUG_VOID_RETURN;
815 816 817
}


unknown's avatar
unknown committed
818 819
bool Item_sum_sum::add()
{
unknown's avatar
unknown committed
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
  DBUG_ENTER("Item_sum_sum::add");
  if (hybrid_type == DECIMAL_RESULT)
  {
    my_decimal value, *val= args[0]->val_decimal(&value);
    if (!args[0]->null_value)
    {
      my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1),
                     val, dec_buffs + curr_dec_buff);
      curr_dec_buff^= 1;
      null_value= 0;
    }
  }
  else
  {
    sum+= args[0]->val_real();
    if (!args[0]->null_value)
      null_value= 0;
  }
  DBUG_RETURN(0);
}


longlong Item_sum_sum::val_int()
{
  DBUG_ASSERT(fixed == 1);
  if (hybrid_type == DECIMAL_RESULT)
  {
    longlong result;
    my_decimal2int(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, unsigned_flag,
                   &result);
    return result;
  }
852
  return (longlong) rint(val_real());
unknown's avatar
unknown committed
853 854
}

855

856
double Item_sum_sum::val_real()
unknown's avatar
unknown committed
857
{
858
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
859 860
  if (hybrid_type == DECIMAL_RESULT)
    my_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum);
unknown's avatar
unknown committed
861 862 863 864
  return sum;
}


865
String *Item_sum_sum::val_str(String *str)
unknown's avatar
unknown committed
866 867
{
  if (hybrid_type == DECIMAL_RESULT)
868 869
    return val_string_from_decimal(str);
  return val_string_from_real(str);
unknown's avatar
unknown committed
870 871 872 873 874
}


my_decimal *Item_sum_sum::val_decimal(my_decimal *val)
{
875 876 877
  if (hybrid_type == DECIMAL_RESULT)
    return (dec_buffs + curr_dec_buff);
  return val_decimal_from_real(val);
unknown's avatar
unknown committed
878 879
}

880
/***************************************************************************/
881

882 883 884
C_MODE_START

/* Declarations for auxilary C-callbacks */
885

886 887 888 889 890 891 892 893 894
static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
{
    return memcmp(key1, key2, *(uint *) arg);
}


static int item_sum_distinct_walk(void *element, element_count num_of_dups,
                                  void *item)
{
895
  return ((Item_sum_distinct*) (item))->unique_walk_function(element);
896 897 898 899 900 901 902 903
}

C_MODE_END

/* Item_sum_distinct */

Item_sum_distinct::Item_sum_distinct(Item *item_arg)
  :Item_sum_num(item_arg), tree(0)
904 905 906 907 908 909 910 911 912 913 914
{
  /*
    quick_group is an optimizer hint, which means that GROUP BY can be
    handled with help of index on grouped columns.
    By setting quick_group to zero we force creation of temporary table
    to perform GROUP BY.
  */
  quick_group= 0;
}


915 916 917
Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
  :Item_sum_num(thd, original), val(original->val), tree(0),
  table_field_type(original->table_field_type)
918 919 920 921 922
{
  quick_group= 0;
}


unknown's avatar
unknown committed
923
/**
924 925 926 927 928 929 930 931
  Behaves like an Integer except to fix_length_and_dec().
  Additionally div() converts val with this traits to a val with true
  decimal traits along with conversion of integer value to decimal value.
  This is to speedup SUM/AVG(DISTINCT) evaluation for 8-32 bit integer
  values.
*/
struct Hybrid_type_traits_fast_decimal: public
       Hybrid_type_traits_integer
unknown's avatar
unknown committed
932
{
933 934 935 936 937
  virtual Item_result type() const { return DECIMAL_RESULT; }
  virtual void fix_length_and_dec(Item *item, Item *arg) const
  { Hybrid_type_traits_decimal::instance()->fix_length_and_dec(item, arg); }

  virtual void div(Hybrid_type *val, ulonglong u) const
unknown's avatar
unknown committed
938
  {
939 940 941 942
    int2my_decimal(E_DEC_FATAL_ERROR, val->integer, 0, val->dec_buf);
    val->used_dec_buf_no= 0;
    val->traits= Hybrid_type_traits_decimal::instance();
    val->traits->div(val, u);
unknown's avatar
unknown committed
943
  }
unknown's avatar
unknown committed
944
  static const Hybrid_type_traits_fast_decimal *instance();
945
  Hybrid_type_traits_fast_decimal() {};
946
};
unknown's avatar
unknown committed
947

unknown's avatar
unknown committed
948 949 950 951 952 953 954
static const Hybrid_type_traits_fast_decimal fast_decimal_traits_instance;

const Hybrid_type_traits_fast_decimal
  *Hybrid_type_traits_fast_decimal::instance()
{
  return &fast_decimal_traits_instance;
}
unknown's avatar
unknown committed
955

956
void Item_sum_distinct::fix_length_and_dec()
957
{
958
  DBUG_ASSERT(args[0]->fixed);
959

960
  table_field_type= args[0]->field_type();
961

962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
  /* Adjust tmp table type according to the chosen aggregation type */
  switch (args[0]->result_type()) {
  case STRING_RESULT:
  case REAL_RESULT:
    val.traits= Hybrid_type_traits::instance();
    if (table_field_type != MYSQL_TYPE_FLOAT)
      table_field_type= MYSQL_TYPE_DOUBLE;
    break;
  case INT_RESULT:
  /*
    Preserving int8, int16, int32 field types gives ~10% performance boost
    as the size of result tree becomes significantly smaller.
    Another speed up we gain by using longlong for intermediate
    calculations. The range of int64 is enough to hold sum 2^32 distinct
    integers each <= 2^32.
  */
  if (table_field_type == MYSQL_TYPE_INT24 ||
979 980
      (table_field_type >= MYSQL_TYPE_TINY &&
       table_field_type <= MYSQL_TYPE_LONG))
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996
  {
    val.traits= Hybrid_type_traits_fast_decimal::instance();
    break;
  }
  table_field_type= MYSQL_TYPE_LONGLONG;
  /* fallthrough */
  case DECIMAL_RESULT:
    val.traits= Hybrid_type_traits_decimal::instance();
    if (table_field_type != MYSQL_TYPE_LONGLONG)
      table_field_type= MYSQL_TYPE_NEWDECIMAL;
    break;
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
  }
  val.traits->fix_length_and_dec(this, args[0]);
997 998 999
}


unknown's avatar
unknown committed
1000 1001 1002 1003
/**
  @todo
  check that the case of CHAR(0) works OK
*/
1004
bool Item_sum_distinct::setup(THD *thd)
1005
{
unknown's avatar
unknown committed
1006 1007
  List<Create_field> field_list;
  Create_field field_def;                              /* field definition */
1008
  DBUG_ENTER("Item_sum_distinct::setup");
1009 1010
  /* It's legal to call setup() more than once when in a subquery */
  if (tree)
unknown's avatar
unknown committed
1011
    DBUG_RETURN(FALSE);
1012 1013

  /*
1014 1015 1016
    Virtual table and the tree are created anew on each re-execution of
    PS/SP. Hence all further allocations are performed in the runtime
    mem_root.
1017
  */
1018
  if (field_list.push_back(&field_def))
unknown's avatar
unknown committed
1019
    DBUG_RETURN(TRUE);
1020

1021
  null_value= maybe_null= 1;
1022 1023 1024 1025 1026 1027 1028 1029 1030
  quick_group= 0;

  DBUG_ASSERT(args[0]->fixed);

  field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
                               args[0]->decimals, args[0]->maybe_null,
                               args[0]->unsigned_flag);

  if (! (table= create_virtual_tmp_table(thd, field_list)))
unknown's avatar
unknown committed
1031
    DBUG_RETURN(TRUE);
1032 1033 1034

  /* XXX: check that the case of CHAR(0) works OK */
  tree_key_length= table->s->reclength - table->s->null_bytes;
1035 1036

  /*
1037 1038 1039 1040
    Unique handles all unique elements in a tree until they can't fit
    in.  Then the tree is dumped to the temporary file. We can use
    simple_raw_key_cmp because the table contains numbers only; decimals
    are converted to binary representation as well.
1041
  */
1042
  tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
1043 1044
                   thd->variables.max_heap_table_size);

1045
  is_evaluated= FALSE;
1046
  DBUG_RETURN(tree == 0);
1047 1048 1049
}


1050
bool Item_sum_distinct::add()
1051
{
1052
  args[0]->save_in_field(table->field[0], FALSE);
1053
  is_evaluated= FALSE;
1054
  if (!table->field[0]->is_null())
1055
  {
1056 1057 1058 1059 1060 1061 1062
    DBUG_ASSERT(tree);
    null_value= 0;
    /*
      '0' values are also stored in the tree. This doesn't matter
      for SUM(DISTINCT), but is important for AVG(DISTINCT)
    */
    return tree->unique_add(table->field[0]->ptr);
1063
  }
1064
  return 0;
unknown's avatar
unknown committed
1065 1066 1067
}


1068
bool Item_sum_distinct::unique_walk_function(void *element)
unknown's avatar
unknown committed
1069
{
1070 1071 1072 1073
  memcpy(table->field[0]->ptr, element, tree_key_length);
  ++count;
  val.traits->add(&val, table->field[0]);
  return 0;
unknown's avatar
unknown committed
1074 1075 1076
}


1077
void Item_sum_distinct::clear()
unknown's avatar
unknown committed
1078
{
1079 1080 1081 1082
  DBUG_ENTER("Item_sum_distinct::clear");
  DBUG_ASSERT(tree != 0);                        /* we always have a tree */
  null_value= 1;
  tree->reset();
1083
  is_evaluated= FALSE;
1084
  DBUG_VOID_RETURN;
1085 1086
}

1087 1088 1089 1090 1091 1092
void Item_sum_distinct::cleanup()
{
  Item_sum_num::cleanup();
  delete tree;
  tree= 0;
  table= 0;
1093
  is_evaluated= FALSE;
unknown's avatar
unknown committed
1094 1095
}

1096 1097 1098 1099
Item_sum_distinct::~Item_sum_distinct()
{
  delete tree;
  /* no need to free the table */
1100 1101
}

1102

1103
void Item_sum_distinct::calculate_val_and_count()
1104
{
1105
  if (!is_evaluated)
unknown's avatar
unknown committed
1106
  {
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
    count= 0;
    val.traits->set_zero(&val);
    /*
      We don't have a tree only if 'setup()' hasn't been called;
      this is the case of sql_select.cc:return_zero_rows.
     */
    if (tree)
    {
      table->field[0]->set_notnull();
      tree->walk(item_sum_distinct_walk, (void*) this);
    }
    is_evaluated= TRUE;
unknown's avatar
unknown committed
1119
  }
1120 1121
}

unknown's avatar
unknown committed
1122

1123
double Item_sum_distinct::val_real()
unknown's avatar
unknown committed
1124
{
1125 1126
  calculate_val_and_count();
  return val.traits->val_real(&val);
unknown's avatar
unknown committed
1127 1128 1129
}


1130
my_decimal *Item_sum_distinct::val_decimal(my_decimal *to)
unknown's avatar
unknown committed
1131
{
1132 1133 1134 1135
  calculate_val_and_count();
  if (null_value)
    return 0;
  return val.traits->val_decimal(&val, to);
unknown's avatar
unknown committed
1136 1137 1138
}


1139
longlong Item_sum_distinct::val_int()
unknown's avatar
unknown committed
1140
{
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
  calculate_val_and_count();
  return val.traits->val_int(&val, unsigned_flag);
}


String *Item_sum_distinct::val_str(String *str)
{
  calculate_val_and_count();
  if (null_value)
    return 0;
  return val.traits->val_str(&val, str, decimals);
unknown's avatar
unknown committed
1152 1153
}

1154 1155 1156 1157
/* end of Item_sum_distinct */

/* Item_sum_avg_distinct */

1158 1159 1160 1161
void
Item_sum_avg_distinct::fix_length_and_dec()
{
  Item_sum_distinct::fix_length_and_dec();
unknown's avatar
unknown committed
1162
  prec_increment= current_thd->variables.div_precincrement;
1163 1164 1165 1166
  /*
    AVG() will divide val by count. We need to reserve digits
    after decimal point as the result can be fractional.
  */
unknown's avatar
unknown committed
1167
  decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
1168 1169 1170
}


1171 1172 1173
void
Item_sum_avg_distinct::calculate_val_and_count()
{
1174 1175 1176 1177 1178 1179 1180
  if (!is_evaluated)
  {
    Item_sum_distinct::calculate_val_and_count();
    if (count)
      val.traits->div(&val, count);
    is_evaluated= TRUE;
  }
1181
}
unknown's avatar
unknown committed
1182

1183

1184
Item *Item_sum_count::copy_or_same(THD* thd)
unknown's avatar
unknown committed
1185
{
unknown's avatar
unknown committed
1186
  return new (thd->mem_root) Item_sum_count(thd, this);
unknown's avatar
unknown committed
1187 1188
}

1189

1190
void Item_sum_count::clear()
1191
{
1192
  count= 0;
1193 1194 1195
}


unknown's avatar
unknown committed
1196 1197
bool Item_sum_count::add()
{
1198
  if (!args[0]->maybe_null || !args[0]->is_null())
unknown's avatar
unknown committed
1199 1200 1201 1202 1203 1204
    count++;
  return 0;
}

longlong Item_sum_count::val_int()
{
1205
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1206 1207 1208
  return (longlong) count;
}

1209 1210 1211 1212

void Item_sum_count::cleanup()
{
  DBUG_ENTER("Item_sum_count::cleanup");
1213
  count= 0;
1214 1215 1216 1217 1218
  Item_sum_int::cleanup();
  DBUG_VOID_RETURN;
}


unknown's avatar
unknown committed
1219
/*
1220
  Avgerage
unknown's avatar
unknown committed
1221
*/
unknown's avatar
unknown committed
1222 1223 1224 1225
void Item_sum_avg::fix_length_and_dec()
{
  Item_sum_sum::fix_length_and_dec();
  maybe_null=null_value=1;
unknown's avatar
unknown committed
1226
  prec_increment= current_thd->variables.div_precincrement;
unknown's avatar
unknown committed
1227 1228
  if (hybrid_type == DECIMAL_RESULT)
  {
unknown's avatar
unknown committed
1229 1230 1231 1232 1233 1234
    int precision= args[0]->decimal_precision() + prec_increment;
    decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
    max_length= my_decimal_precision_to_length(precision, decimals,
                                               unsigned_flag);
    f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
    f_scale=  args[0]->decimals;
unknown's avatar
unknown committed
1235 1236
    dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
  }
1237
  else {
unknown's avatar
unknown committed
1238
    decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
1239 1240
    max_length= args[0]->max_length + prec_increment;
  }
unknown's avatar
unknown committed
1241 1242
}

unknown's avatar
unknown committed
1243

1244
Item *Item_sum_avg::copy_or_same(THD* thd)
unknown's avatar
unknown committed
1245
{
unknown's avatar
unknown committed
1246
  return new (thd->mem_root) Item_sum_avg(thd, this);
unknown's avatar
unknown committed
1247 1248
}

1249

unknown's avatar
unknown committed
1250 1251 1252
Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table,
                                      uint convert_blob_len)
{
unknown's avatar
unknown committed
1253
  Field *field;
1254
  if (group)
unknown's avatar
unknown committed
1255
  {
1256 1257
    /*
      We must store both value and counter in the temporary table in one field.
1258
      The easiest way is to do this is to store both value in a string
1259 1260
      and unpack on access.
    */
unknown's avatar
unknown committed
1261
    field= new Field_string(((hybrid_type == DECIMAL_RESULT) ?
1262
                             dec_bin_size : sizeof(double)) + sizeof(longlong),
unknown's avatar
unknown committed
1263
                            0, name, &my_charset_bin);
unknown's avatar
unknown committed
1264
  }
unknown's avatar
unknown committed
1265 1266
  else if (hybrid_type == DECIMAL_RESULT)
    field= new Field_new_decimal(max_length, maybe_null, name,
unknown's avatar
unknown committed
1267
                                 decimals, unsigned_flag);
unknown's avatar
unknown committed
1268
  else
1269
    field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
unknown's avatar
unknown committed
1270 1271 1272
  if (field)
    field->init(table);
  return field;
unknown's avatar
unknown committed
1273 1274 1275
}


1276
void Item_sum_avg::clear()
1277
{
unknown's avatar
unknown committed
1278 1279
  Item_sum_sum::clear();
  count=0;
1280 1281 1282
}


unknown's avatar
unknown committed
1283 1284
bool Item_sum_avg::add()
{
unknown's avatar
unknown committed
1285 1286
  if (Item_sum_sum::add())
    return TRUE;
unknown's avatar
unknown committed
1287 1288
  if (!args[0]->null_value)
    count++;
unknown's avatar
unknown committed
1289
  return FALSE;
unknown's avatar
unknown committed
1290 1291
}

1292
double Item_sum_avg::val_real()
unknown's avatar
unknown committed
1293
{
1294
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1295 1296 1297 1298 1299
  if (!count)
  {
    null_value=1;
    return 0.0;
  }
unknown's avatar
unknown committed
1300 1301 1302 1303 1304 1305
  return Item_sum_sum::val_real() / ulonglong2double(count);
}


my_decimal *Item_sum_avg::val_decimal(my_decimal *val)
{
1306
  my_decimal sum_buff, cnt;
1307
  const my_decimal *sum_dec;
unknown's avatar
unknown committed
1308 1309 1310 1311 1312 1313
  DBUG_ASSERT(fixed == 1);
  if (!count)
  {
    null_value=1;
    return NULL;
  }
1314 1315 1316 1317 1318 1319 1320 1321 1322

  /*
    For non-DECIMAL hybrid_type the division will be done in
    Item_sum_avg::val_real().
  */
  if (hybrid_type != DECIMAL_RESULT)
    return val_decimal_from_real(val);

  sum_dec= dec_buffs + curr_dec_buff;
unknown's avatar
unknown committed
1323
  int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &cnt);
unknown's avatar
unknown committed
1324
  my_decimal_div(E_DEC_FATAL_ERROR, val, sum_dec, &cnt, prec_increment);
unknown's avatar
unknown committed
1325 1326 1327 1328 1329 1330 1331
  return val;
}


String *Item_sum_avg::val_str(String *str)
{
  if (hybrid_type == DECIMAL_RESULT)
1332 1333
    return val_string_from_decimal(str);
  return val_string_from_real(str);
unknown's avatar
unknown committed
1334 1335 1336 1337
}


/*
1338
  Standard deviation
unknown's avatar
unknown committed
1339 1340
*/

1341
double Item_sum_std::val_real()
unknown's avatar
unknown committed
1342
{
1343
  DBUG_ASSERT(fixed == 1);
1344 1345 1346
  double nr= Item_sum_variance::val_real();
  DBUG_ASSERT(nr >= 0.0);
  return sqrt(nr);
unknown's avatar
unknown committed
1347 1348
}

1349 1350
Item *Item_sum_std::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1351
  return new (thd->mem_root) Item_sum_std(thd, this);
1352 1353 1354
}


unknown's avatar
unknown committed
1355
/*
1356
  Variance
unknown's avatar
unknown committed
1357 1358
*/

unknown's avatar
unknown committed
1359

1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
/**
  Variance implementation for floating-point implementations, without
  catastrophic cancellation, from Knuth's _TAoCP_, 3rd ed, volume 2, pg232.
  This alters the value at m, s, and increments count.
*/

/*
  These two functions are used by the Item_sum_variance and the
  Item_variance_field classes, which are unrelated, and each need to calculate
  variance.  The difference between the two classes is that the first is used
  for a mundane SELECT, while the latter is used in a GROUPing SELECT.
*/
static void variance_fp_recurrence_next(double *m, double *s, ulonglong *count, double nr)
unknown's avatar
unknown committed
1373
{
1374 1375 1376
  *count += 1;

  if (*count == 1) 
unknown's avatar
unknown committed
1377
  {
1378 1379
    *m= nr;
    *s= 0;
unknown's avatar
unknown committed
1380 1381 1382
  }
  else
  {
1383 1384 1385
    double m_kminusone= *m;
    *m= m_kminusone + (nr - m_kminusone) / (double) *count;
    *s= *s + (nr - m_kminusone) * (nr - *m);
unknown's avatar
unknown committed
1386 1387 1388 1389
  }
}


1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
static double variance_fp_recurrence_result(double s, ulonglong count, bool is_sample_variance)
{
  if (count == 1)
    return 0.0;

  if (is_sample_variance)
    return s / (count - 1);

  /* else, is a population variance */
  return s / count;
}


Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item):
  Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
    count(item->count), sample(item->sample),
    prec_increment(item->prec_increment)
{
  recurrence_m= item->recurrence_m;
  recurrence_s= item->recurrence_s;
}


unknown's avatar
unknown committed
1413 1414
void Item_sum_variance::fix_length_and_dec()
{
1415 1416
  DBUG_ENTER("Item_sum_variance::fix_length_and_dec");
  maybe_null= null_value= 1;
unknown's avatar
unknown committed
1417
  prec_increment= current_thd->variables.div_precincrement;
1418 1419 1420 1421 1422 1423 1424 1425 1426

  /*
    According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
    aggregate function; paragraph 7h of Syntax Rules), "the declared 
    type of the result is an implementation-defined aproximate numeric
    type.
  */
  hybrid_type= REAL_RESULT;

1427
  switch (args[0]->result_type()) {
unknown's avatar
unknown committed
1428 1429
  case REAL_RESULT:
  case STRING_RESULT:
unknown's avatar
unknown committed
1430
    decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
unknown's avatar
unknown committed
1431 1432 1433
    break;
  case INT_RESULT:
  case DECIMAL_RESULT:
unknown's avatar
unknown committed
1434 1435 1436 1437 1438
  {
    int precision= args[0]->decimal_precision()*2 + prec_increment;
    decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
    max_length= my_decimal_precision_to_length(precision, decimals,
                                               unsigned_flag);
1439

unknown's avatar
unknown committed
1440
    break;
unknown's avatar
unknown committed
1441
  }
unknown's avatar
unknown committed
1442 1443 1444 1445
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
  }
1446
  DBUG_PRINT("info", ("Type: REAL_RESULT (%d, %d)", max_length, (int)decimals));
unknown's avatar
unknown committed
1447 1448 1449 1450
  DBUG_VOID_RETURN;
}


1451 1452
Item *Item_sum_variance::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1453
  return new (thd->mem_root) Item_sum_variance(thd, this);
1454 1455 1456
}


1457 1458 1459 1460 1461
/**
  Create a new field to match the type of value we're expected to yield.
  If we're grouping, then we need some space to serialize variables into, to
  pass around.
*/
unknown's avatar
unknown committed
1462 1463 1464
Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table,
                                           uint convert_blob_len)
{
unknown's avatar
unknown committed
1465
  Field *field;
1466
  if (group)
unknown's avatar
unknown committed
1467
  {
1468 1469
    /*
      We must store both value and counter in the temporary table in one field.
1470
      The easiest way is to do this is to store both value in a string
1471 1472
      and unpack on access.
    */
1473
    field= new Field_string(sizeof(double)*2 + sizeof(longlong), 0, name, &my_charset_bin);
unknown's avatar
unknown committed
1474
  }
unknown's avatar
unknown committed
1475
  else
1476
    field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
1477 1478

  if (field != NULL)
unknown's avatar
unknown committed
1479
    field->init(table);
1480

unknown's avatar
unknown committed
1481
  return field;
unknown's avatar
unknown committed
1482 1483 1484
}


1485
void Item_sum_variance::clear()
unknown's avatar
unknown committed
1486
{
1487
  count= 0; 
unknown's avatar
unknown committed
1488 1489 1490
}

bool Item_sum_variance::add()
unknown's avatar
unknown committed
1491
{
1492 1493 1494 1495 1496 1497 1498 1499
  /* 
    Why use a temporary variable?  We don't know if it is null until we
    evaluate it, which has the side-effect of setting null_value .
  */
  double nr= args[0]->val_real();
  
  if (!args[0]->null_value)
    variance_fp_recurrence_next(&recurrence_m, &recurrence_s, &count, nr);
unknown's avatar
unknown committed
1500 1501 1502
  return 0;
}

1503
double Item_sum_variance::val_real()
unknown's avatar
unknown committed
1504
{
1505
  DBUG_ASSERT(fixed == 1);
1506

1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
  /*
    'sample' is a 1/0 boolean value.  If it is 1/true, id est this is a sample
    variance call, then we should set nullness when the count of the items
    is one or zero.  If it's zero, i.e. a population variance, then we only
    set nullness when the count is zero.

    Another way to read it is that 'sample' is the numerical threshhold, at and
    below which a 'count' number of items is called NULL.
  */
  DBUG_ASSERT((sample == 0) || (sample == 1));
1517
  if (count <= sample)
unknown's avatar
unknown committed
1518 1519 1520 1521
  {
    null_value=1;
    return 0.0;
  }
1522

unknown's avatar
unknown committed
1523
  null_value=0;
1524
  return variance_fp_recurrence_result(recurrence_s, count, sample);
unknown's avatar
unknown committed
1525 1526 1527 1528 1529
}


my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf)
{
1530 1531
  DBUG_ASSERT(fixed == 1);
  return val_decimal_from_real(dec_buf);
unknown's avatar
unknown committed
1532 1533
}

1534

unknown's avatar
unknown committed
1535 1536
void Item_sum_variance::reset_field()
{
1537
  double nr;
1538
  uchar *res= result_field->ptr;
1539

1540
  nr= args[0]->val_real();              /* sets null_value as side-effect */
unknown's avatar
unknown committed
1541 1542 1543 1544 1545

  if (args[0]->null_value)
    bzero(res,sizeof(double)*2+sizeof(longlong));
  else
  {
1546 1547 1548 1549 1550 1551 1552 1553
    /* Serialize format is (double)m, (double)s, (longlong)count */
    ulonglong tmp_count;
    double tmp_s;
    float8store(res, nr);               /* recurrence variable m */
    tmp_s= 0.0;
    float8store(res + sizeof(double), tmp_s);
    tmp_count= 1;
    int8store(res + sizeof(double)*2, tmp_count);
unknown's avatar
unknown committed
1554 1555 1556
  }
}

1557

unknown's avatar
unknown committed
1558
void Item_sum_variance::update_field()
unknown's avatar
unknown committed
1559
{
1560
  ulonglong field_count;
1561
  uchar *res=result_field->ptr;
1562 1563 1564 1565

  double nr= args[0]->val_real();       /* sets null_value as side-effect */

  if (args[0]->null_value)
unknown's avatar
unknown committed
1566
    return;
unknown's avatar
unknown committed
1567

1568 1569 1570 1571
  /* Serialize format is (double)m, (double)s, (longlong)count */
  double field_recurrence_m, field_recurrence_s;
  float8get(field_recurrence_m, res);
  float8get(field_recurrence_s, res + sizeof(double));
unknown's avatar
unknown committed
1572
  field_count=sint8korr(res+sizeof(double)*2);
unknown's avatar
unknown committed
1573

1574 1575 1576 1577
  variance_fp_recurrence_next(&field_recurrence_m, &field_recurrence_s, &field_count, nr);

  float8store(res, field_recurrence_m);
  float8store(res + sizeof(double), field_recurrence_s);
1578 1579
  res+= sizeof(double)*2;
  int8store(res,field_count);
unknown's avatar
unknown committed
1580 1581
}

1582

unknown's avatar
unknown committed
1583 1584
/* min & max */

1585 1586
void Item_sum_hybrid::clear()
{
1587
  switch (hybrid_type) {
unknown's avatar
unknown committed
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599
  case INT_RESULT:
    sum_int= 0;
    break;
  case DECIMAL_RESULT:
    my_decimal_set_zero(&sum_dec);
    break;
  case REAL_RESULT:
    sum= 0.0;
    break;
  default:
    value.length(0);
  }
1600 1601 1602
  null_value= 1;
}

1603
double Item_sum_hybrid::val_real()
unknown's avatar
unknown committed
1604
{
1605
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1606 1607
  if (null_value)
    return 0.0;
1608 1609
  switch (hybrid_type) {
  case STRING_RESULT:
1610 1611 1612
  {
    char *end_not_used;
    int err_not_used;
unknown's avatar
unknown committed
1613
    String *res;  res=val_str(&str_value);
1614 1615 1616
    return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
			     &end_not_used, &err_not_used) : 0.0);
  }
1617 1618 1619 1620
  case INT_RESULT:
    if (unsigned_flag)
      return ulonglong2double(sum_int);
    return (double) sum_int;
unknown's avatar
unknown committed
1621 1622 1623
  case DECIMAL_RESULT:
    my_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
    return sum;
1624 1625
  case REAL_RESULT:
    return sum;
1626
  case ROW_RESULT:
unknown's avatar
unknown committed
1627
  default:
unknown's avatar
unknown committed
1628 1629 1630
    // This case should never be choosen
    DBUG_ASSERT(0);
    return 0;
unknown's avatar
unknown committed
1631
  }
1632 1633 1634 1635
}

longlong Item_sum_hybrid::val_int()
{
1636
  DBUG_ASSERT(fixed == 1);
1637 1638
  if (null_value)
    return 0;
1639
  switch (hybrid_type) {
unknown's avatar
unknown committed
1640 1641 1642 1643 1644 1645
  case INT_RESULT:
    return sum_int;
  case DECIMAL_RESULT:
  {
    longlong result;
    my_decimal2int(E_DEC_FATAL_ERROR, &sum_dec, unsigned_flag, &result);
1646
    return sum_int;
unknown's avatar
unknown committed
1647 1648
  }
  default:
1649
    return (longlong) rint(Item_sum_hybrid::val_real());
unknown's avatar
unknown committed
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678
  }
}


my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
{
  DBUG_ASSERT(fixed == 1);
  if (null_value)
    return 0;
  switch (hybrid_type) {
  case STRING_RESULT:
    string2my_decimal(E_DEC_FATAL_ERROR, &value, val);
    break;
  case REAL_RESULT:
    double2my_decimal(E_DEC_FATAL_ERROR, sum, val);
    break;
  case DECIMAL_RESULT:
    val= &sum_dec;
    break;
  case INT_RESULT:
    int2my_decimal(E_DEC_FATAL_ERROR, sum_int, unsigned_flag, val);
    break;
  case ROW_RESULT:
  default:
    // This case should never be choosen
    DBUG_ASSERT(0);
    break;
  }
  return val;					// Keep compiler happy
unknown's avatar
unknown committed
1679 1680 1681 1682 1683 1684
}


String *
Item_sum_hybrid::val_str(String *str)
{
1685
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1686 1687
  if (null_value)
    return 0;
1688 1689
  switch (hybrid_type) {
  case STRING_RESULT:
unknown's avatar
unknown committed
1690
    return &value;
1691
  case REAL_RESULT:
1692
    str->set_real(sum,decimals, &my_charset_bin);
1693
    break;
unknown's avatar
unknown committed
1694 1695 1696
  case DECIMAL_RESULT:
    my_decimal2string(E_DEC_FATAL_ERROR, &sum_dec, 0, 0, 0, str);
    return str;
1697
  case INT_RESULT:
1698
    str->set_int(sum_int, unsigned_flag, &my_charset_bin);
1699
    break;
1700
  case ROW_RESULT:
unknown's avatar
unknown committed
1701
  default:
unknown's avatar
unknown committed
1702 1703 1704
    // This case should never be choosen
    DBUG_ASSERT(0);
    break;
1705 1706
  }
  return str;					// Keep compiler happy
unknown's avatar
unknown committed
1707 1708
}

1709

1710 1711 1712 1713
void Item_sum_hybrid::cleanup()
{
  DBUG_ENTER("Item_sum_hybrid::cleanup");
  Item_sum::cleanup();
unknown's avatar
unknown committed
1714
  forced_const= FALSE;
unknown's avatar
unknown committed
1715

1716
  /*
unknown's avatar
unknown committed
1717
    by default it is TRUE to avoid TRUE reporting by
1718 1719 1720
    Item_func_not_all/Item_func_nop_all if this item was never called.

    no_rows_in_result() set it to FALSE if was not results found.
unknown's avatar
unknown committed
1721
    If some results found it will be left unchanged.
1722 1723
  */
  was_values= TRUE;
1724 1725 1726
  DBUG_VOID_RETURN;
}

1727 1728 1729
void Item_sum_hybrid::no_rows_in_result()
{
  was_values= FALSE;
1730
  clear();
1731 1732
}

1733

1734 1735
Item *Item_sum_min::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1736
  return new (thd->mem_root) Item_sum_min(thd, this);
1737 1738 1739
}


unknown's avatar
unknown committed
1740 1741
bool Item_sum_min::add()
{
1742 1743
  switch (hybrid_type) {
  case STRING_RESULT:
unknown's avatar
unknown committed
1744 1745 1746
  {
    String *result=args[0]->val_str(&tmp_value);
    if (!args[0]->null_value &&
1747
	(null_value || sortcmp(&value,result,collation.collation) > 0))
unknown's avatar
unknown committed
1748 1749 1750 1751 1752
    {
      value.copy(*result);
      null_value=0;
    }
  }
1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766
  break;
  case INT_RESULT:
  {
    longlong nr=args[0]->val_int();
    if (!args[0]->null_value && (null_value ||
				 (unsigned_flag && 
				  (ulonglong) nr < (ulonglong) sum_int) ||
				 (!unsigned_flag && nr < sum_int)))
    {
      sum_int=nr;
      null_value=0;
    }
  }
  break;
unknown's avatar
unknown committed
1767 1768
  case DECIMAL_RESULT:
  {
1769
    my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
unknown's avatar
unknown committed
1770 1771 1772 1773 1774 1775 1776 1777
    if (!args[0]->null_value &&
        (null_value || (my_decimal_cmp(&sum_dec, val) > 0)))
    {
      my_decimal2decimal(val, &sum_dec);
      null_value= 0;
    }
  }
  break;
1778
  case REAL_RESULT:
unknown's avatar
unknown committed
1779
  {
1780
    double nr= args[0]->val_real();
1781
    if (!args[0]->null_value && (null_value || nr < sum))
unknown's avatar
unknown committed
1782 1783 1784 1785 1786
    {
      sum=nr;
      null_value=0;
    }
  }
1787
  break;
1788
  case ROW_RESULT:
unknown's avatar
unknown committed
1789
  default:
unknown's avatar
unknown committed
1790 1791 1792
    // This case should never be choosen
    DBUG_ASSERT(0);
    break;
1793 1794 1795 1796 1797
  }
  return 0;
}


1798 1799
Item *Item_sum_max::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1800
  return new (thd->mem_root) Item_sum_max(thd, this);
1801 1802 1803
}


1804 1805 1806 1807
bool Item_sum_max::add()
{
  switch (hybrid_type) {
  case STRING_RESULT:
unknown's avatar
unknown committed
1808 1809 1810
  {
    String *result=args[0]->val_str(&tmp_value);
    if (!args[0]->null_value &&
1811
	(null_value || sortcmp(&value,result,collation.collation) < 0))
unknown's avatar
unknown committed
1812 1813 1814 1815 1816
    {
      value.copy(*result);
      null_value=0;
    }
  }
1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830
  break;
  case INT_RESULT:
  {
    longlong nr=args[0]->val_int();
    if (!args[0]->null_value && (null_value ||
				 (unsigned_flag && 
				  (ulonglong) nr > (ulonglong) sum_int) ||
				 (!unsigned_flag && nr > sum_int)))
    {
      sum_int=nr;
      null_value=0;
    }
  }
  break;
unknown's avatar
unknown committed
1831 1832
  case DECIMAL_RESULT:
  {
1833
    my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
unknown's avatar
unknown committed
1834 1835 1836 1837 1838 1839 1840 1841
    if (!args[0]->null_value &&
        (null_value || (my_decimal_cmp(val, &sum_dec) > 0)))
    {
      my_decimal2decimal(val, &sum_dec);
      null_value= 0;
    }
  }
  break;
1842 1843
  case REAL_RESULT:
  {
1844
    double nr= args[0]->val_real();
1845 1846 1847 1848 1849 1850 1851
    if (!args[0]->null_value && (null_value || nr > sum))
    {
      sum=nr;
      null_value=0;
    }
  }
  break;
1852
  case ROW_RESULT:
unknown's avatar
unknown committed
1853
  default:
unknown's avatar
unknown committed
1854 1855 1856
    // This case should never be choosen
    DBUG_ASSERT(0);
    break;
1857
  }
unknown's avatar
unknown committed
1858 1859 1860 1861 1862 1863 1864 1865
  return 0;
}


/* bit_or and bit_and */

longlong Item_sum_bit::val_int()
{
1866
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1867 1868 1869
  return (longlong) bits;
}

1870

1871
void Item_sum_bit::clear()
1872
{
1873
  bits= reset_bits;
1874 1875 1876
}

Item *Item_sum_or::copy_or_same(THD* thd)
unknown's avatar
unknown committed
1877
{
unknown's avatar
unknown committed
1878
  return new (thd->mem_root) Item_sum_or(thd, this);
unknown's avatar
unknown committed
1879 1880
}

1881

unknown's avatar
unknown committed
1882 1883 1884 1885 1886 1887 1888 1889
bool Item_sum_or::add()
{
  ulonglong value= (ulonglong) args[0]->val_int();
  if (!args[0]->null_value)
    bits|=value;
  return 0;
}

1890 1891
Item *Item_sum_xor::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1892
  return new (thd->mem_root) Item_sum_xor(thd, this);
1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903
}


bool Item_sum_xor::add()
{
  ulonglong value= (ulonglong) args[0]->val_int();
  if (!args[0]->null_value)
    bits^=value;
  return 0;
}

1904 1905
Item *Item_sum_and::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1906
  return new (thd->mem_root) Item_sum_and(thd, this);
1907 1908 1909
}


unknown's avatar
unknown committed
1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923
bool Item_sum_and::add()
{
  ulonglong value= (ulonglong) args[0]->val_int();
  if (!args[0]->null_value)
    bits&=value;
  return 0;
}

/************************************************************************
** reset result of a Item_sum with is saved in a tmp_table
*************************************************************************/

void Item_sum_num::reset_field()
{
1924
  double nr= args[0]->val_real();
1925
  uchar *res=result_field->ptr;
unknown's avatar
unknown committed
1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942

  if (maybe_null)
  {
    if (args[0]->null_value)
    {
      nr=0.0;
      result_field->set_null();
    }
    else
      result_field->set_notnull();
  }
  float8store(res,nr);
}


void Item_sum_hybrid::reset_field()
{
1943
  switch(hybrid_type) {
unknown's avatar
unknown committed
1944
  case STRING_RESULT:
unknown's avatar
unknown committed
1945 1946
  {
    char buff[MAX_FIELD_WIDTH];
1947
    String tmp(buff,sizeof(buff),result_field->charset()),*res;
unknown's avatar
unknown committed
1948 1949 1950 1951 1952 1953 1954 1955 1956 1957

    res=args[0]->val_str(&tmp);
    if (args[0]->null_value)
    {
      result_field->set_null();
      result_field->reset();
    }
    else
    {
      result_field->set_notnull();
1958
      result_field->store(res->ptr(),res->length(),tmp.charset());
unknown's avatar
unknown committed
1959
    }
unknown's avatar
unknown committed
1960
    break;
unknown's avatar
unknown committed
1961
  }
unknown's avatar
unknown committed
1962
  case INT_RESULT:
unknown's avatar
unknown committed
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975
  {
    longlong nr=args[0]->val_int();

    if (maybe_null)
    {
      if (args[0]->null_value)
      {
	nr=0;
	result_field->set_null();
      }
      else
	result_field->set_notnull();
    }
1976
    result_field->store(nr, unsigned_flag);
unknown's avatar
unknown committed
1977
    break;
unknown's avatar
unknown committed
1978
  }
unknown's avatar
unknown committed
1979
  case REAL_RESULT:
unknown's avatar
unknown committed
1980
  {
1981
    double nr= args[0]->val_real();
unknown's avatar
unknown committed
1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993

    if (maybe_null)
    {
      if (args[0]->null_value)
      {
	nr=0.0;
	result_field->set_null();
      }
      else
	result_field->set_notnull();
    }
    result_field->store(nr);
unknown's avatar
unknown committed
1994 1995 1996 1997
    break;
  }
  case DECIMAL_RESULT:
  {
1998
    my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
unknown's avatar
unknown committed
1999 2000 2001 2002 2003 2004 2005 2006

    if (maybe_null)
    {
      if (args[0]->null_value)
        result_field->set_null();
      else
        result_field->set_notnull();
    }
2007 2008 2009 2010 2011 2012 2013
    /*
      We must store zero in the field as we will use the field value in
      add()
    */
    if (!arg_dec)                               // Null
      arg_dec= &decimal_zero;
    result_field->store_decimal(arg_dec);
unknown's avatar
unknown committed
2014 2015 2016 2017 2018
    break;
  }
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
unknown's avatar
unknown committed
2019 2020 2021 2022 2023 2024
  }
}


void Item_sum_sum::reset_field()
{
unknown's avatar
unknown committed
2025 2026 2027
  if (hybrid_type == DECIMAL_RESULT)
  {
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
2028 2029 2030
    if (!arg_val)                               // Null
      arg_val= &decimal_zero;
    result_field->store_decimal(arg_val);
unknown's avatar
unknown committed
2031 2032 2033 2034 2035 2036 2037
  }
  else
  {
    DBUG_ASSERT(hybrid_type == REAL_RESULT);
    double nr= args[0]->val_real();			// Nulls also return 0
    float8store(result_field->ptr, nr);
  }
unknown's avatar
unknown committed
2038 2039 2040 2041
  if (args[0]->null_value)
    result_field->set_null();
  else
    result_field->set_notnull();
unknown's avatar
unknown committed
2042 2043 2044 2045 2046
}


void Item_sum_count::reset_field()
{
2047
  uchar *res=result_field->ptr;
unknown's avatar
unknown committed
2048 2049
  longlong nr=0;

2050
  if (!args[0]->maybe_null || !args[0]->is_null())
unknown's avatar
unknown committed
2051 2052 2053 2054 2055 2056 2057
    nr=1;
  int8store(res,nr);
}


void Item_sum_avg::reset_field()
{
2058
  uchar *res=result_field->ptr;
unknown's avatar
unknown committed
2059 2060
  if (hybrid_type == DECIMAL_RESULT)
  {
2061
    longlong tmp;
unknown's avatar
unknown committed
2062 2063 2064
    my_decimal value, *arg_dec= args[0]->val_decimal(&value);
    if (args[0]->null_value)
    {
2065 2066
      arg_dec= &decimal_zero;
      tmp= 0;
unknown's avatar
unknown committed
2067 2068
    }
    else
2069 2070 2071 2072
      tmp= 1;
    my_decimal2binary(E_DEC_FATAL_ERROR, arg_dec, res, f_precision, f_scale);
    res+= dec_bin_size;
    int8store(res, tmp);
unknown's avatar
unknown committed
2073
  }
unknown's avatar
unknown committed
2074 2075
  else
  {
unknown's avatar
unknown committed
2076 2077 2078 2079 2080 2081
    double nr= args[0]->val_real();

    if (args[0]->null_value)
      bzero(res,sizeof(double)+sizeof(longlong));
    else
    {
2082
      longlong tmp= 1;
unknown's avatar
unknown committed
2083 2084 2085 2086
      float8store(res,nr);
      res+=sizeof(double);
      int8store(res,tmp);
    }
unknown's avatar
unknown committed
2087 2088 2089
  }
}

2090

unknown's avatar
unknown committed
2091
void Item_sum_bit::reset_field()
unknown's avatar
unknown committed
2092
{
2093 2094
  reset();
  int8store(result_field->ptr, bits);
unknown's avatar
unknown committed
2095 2096 2097
}

void Item_sum_bit::update_field()
unknown's avatar
unknown committed
2098
{
2099
  uchar *res=result_field->ptr;
unknown's avatar
unknown committed
2100 2101 2102
  bits= uint8korr(res);
  add();
  int8store(res, bits);
unknown's avatar
unknown committed
2103 2104
}

2105

unknown's avatar
unknown committed
2106 2107
/**
  calc next value and merge it with field_value.
unknown's avatar
unknown committed
2108 2109
*/

unknown's avatar
unknown committed
2110
void Item_sum_sum::update_field()
unknown's avatar
unknown committed
2111
{
unknown's avatar
unknown committed
2112
  if (hybrid_type == DECIMAL_RESULT)
unknown's avatar
unknown committed
2113
  {
unknown's avatar
unknown committed
2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
    if (!args[0]->null_value)
    {
      if (!result_field->is_null())
      {
        my_decimal field_value,
                   *field_val= result_field->val_decimal(&field_value);
        my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, field_val);
        result_field->store_decimal(dec_buffs);
      }
      else
      {
        result_field->store_decimal(arg_val);
        result_field->set_notnull();
      }
    }
  }
  else
  {
    double old_nr,nr;
2134
    uchar *res=result_field->ptr;
unknown's avatar
unknown committed
2135 2136 2137 2138 2139 2140 2141 2142 2143

    float8get(old_nr,res);
    nr= args[0]->val_real();
    if (!args[0]->null_value)
    {
      old_nr+=nr;
      result_field->set_notnull();
    }
    float8store(res,old_nr);
unknown's avatar
unknown committed
2144
  }
unknown's avatar
unknown committed
2145 2146 2147
}


unknown's avatar
unknown committed
2148
void Item_sum_count::update_field()
unknown's avatar
unknown committed
2149 2150
{
  longlong nr;
2151
  uchar *res=result_field->ptr;
unknown's avatar
unknown committed
2152

unknown's avatar
unknown committed
2153
  nr=sint8korr(res);
2154
  if (!args[0]->maybe_null || !args[0]->is_null())
unknown's avatar
unknown committed
2155 2156 2157 2158 2159
    nr++;
  int8store(res,nr);
}


unknown's avatar
unknown committed
2160
void Item_sum_avg::update_field()
unknown's avatar
unknown committed
2161 2162
{
  longlong field_count;
2163
  uchar *res=result_field->ptr;
unknown's avatar
unknown committed
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175
  if (hybrid_type == DECIMAL_RESULT)
  {
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
    if (!args[0]->null_value)
    {
      binary2my_decimal(E_DEC_FATAL_ERROR, res,
                        dec_buffs + 1, f_precision, f_scale);
      field_count= sint8korr(res + dec_bin_size);
      my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, dec_buffs + 1);
      my_decimal2binary(E_DEC_FATAL_ERROR, dec_buffs,
                        res, f_precision, f_scale);
      res+= dec_bin_size;
2176
      field_count++;
unknown's avatar
unknown committed
2177 2178 2179 2180 2181
      int8store(res, field_count);
    }
  }
  else
  {
2182
    double nr;
unknown's avatar
unknown committed
2183

unknown's avatar
unknown committed
2184 2185 2186
    nr= args[0]->val_real();
    if (!args[0]->null_value)
    {
2187 2188 2189
      double old_nr;
      float8get(old_nr, res);
      field_count= sint8korr(res + sizeof(double));
unknown's avatar
unknown committed
2190
      old_nr+= nr;
2191 2192
      float8store(res,old_nr);
      res+= sizeof(double);
unknown's avatar
unknown committed
2193
      field_count++;
2194
      int8store(res, field_count);
unknown's avatar
unknown committed
2195
    }
unknown's avatar
unknown committed
2196 2197 2198
  }
}

2199

unknown's avatar
unknown committed
2200
void Item_sum_hybrid::update_field()
unknown's avatar
unknown committed
2201
{
2202
  switch (hybrid_type) {
unknown's avatar
unknown committed
2203
  case STRING_RESULT:
unknown's avatar
unknown committed
2204
    min_max_update_str_field();
unknown's avatar
unknown committed
2205 2206
    break;
  case INT_RESULT:
unknown's avatar
unknown committed
2207
    min_max_update_int_field();
unknown's avatar
unknown committed
2208 2209 2210 2211 2212
    break;
  case DECIMAL_RESULT:
    min_max_update_decimal_field();
    break;
  default:
unknown's avatar
unknown committed
2213
    min_max_update_real_field();
unknown's avatar
unknown committed
2214
  }
unknown's avatar
unknown committed
2215 2216 2217 2218
}


void
unknown's avatar
unknown committed
2219
Item_sum_hybrid::min_max_update_str_field()
unknown's avatar
unknown committed
2220 2221 2222
{
  String *res_str=args[0]->val_str(&value);

unknown's avatar
unknown committed
2223
  if (!args[0]->null_value)
unknown's avatar
unknown committed
2224
  {
2225
    result_field->val_str(&tmp_value);
unknown's avatar
unknown committed
2226 2227

    if (result_field->is_null() ||
2228
	(cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
2229
      result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
unknown's avatar
unknown committed
2230 2231 2232 2233 2234 2235
    result_field->set_notnull();
  }
}


void
unknown's avatar
unknown committed
2236
Item_sum_hybrid::min_max_update_real_field()
unknown's avatar
unknown committed
2237 2238 2239 2240
{
  double nr,old_nr;

  old_nr=result_field->val_real();
2241
  nr= args[0]->val_real();
unknown's avatar
unknown committed
2242 2243
  if (!args[0]->null_value)
  {
unknown's avatar
unknown committed
2244
    if (result_field->is_null(0) ||
unknown's avatar
unknown committed
2245 2246 2247 2248
	(cmp_sign > 0 ? old_nr > nr : old_nr < nr))
      old_nr=nr;
    result_field->set_notnull();
  }
unknown's avatar
unknown committed
2249
  else if (result_field->is_null(0))
unknown's avatar
unknown committed
2250 2251 2252 2253 2254 2255
    result_field->set_null();
  result_field->store(old_nr);
}


void
unknown's avatar
unknown committed
2256
Item_sum_hybrid::min_max_update_int_field()
unknown's avatar
unknown committed
2257 2258 2259 2260 2261 2262 2263
{
  longlong nr,old_nr;

  old_nr=result_field->val_int();
  nr=args[0]->val_int();
  if (!args[0]->null_value)
  {
unknown's avatar
unknown committed
2264
    if (result_field->is_null(0))
unknown's avatar
unknown committed
2265
      old_nr=nr;
2266 2267 2268 2269 2270 2271
    else
    {
      bool res=(unsigned_flag ?
		(ulonglong) old_nr > (ulonglong) nr :
		old_nr > nr);
      /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
unknown's avatar
unknown committed
2272
      if ((cmp_sign > 0) ^ (!res))
2273 2274
	old_nr=nr;
    }
unknown's avatar
unknown committed
2275 2276
    result_field->set_notnull();
  }
unknown's avatar
unknown committed
2277
  else if (result_field->is_null(0))
unknown's avatar
unknown committed
2278
    result_field->set_null();
2279
  result_field->store(old_nr, unsigned_flag);
unknown's avatar
unknown committed
2280 2281 2282
}


unknown's avatar
unknown committed
2283 2284 2285 2286
/**
  @todo
  optimize: do not get result_field in case of args[0] is NULL
*/
unknown's avatar
unknown committed
2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313
void
Item_sum_hybrid::min_max_update_decimal_field()
{
  /* TODO: optimize: do not get result_field in case of args[0] is NULL */
  my_decimal old_val, nr_val;
  const my_decimal *old_nr= result_field->val_decimal(&old_val);
  const my_decimal *nr= args[0]->val_decimal(&nr_val);
  if (!args[0]->null_value)
  {
    if (result_field->is_null(0))
      old_nr=nr;
    else
    {
      bool res= my_decimal_cmp(old_nr, nr) > 0;
      /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
      if ((cmp_sign > 0) ^ (!res))
        old_nr=nr;
    }
    result_field->set_notnull();
  }
  else if (result_field->is_null(0))
    result_field->set_null();
  result_field->store_decimal(old_nr);
}


Item_avg_field::Item_avg_field(Item_result res_type, Item_sum_avg *item)
unknown's avatar
unknown committed
2314 2315 2316
{
  name=item->name;
  decimals=item->decimals;
unknown's avatar
unknown committed
2317 2318
  max_length= item->max_length;
  unsigned_flag= item->unsigned_flag;
unknown's avatar
unknown committed
2319 2320
  field=item->result_field;
  maybe_null=1;
unknown's avatar
unknown committed
2321
  hybrid_type= res_type;
unknown's avatar
unknown committed
2322
  prec_increment= item->prec_increment;
unknown's avatar
unknown committed
2323 2324 2325 2326 2327 2328
  if (hybrid_type == DECIMAL_RESULT)
  {
    f_scale= item->f_scale;
    f_precision= item->f_precision;
    dec_bin_size= item->dec_bin_size;
  }
unknown's avatar
unknown committed
2329 2330
}

2331
double Item_avg_field::val_real()
unknown's avatar
unknown committed
2332
{
2333
  // fix_fields() never calls for this Item
2334 2335
  double nr;
  longlong count;
2336
  uchar *res;
2337

unknown's avatar
unknown committed
2338
  if (hybrid_type == DECIMAL_RESULT)
2339
    return val_real_from_decimal();
unknown's avatar
unknown committed
2340

2341 2342 2343 2344 2345 2346 2347
  float8get(nr,field->ptr);
  res= (field->ptr+sizeof(double));
  count= sint8korr(res);

  if ((null_value= !count))
    return 0.0;
  return nr/(double) count;
unknown's avatar
unknown committed
2348 2349
}

2350

unknown's avatar
unknown committed
2351 2352
longlong Item_avg_field::val_int()
{
2353
  return (longlong) rint(val_real());
unknown's avatar
unknown committed
2354 2355 2356
}


2357
my_decimal *Item_avg_field::val_decimal(my_decimal *dec_buf)
unknown's avatar
unknown committed
2358 2359
{
  // fix_fields() never calls for this Item
2360 2361 2362
  if (hybrid_type == REAL_RESULT)
    return val_decimal_from_real(dec_buf);

unknown's avatar
unknown committed
2363 2364
  longlong count= sint8korr(field->ptr + dec_bin_size);
  if ((null_value= !count))
2365
    return 0;
unknown's avatar
unknown committed
2366 2367 2368 2369 2370

  my_decimal dec_count, dec_field;
  binary2my_decimal(E_DEC_FATAL_ERROR,
                    field->ptr, &dec_field, f_precision, f_scale);
  int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &dec_count);
unknown's avatar
unknown committed
2371 2372
  my_decimal_div(E_DEC_FATAL_ERROR, dec_buf,
                 &dec_field, &dec_count, prec_increment);
2373
  return dec_buf;
unknown's avatar
unknown committed
2374 2375
}

unknown's avatar
unknown committed
2376

unknown's avatar
unknown committed
2377 2378
String *Item_avg_field::val_str(String *str)
{
2379
  // fix_fields() never calls for this Item
unknown's avatar
unknown committed
2380
  if (hybrid_type == DECIMAL_RESULT)
2381 2382
    return val_string_from_decimal(str);
  return val_string_from_real(str);
unknown's avatar
unknown committed
2383 2384
}

2385

unknown's avatar
unknown committed
2386
Item_std_field::Item_std_field(Item_sum_std *item)
unknown's avatar
unknown committed
2387 2388 2389 2390
  : Item_variance_field(item)
{
}

2391

2392
double Item_std_field::val_real()
unknown's avatar
unknown committed
2393
{
2394
  double nr;
2395
  // fix_fields() never calls for this Item
2396 2397 2398
  nr= Item_variance_field::val_real();
  DBUG_ASSERT(nr >= 0.0);
  return sqrt(nr);
unknown's avatar
unknown committed
2399 2400
}

2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411

my_decimal *Item_std_field::val_decimal(my_decimal *dec_buf)
{
  /*
    We can't call val_decimal_from_real() for DECIMAL_RESULT as
    Item_variance_field::val_real() would cause an infinite loop
  */
  my_decimal tmp_dec, *dec;
  double nr;
  if (hybrid_type == REAL_RESULT)
    return val_decimal_from_real(dec_buf);
2412

2413 2414 2415 2416
  dec= Item_variance_field::val_decimal(dec_buf);
  if (!dec)
    return 0;
  my_decimal2double(E_DEC_FATAL_ERROR, dec, &nr);
2417 2418
  DBUG_ASSERT(nr >= 0.0);
  nr= sqrt(nr);
2419 2420 2421 2422 2423 2424
  double2my_decimal(E_DEC_FATAL_ERROR, nr, &tmp_dec);
  my_decimal_round(E_DEC_FATAL_ERROR, &tmp_dec, decimals, FALSE, dec_buf);
  return dec_buf;
}


unknown's avatar
unknown committed
2425
Item_variance_field::Item_variance_field(Item_sum_variance *item)
unknown's avatar
unknown committed
2426 2427 2428 2429
{
  name=item->name;
  decimals=item->decimals;
  max_length=item->max_length;
unknown's avatar
unknown committed
2430
  unsigned_flag= item->unsigned_flag;
unknown's avatar
unknown committed
2431 2432
  field=item->result_field;
  maybe_null=1;
2433
  sample= item->sample;
unknown's avatar
unknown committed
2434
  prec_increment= item->prec_increment;
unknown's avatar
unknown committed
2435 2436 2437 2438 2439 2440 2441 2442 2443
  if ((hybrid_type= item->hybrid_type) == DECIMAL_RESULT)
  {
    f_scale0= item->f_scale0;
    f_precision0= item->f_precision0;
    dec_bin_size0= item->dec_bin_size0;
    f_scale1= item->f_scale1;
    f_precision1= item->f_precision1;
    dec_bin_size1= item->dec_bin_size1;
  }
unknown's avatar
unknown committed
2444 2445
}

2446

2447
double Item_variance_field::val_real()
unknown's avatar
unknown committed
2448
{
2449
  // fix_fields() never calls for this Item
unknown's avatar
unknown committed
2450
  if (hybrid_type == DECIMAL_RESULT)
2451 2452
    return val_real_from_decimal();

2453 2454 2455
  double recurrence_s;
  ulonglong count;
  float8get(recurrence_s, (field->ptr + sizeof(double)));
unknown's avatar
unknown committed
2456 2457
  count=sint8korr(field->ptr+sizeof(double)*2);

2458
  if ((null_value= (count <= sample)))
unknown's avatar
unknown committed
2459
    return 0.0;
2460

2461
  return variance_fp_recurrence_result(recurrence_s, count, sample);
unknown's avatar
unknown committed
2462 2463 2464
}


unknown's avatar
unknown committed
2465 2466 2467 2468
/****************************************************************************
** COUNT(DISTINCT ...)
****************************************************************************/

2469
int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2)
2470
{
2471
  Field *f= (Field*) arg;
2472
  return f->cmp(key1, key2);
2473 2474
}

unknown's avatar
unknown committed
2475
/**
unknown's avatar
unknown committed
2476 2477 2478 2479 2480 2481
  Did not make this one static - at least gcc gets confused when
  I try to declare a static function as a friend. If you can figure
  out the syntax to make a static function a friend, make this one
  static
*/

2482
int composite_key_cmp(void* arg, uchar* key1, uchar* key2)
2483 2484
{
  Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
unknown's avatar
unknown committed
2485
  Field **field    = item->table->field;
2486
  Field **field_end= field + item->table->s->fields;
unknown's avatar
unknown committed
2487 2488 2489 2490 2491
  uint32 *lengths=item->field_lengths;
  for (; field < field_end; ++field)
  {
    Field* f = *field;
    int len = *lengths++;
2492
    int res = f->cmp(key1, key2);
unknown's avatar
unknown committed
2493 2494 2495 2496 2497
    if (res)
      return res;
    key1 += len;
    key2 += len;
  }
2498 2499 2500 2501
  return 0;
}


2502 2503
C_MODE_START

2504
static int count_distinct_walk(void *elem, element_count count, void *arg)
2505
{
2506
  (*((ulonglong*)arg))++;
2507 2508
  return 0;
}
2509

2510 2511
C_MODE_END

unknown's avatar
unknown committed
2512

unknown's avatar
unknown committed
2513
void Item_sum_count_distinct::cleanup()
unknown's avatar
unknown committed
2514
{
unknown's avatar
unknown committed
2515
  DBUG_ENTER("Item_sum_count_distinct::cleanup");
unknown's avatar
unknown committed
2516
  Item_sum_int::cleanup();
2517 2518

  /* Free objects only if we own them. */
2519 2520
  if (!original)
  {
2521 2522 2523 2524 2525 2526 2527
    /*
      We need to delete the table and the tree in cleanup() as
      they were allocated in the runtime memroot. Using the runtime
      memroot reduces memory footprint for PS/SP and simplifies setup().
    */
    delete tree;
    tree= 0;
2528
    is_evaluated= FALSE;
2529
    if (table)
unknown's avatar
unknown committed
2530
    {
2531
      free_tmp_table(table->in_use, table);
unknown's avatar
unknown committed
2532 2533
      table= 0;
    }
2534
    delete tmp_table_param;
unknown's avatar
unknown committed
2535
    tmp_table_param= 0;
2536
  }
2537
  always_null= FALSE;
unknown's avatar
unknown committed
2538
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
2539 2540
}

unknown's avatar
unknown committed
2541

unknown's avatar
unknown committed
2542 2543 2544 2545
/**
  This is used by rollup to create a separate usable copy of
  the function.
*/
2546 2547 2548 2549 2550

void Item_sum_count_distinct::make_unique()
{
  table=0;
  original= 0;
2551
  force_copy_fields= 1;
2552
  tree= 0;
2553
  is_evaluated= FALSE;
2554 2555 2556 2557 2558 2559 2560 2561
  tmp_table_param= 0;
  always_null= FALSE;
}


Item_sum_count_distinct::~Item_sum_count_distinct()
{
  cleanup();
2562 2563 2564
}


unknown's avatar
unknown committed
2565 2566 2567
bool Item_sum_count_distinct::setup(THD *thd)
{
  List<Item> list;
unknown's avatar
unknown committed
2568
  SELECT_LEX *select_lex= thd->lex->current_select;
2569 2570 2571 2572

  /*
    Setup can be called twice for ROLLUP items. This is a bug.
    Please add DBUG_ASSERT(tree == 0) here when it's fixed.
2573
    It's legal to call setup() more than once when in a subquery
2574 2575 2576 2577
  */
  if (tree || table || tmp_table_param)
    return FALSE;

2578
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
unknown's avatar
unknown committed
2579
    return TRUE;
2580

unknown's avatar
unknown committed
2581 2582
  /* Create a table with an unique key over all parameters */
  for (uint i=0; i < arg_count ; i++)
2583 2584 2585
  {
    Item *item=args[i];
    if (list.push_back(item))
unknown's avatar
unknown committed
2586
      return TRUE;                              // End of memory
2587 2588
    if (item->const_item() && item->is_null())
      always_null= 1;
2589 2590
  }
  if (always_null)
unknown's avatar
unknown committed
2591
    return FALSE;
2592
  count_field_types(select_lex, tmp_table_param, list, 0);
2593
  tmp_table_param->force_copy_fields= force_copy_fields;
2594
  DBUG_ASSERT(table == 0);
2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611
  /*
    Make create_tmp_table() convert BIT columns to BIGINT.
    This is needed because BIT fields store parts of their data in table's
    null bits, and we don't have methods to compare two table records, which
    is needed by Unique which is used when HEAP table is used.
  */
  {
    List_iterator_fast<Item> li(list);
    Item *item;
    while ((item= li++))
    {
      if (item->type() == Item::FIELD_ITEM &&
          ((Item_field*)item)->field->type() == FIELD_TYPE_BIT)
        item->marker=4;
    }
  }

2612
  if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
unknown's avatar
unknown committed
2613
				0,
2614
				(select_lex->options | thd->options),
2615
				HA_POS_ERROR, (char*)"")))
unknown's avatar
unknown committed
2616
    return TRUE;
unknown's avatar
unknown committed
2617
  table->file->extra(HA_EXTRA_NO_ROWS);		// Don't update rows
2618
  table->no_rows=1;
2619

unknown's avatar
unknown committed
2620
  if (table->s->db_type() == heap_hton)
unknown's avatar
unknown committed
2621
  {
2622 2623 2624 2625
    /*
      No blobs, otherwise it would have been MyISAM: set up a compare
      function and its arguments to use with Unique.
    */
unknown's avatar
unknown committed
2626 2627
    qsort_cmp2 compare_key;
    void* cmp_arg;
2628 2629 2630
    Field **field= table->field;
    Field **field_end= field + table->s->fields;
    bool all_binary= TRUE;
unknown's avatar
unknown committed
2631

2632
    for (tree_key_length= 0; field < field_end; ++field)
unknown's avatar
unknown committed
2633
    {
2634
      Field *f= *field;
2635
      enum enum_field_types f_type= f->type();
2636
      tree_key_length+= f->pack_length();
2637
      if ((f_type == MYSQL_TYPE_VARCHAR) ||
2638 2639
          (!f->binary() && (f_type == MYSQL_TYPE_STRING ||
                            f_type == MYSQL_TYPE_VAR_STRING)))
2640 2641 2642
      {
        all_binary= FALSE;
        break;
unknown's avatar
unknown committed
2643
      }
2644
    }
2645
    if (all_binary)
unknown's avatar
unknown committed
2646
    {
2647 2648 2649 2650 2651 2652
      cmp_arg= (void*) &tree_key_length;
      compare_key= (qsort_cmp2) simple_raw_key_cmp;
    }
    else
    {
      if (table->s->fields == 1)
unknown's avatar
unknown committed
2653
      {
2654 2655 2656 2657 2658 2659 2660 2661 2662
        /*
          If we have only one field, which is the most common use of
          count(distinct), it is much faster to use a simpler key
          compare method that can take advantage of not having to worry
          about other fields.
        */
        compare_key= (qsort_cmp2) simple_str_key_cmp;
        cmp_arg= (void*) table->field[0];
        /* tree_key_length has been set already */
unknown's avatar
unknown committed
2663 2664 2665
      }
      else
      {
2666 2667 2668 2669 2670 2671 2672 2673 2674 2675
        uint32 *length;
        compare_key= (qsort_cmp2) composite_key_cmp;
        cmp_arg= (void*) this;
        field_lengths= (uint32*) thd->alloc(table->s->fields * sizeof(uint32));
        for (tree_key_length= 0, length= field_lengths, field= table->field;
             field < field_end; ++field, ++length)
        {
          *length= (*field)->pack_length();
          tree_key_length+= *length;
        }
unknown's avatar
unknown committed
2676 2677
      }
    }
2678 2679 2680
    DBUG_ASSERT(tree == 0);
    tree= new Unique(compare_key, cmp_arg, tree_key_length,
                     thd->variables.max_heap_table_size);
unknown's avatar
unknown committed
2681
    /*
2682
      The only time tree_key_length could be 0 is if someone does
unknown's avatar
unknown committed
2683 2684 2685 2686
      count(distinct) on a char(0) field - stupid thing to do,
      but this has to be handled - otherwise someone can crash
      the server with a DoS attack
    */
2687
    is_evaluated= FALSE;
2688 2689
    if (! tree)
      return TRUE;
unknown's avatar
unknown committed
2690
  }
2691
  return FALSE;
2692
}
unknown's avatar
unknown committed
2693

2694 2695 2696

Item *Item_sum_count_distinct::copy_or_same(THD* thd) 
{
unknown's avatar
unknown committed
2697
  return new (thd->mem_root) Item_sum_count_distinct(thd, this);
2698 2699 2700
}


2701
void Item_sum_count_distinct::clear()
unknown's avatar
unknown committed
2702
{
2703
  /* tree and table can be both null only if always_null */
2704
  is_evaluated= FALSE;
2705
  if (tree)
2706
  {
2707
    tree->reset();
2708
  }
unknown's avatar
merge  
unknown committed
2709
  else if (table)
2710 2711
  {
    table->file->extra(HA_EXTRA_NO_CACHE);
2712
    table->file->ha_delete_all_rows();
2713 2714
    table->file->extra(HA_EXTRA_WRITE_CACHE);
  }
unknown's avatar
unknown committed
2715 2716 2717 2718 2719
}

bool Item_sum_count_distinct::add()
{
  int error;
2720 2721
  if (always_null)
    return 0;
unknown's avatar
unknown committed
2722
  copy_fields(tmp_table_param);
unknown's avatar
unknown committed
2723
  copy_funcs(tmp_table_param->items_to_copy);
unknown's avatar
unknown committed
2724

2725 2726 2727 2728
  for (Field **field=table->field ; *field ; field++)
    if ((*field)->is_real_null(0))
      return 0;					// Don't count NULL

2729
  is_evaluated= FALSE;
2730
  if (tree)
unknown's avatar
unknown committed
2731 2732
  {
    /*
2733 2734 2735 2736
      The first few bytes of record (at least one) are just markers
      for deleted and NULLs. We want to skip them since they will
      bloat the tree without providing any valuable info. Besides,
      key_length used to initialize the tree didn't include space for them.
unknown's avatar
unknown committed
2737
    */
2738
    return tree->unique_add(table->record[0] + table->s->null_bytes);
unknown's avatar
unknown committed
2739
  }
2740
  if ((error= table->file->ha_write_row(table->record[0])) &&
2741
      table->file->is_fatal_error(error, HA_CHECK_DUP))
2742 2743
    return TRUE;
  return FALSE;
unknown's avatar
unknown committed
2744 2745
}

unknown's avatar
unknown committed
2746

unknown's avatar
unknown committed
2747 2748
longlong Item_sum_count_distinct::val_int()
{
2749
  int error;
2750
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2751 2752
  if (!table)					// Empty query
    return LL(0);
2753 2754
  if (tree)
  {
2755 2756
    if (is_evaluated)
      return count;
2757 2758 2759 2760 2761

    if (tree->elements == 0)
      return (longlong) tree->elements_in_tree(); // everything fits in memory
    count= 0;
    tree->walk(count_distinct_walk, (void*) &count);
2762
    is_evaluated= TRUE;
2763 2764
    return (longlong) count;
  }
2765 2766 2767 2768 2769 2770 2771 2772

  error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);

  if(error)
  {
    table->file->print_error(error, MYF(0));
  }

2773
  return table->file->stats.records;
unknown's avatar
unknown committed
2774 2775
}

2776

unknown's avatar
unknown committed
2777 2778 2779 2780 2781 2782 2783 2784 2785
/****************************************************************************
** Functions to handle dynamic loadable aggregates
** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
** Adapted for UDAs by: Andreas F. Bobak <bobak@relog.ch>.
** Rewritten by: Monty.
****************************************************************************/

#ifdef HAVE_DLOPEN

2786
void Item_udf_sum::clear()
unknown's avatar
unknown committed
2787
{
2788
  DBUG_ENTER("Item_udf_sum::clear");
2789
  udf.clear();
2790
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
2791 2792 2793 2794
}

bool Item_udf_sum::add()
{
2795
  DBUG_ENTER("Item_udf_sum::add");
unknown's avatar
unknown committed
2796 2797 2798 2799
  udf.add(&null_value);
  DBUG_RETURN(0);
}

2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810
void Item_udf_sum::cleanup()
{
  /*
    udf_handler::cleanup() nicely handles case when we have not
    original item but one created by copy_or_same() method.
  */
  udf.cleanup();
  Item_sum::cleanup();
}


2811
void Item_udf_sum::print(String *str, enum_query_type query_type)
2812 2813 2814 2815 2816 2817 2818
{
  str->append(func_name());
  str->append('(');
  for (uint i=0 ; i < arg_count ; i++)
  {
    if (i)
      str->append(',');
2819
    args[i]->print(str, query_type);
2820 2821 2822 2823 2824
  }
  str->append(')');
}


2825 2826
Item *Item_sum_udf_float::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
2827
  return new (thd->mem_root) Item_sum_udf_float(thd, this);
2828 2829
}

2830
double Item_sum_udf_float::val_real()
unknown's avatar
unknown committed
2831
{
2832
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2833 2834 2835 2836 2837 2838
  DBUG_ENTER("Item_sum_udf_float::val");
  DBUG_PRINT("info",("result_type: %d  arg_count: %d",
		     args[0]->result_type(), arg_count));
  DBUG_RETURN(udf.val(&null_value));
}

2839

unknown's avatar
unknown committed
2840 2841
String *Item_sum_udf_float::val_str(String *str)
{
2842
  return val_string_from_real(str);
unknown's avatar
unknown committed
2843 2844 2845
}


2846
my_decimal *Item_sum_udf_float::val_decimal(my_decimal *dec)
2847
{
2848
  return val_decimal_from_real(dec);
2849 2850 2851
}


unknown's avatar
unknown committed
2852 2853
String *Item_sum_udf_decimal::val_str(String *str)
{
2854
  return val_string_from_decimal(str);
unknown's avatar
unknown committed
2855 2856 2857 2858 2859
}


double Item_sum_udf_decimal::val_real()
{
2860
  return val_real_from_decimal();
unknown's avatar
unknown committed
2861 2862 2863 2864 2865
}


longlong Item_sum_udf_decimal::val_int()
{
2866
  return val_int_from_decimal();
unknown's avatar
unknown committed
2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886
}


my_decimal *Item_sum_udf_decimal::val_decimal(my_decimal *dec_buf)
{
  DBUG_ASSERT(fixed == 1);
  DBUG_ENTER("Item_func_udf_decimal::val_decimal");
  DBUG_PRINT("info",("result_type: %d  arg_count: %d",
                     args[0]->result_type(), arg_count));

  DBUG_RETURN(udf.val_decimal(&null_value, dec_buf));
}


Item *Item_sum_udf_decimal::copy_or_same(THD* thd)
{
  return new (thd->mem_root) Item_sum_udf_decimal(thd, this);
}


2887 2888 2889 2890 2891
Item *Item_sum_udf_int::copy_or_same(THD* thd)
{
  return new (thd->mem_root) Item_sum_udf_int(thd, this);
}

unknown's avatar
unknown committed
2892 2893
longlong Item_sum_udf_int::val_int()
{
2894
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2895 2896 2897 2898 2899 2900
  DBUG_ENTER("Item_sum_udf_int::val_int");
  DBUG_PRINT("info",("result_type: %d  arg_count: %d",
		     args[0]->result_type(), arg_count));
  DBUG_RETURN(udf.val_int(&null_value));
}

2901

unknown's avatar
unknown committed
2902 2903
String *Item_sum_udf_int::val_str(String *str)
{
2904
  return val_string_from_int(str);
unknown's avatar
unknown committed
2905 2906
}

2907 2908 2909 2910 2911 2912
my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
{
  return val_decimal_from_int(dec);
}


unknown's avatar
unknown committed
2913
/** Default max_length is max argument length. */
unknown's avatar
unknown committed
2914 2915 2916 2917 2918 2919 2920 2921 2922 2923

void Item_sum_udf_str::fix_length_and_dec()
{
  DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec");
  max_length=0;
  for (uint i = 0; i < arg_count; i++)
    set_if_bigger(max_length,args[i]->max_length);
  DBUG_VOID_RETURN;
}

2924 2925 2926

Item *Item_sum_udf_str::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
2927
  return new (thd->mem_root) Item_sum_udf_str(thd, this);
2928 2929 2930
}


2931 2932 2933 2934 2935
my_decimal *Item_sum_udf_str::val_decimal(my_decimal *dec)
{
  return val_decimal_from_string(dec);
}

unknown's avatar
unknown committed
2936 2937
String *Item_sum_udf_str::val_str(String *str)
{
2938
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2939 2940 2941 2942 2943 2944 2945
  DBUG_ENTER("Item_sum_udf_str::str");
  String *res=udf.val_str(str,&str_value);
  null_value = !res;
  DBUG_RETURN(res);
}

#endif /* HAVE_DLOPEN */
2946 2947 2948 2949


/*****************************************************************************
 GROUP_CONCAT function
unknown's avatar
unknown committed
2950 2951

 SQL SYNTAX:
unknown's avatar
unknown committed
2952
  GROUP_CONCAT([DISTINCT] expr,... [ORDER BY col [ASC|DESC],...]
unknown's avatar
unknown committed
2953 2954
    [SEPARATOR str_const])

2955
 concat of values from "group by" operation
unknown's avatar
unknown committed
2956 2957 2958

 BUGS
   Blobs doesn't work with DISTINCT or ORDER BY
2959 2960
*****************************************************************************/

2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975


/** 
  Compares the values for fields in expr list of GROUP_CONCAT.
  @note
       
     GROUP_CONCAT([DISTINCT] expr [,expr ...]
              [ORDER BY {unsigned_integer | col_name | expr}
                  [ASC | DESC] [,col_name ...]]
              [SEPARATOR str_val])
 
  @return
  @retval -1 : key1 < key2 
  @retval  0 : key1 = key2
  @retval  1 : key1 > key2 
2976 2977
*/

2978 2979
int group_concat_key_cmp_with_distinct(void* arg, const void* key1, 
                                       const void* key2)
2980
{
2981 2982
  Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
  TABLE *table= item_func->table;
unknown's avatar
unknown committed
2983

2984
  for (uint i= 0; i < item_func->arg_count_field; i++)
2985
  {
2986 2987 2988 2989 2990 2991 2992
    Item *item= item_func->args[i];
    /* 
      If field_item is a const item then either get_tp_table_field returns 0
      or it is an item over a const table. 
    */
    if (item->const_item())
      continue;
unknown's avatar
unknown committed
2993 2994 2995 2996 2997
    /*
      We have to use get_tmp_table_field() instead of
      real_item()->get_tmp_table_field() because we want the field in
      the temporary table, not the original field
    */
2998 2999
    Field *field= item->get_tmp_table_field();
    int res;
3000 3001
    uint offset= field->offset(field->table->record[0])-table->s->null_bytes;
    if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
3002
      return res;
unknown's avatar
unknown committed
3003
  }
3004 3005 3006
  return 0;
}

3007

unknown's avatar
unknown committed
3008 3009
/**
  function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
3010 3011
*/

3012 3013
int group_concat_key_cmp_with_order(void* arg, const void* key1, 
                                    const void* key2)
3014
{
unknown's avatar
unknown committed
3015
  Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
unknown's avatar
unknown committed
3016
  ORDER **order_item, **end;
unknown's avatar
unknown committed
3017
  TABLE *table= grp_item->table;
unknown's avatar
unknown committed
3018

unknown's avatar
unknown committed
3019
  for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
unknown's avatar
unknown committed
3020 3021
       order_item < end;
       order_item++)
3022
  {
unknown's avatar
unknown committed
3023
    Item *item= *(*order_item)->item;
unknown's avatar
unknown committed
3024 3025 3026 3027 3028 3029
    /*
      We have to use get_tmp_table_field() instead of
      real_item()->get_tmp_table_field() because we want the field in
      the temporary table, not the original field
    */
    Field *field= item->get_tmp_table_field();
unknown's avatar
unknown committed
3030 3031 3032 3033 3034
    /* 
      If item is a const item then either get_tp_table_field returns 0
      or it is an item over a const table. 
    */
    if (field && !item->const_item())
3035
    {
unknown's avatar
unknown committed
3036
      int res;
3037 3038
      uint offset= (field->offset(field->table->record[0]) -
                    table->s->null_bytes);
3039
      if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
unknown's avatar
unknown committed
3040
        return (*order_item)->asc ? res : -res;
3041
    }
unknown's avatar
unknown committed
3042
  }
unknown's avatar
SCRUM  
unknown committed
3043
  /*
unknown's avatar
unknown committed
3044 3045
    We can't return 0 because in that case the tree class would remove this
    item as double value. This would cause problems for case-changes and
unknown's avatar
unknown committed
3046
    if the returned values are not the same we do the sort on.
unknown's avatar
unknown committed
3047
  */
3048 3049 3050
  return 1;
}

3051

unknown's avatar
unknown committed
3052 3053
/**
  Append data from current leaf to item->result.
3054
*/
unknown's avatar
SCRUM  
unknown committed
3055

3056
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
unknown's avatar
unknown committed
3057
                  Item_func_group_concat *item)
3058
{
unknown's avatar
unknown committed
3059
  TABLE *table= item->table;
unknown's avatar
unknown committed
3060 3061 3062
  String tmp((char *)table->record[1], table->s->reclength,
             default_charset_info);
  String tmp2;
unknown's avatar
unknown committed
3063
  String *result= &item->result;
unknown's avatar
unknown committed
3064
  Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
3065
  uint old_length= result->length();
unknown's avatar
unknown committed
3066

3067 3068 3069
  if (item->no_appended)
    item->no_appended= FALSE;
  else
unknown's avatar
unknown committed
3070
    result->append(*item->separator);
unknown's avatar
a fix  
unknown committed
3071

3072
  tmp.length(0);
unknown's avatar
unknown committed
3073 3074

  for (; arg < arg_end; arg++)
3075
  {
unknown's avatar
unknown committed
3076 3077
    String *res;
    if (! (*arg)->const_item())
3078
    {
unknown's avatar
unknown committed
3079 3080 3081 3082
      /*
	We have to use get_tmp_table_field() instead of
	real_item()->get_tmp_table_field() because we want the field in
	the temporary table, not the original field
unknown's avatar
unknown committed
3083 3084
        We also can't use table->field array to access the fields
        because it contains both order and arg list fields.
unknown's avatar
unknown committed
3085
      */
unknown's avatar
unknown committed
3086
      Field *field= (*arg)->get_tmp_table_field();
3087 3088
      uint offset= (field->offset(field->table->record[0]) -
                    table->s->null_bytes);
unknown's avatar
unknown committed
3089
      DBUG_ASSERT(offset < table->s->reclength);
3090
      res= field->val_str(&tmp, key + offset);
3091
    }
unknown's avatar
unknown committed
3092 3093 3094
    else
      res= (*arg)->val_str(&tmp);
    if (res)
unknown's avatar
unknown committed
3095
      result->append(*res);
3096
  }
unknown's avatar
unknown committed
3097

unknown's avatar
unknown committed
3098
  /* stop if length of result more than max_length */
unknown's avatar
unknown committed
3099
  if (result->length() > item->max_length)
3100
  {
3101 3102
    int well_formed_error;
    CHARSET_INFO *cs= item->collation.collation;
unknown's avatar
unknown committed
3103
    const char *ptr= result->ptr();
3104 3105 3106 3107 3108 3109 3110 3111
    uint add_length;
    /*
      It's ok to use item->result.length() as the fourth argument
      as this is never used to limit the length of the data.
      Cut is done with the third argument.
    */
    add_length= cs->cset->well_formed_len(cs,
                                          ptr + old_length,
unknown's avatar
unknown committed
3112 3113
                                          ptr + item->max_length,
                                          result->length(),
3114
                                          &well_formed_error);
unknown's avatar
unknown committed
3115
    result->length(old_length + add_length);
unknown's avatar
unknown committed
3116 3117
    item->count_cut_values++;
    item->warning_for_row= TRUE;
3118 3119 3120 3121 3122
    return 1;
  }
  return 0;
}

3123

unknown's avatar
unknown committed
3124 3125 3126 3127 3128 3129 3130
/**
  Constructor of Item_func_group_concat.

  @param distinct_arg   distinct
  @param select_list    list of expression for show values
  @param order_list     list of sort columns
  @param separator_arg  string value of separator.
3131
*/
unknown's avatar
SCRUM  
unknown committed
3132

unknown's avatar
unknown committed
3133
Item_func_group_concat::
3134 3135
Item_func_group_concat(Name_resolution_context *context_arg,
                       bool distinct_arg, List<Item> *select_list,
unknown's avatar
unknown committed
3136 3137
                       SQL_LIST *order_list, String *separator_arg)
  :tmp_table_param(0), warning(0),
3138
   separator(separator_arg), tree(0), unique_filter(NULL), table(0),
3139
   order(0), context(context_arg),
unknown's avatar
unknown committed
3140 3141 3142 3143 3144
   arg_count_order(order_list ? order_list->elements : 0),
   arg_count_field(select_list->elements),
   count_cut_values(0),
   distinct(distinct_arg),
   warning_for_row(FALSE),
unknown's avatar
unknown committed
3145
   force_copy_fields(0), original(0)
3146
{
unknown's avatar
unknown committed
3147 3148 3149
  Item *item_select;
  Item **arg_ptr;

unknown's avatar
unknown committed
3150
  quick_group= FALSE;
unknown's avatar
unknown committed
3151
  arg_count= arg_count_field + arg_count_order;
unknown's avatar
unknown committed
3152

unknown's avatar
SCRUM  
unknown committed
3153 3154
  /*
    We need to allocate:
unknown's avatar
unknown committed
3155 3156
    args - arg_count_field+arg_count_order
           (for possible order items in temporare tables)
unknown's avatar
SCRUM  
unknown committed
3157 3158
    order - arg_count_order
  */
unknown's avatar
unknown committed
3159
  if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
unknown's avatar
unknown committed
3160
                                 sizeof(ORDER*)*arg_count_order)))
unknown's avatar
unknown committed
3161
    return;
unknown's avatar
unknown committed
3162

3163 3164 3165 3166 3167 3168
  if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count)))
  {
    args= NULL;
    return;
  }

unknown's avatar
unknown committed
3169 3170
  order= (ORDER**)(args + arg_count);

unknown's avatar
unknown committed
3171
  /* fill args items of show and sort */
unknown's avatar
unknown committed
3172
  List_iterator_fast<Item> li(*select_list);
3173

unknown's avatar
unknown committed
3174 3175
  for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
    *arg_ptr= item_select;
unknown's avatar
unknown committed
3176

unknown's avatar
unknown committed
3177
  if (arg_count_order)
unknown's avatar
SCRUM  
unknown committed
3178
  {
unknown's avatar
unknown committed
3179
    ORDER **order_ptr= order;
unknown's avatar
unknown committed
3180 3181 3182
    for (ORDER *order_item= (ORDER*) order_list->first;
         order_item != NULL;
         order_item= order_item->next)
3183
    {
unknown's avatar
unknown committed
3184 3185 3186
      (*order_ptr++)= order_item;
      *arg_ptr= *order_item->item;
      order_item->item= arg_ptr++;
3187 3188 3189
    }
  }
}
unknown's avatar
unknown committed
3190

unknown's avatar
unknown committed
3191 3192

Item_func_group_concat::Item_func_group_concat(THD *thd,
unknown's avatar
unknown committed
3193 3194
                                               Item_func_group_concat *item)
  :Item_sum(thd, item),
unknown's avatar
unknown committed
3195 3196 3197 3198
  tmp_table_param(item->tmp_table_param),
  warning(item->warning),
  separator(item->separator),
  tree(item->tree),
3199
  unique_filter(item->unique_filter),
unknown's avatar
unknown committed
3200 3201
  table(item->table),
  order(item->order),
3202
  context(item->context),
unknown's avatar
unknown committed
3203 3204 3205
  arg_count_order(item->arg_count_order),
  arg_count_field(item->arg_count_field),
  count_cut_values(item->count_cut_values),
unknown's avatar
unknown committed
3206 3207 3208
  distinct(item->distinct),
  warning_for_row(item->warning_for_row),
  always_null(item->always_null),
unknown's avatar
unknown committed
3209
  force_copy_fields(item->force_copy_fields),
unknown's avatar
unknown committed
3210 3211 3212
  original(item)
{
  quick_group= item->quick_group;
3213
  result.set_charset(collation.collation);
unknown's avatar
unknown committed
3214 3215
}

3216

unknown's avatar
SCRUM  
unknown committed
3217

unknown's avatar
unknown committed
3218 3219
void Item_func_group_concat::cleanup()
{
unknown's avatar
unknown committed
3220
  DBUG_ENTER("Item_func_group_concat::cleanup");
3221
  Item_sum::cleanup();
unknown's avatar
unknown committed
3222

3223 3224 3225 3226 3227
  /* Adjust warning message to include total number of cut values */
  if (warning)
  {
    char warn_buff[MYSQL_ERRMSG_SIZE];
    sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3228
    warning->set_msg(current_thd, warn_buff);
3229 3230 3231
    warning= 0;
  }

unknown's avatar
unknown committed
3232 3233 3234 3235 3236 3237
  /*
    Free table and tree if they belong to this item (if item have not pointer
    to original item from which was made copy => it own its objects )
  */
  if (!original)
  {
unknown's avatar
unknown committed
3238 3239
    delete tmp_table_param;
    tmp_table_param= 0;
unknown's avatar
unknown committed
3240
    if (table)
unknown's avatar
unknown committed
3241
    {
unknown's avatar
unknown committed
3242
      THD *thd= table->in_use;
unknown's avatar
unknown committed
3243
      free_tmp_table(thd, table);
unknown's avatar
unknown committed
3244
      table= 0;
unknown's avatar
unknown committed
3245 3246 3247 3248 3249
      if (tree)
      {
        delete_tree(tree);
        tree= 0;
      }
3250 3251 3252 3253 3254
      if (unique_filter)
      {
        delete unique_filter;
        unique_filter= NULL;
      }
unknown's avatar
unknown committed
3255 3256 3257 3258 3259 3260 3261
      if (warning)
      {
        char warn_buff[MYSQL_ERRMSG_SIZE];
        sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
        warning->set_msg(thd, warn_buff);
        warning= 0;
      }
unknown's avatar
unknown committed
3262
    }
3263
    DBUG_ASSERT(tree == 0 && warning == 0);
unknown's avatar
unknown committed
3264
  }
unknown's avatar
unknown committed
3265
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
3266 3267
}

unknown's avatar
unknown committed
3268

3269 3270
Item *Item_func_group_concat::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
3271
  return new (thd->mem_root) Item_func_group_concat(thd, this);
3272 3273 3274
}


3275
void Item_func_group_concat::clear()
3276 3277 3278
{
  result.length(0);
  result.copy();
unknown's avatar
SCRUM  
unknown committed
3279
  null_value= TRUE;
unknown's avatar
unknown committed
3280
  warning_for_row= FALSE;
3281
  no_appended= TRUE;
unknown's avatar
unknown committed
3282
  if (tree)
3283
    reset_tree(tree);
3284
  if (unique_filter)
3285
    unique_filter->reset();
unknown's avatar
unknown committed
3286
  /* No need to reset the table as we never call write_row */
3287 3288
}

unknown's avatar
SCRUM  
unknown committed
3289

3290 3291
bool Item_func_group_concat::add()
{
unknown's avatar
BUG  
unknown committed
3292 3293
  if (always_null)
    return 0;
3294 3295 3296
  copy_fields(tmp_table_param);
  copy_funcs(tmp_table_param->items_to_copy);

unknown's avatar
unknown committed
3297
  for (uint i= 0; i < arg_count_field; i++)
3298
  {
unknown's avatar
unknown committed
3299
    Item *show_item= args[i];
unknown's avatar
SCRUM  
unknown committed
3300
    if (!show_item->const_item())
3301
    {
unknown's avatar
unknown committed
3302 3303
      Field *f= show_item->get_tmp_table_field();
      if (f->is_null_in_record((const uchar*) table->record[0]))
unknown's avatar
unknown committed
3304
        return 0;                               // Skip row if it contains null
3305 3306
    }
  }
unknown's avatar
unknown committed
3307

unknown's avatar
SCRUM  
unknown committed
3308
  null_value= FALSE;
3309 3310 3311 3312 3313 3314 3315 3316 3317 3318
  bool row_eligible= TRUE;

  if (distinct) 
  {
    /* Filter out duplicate rows. */
    uint count= unique_filter->elements_in_tree();
    unique_filter->unique_add(table->record[0] + table->s->null_bytes);
    if (count == unique_filter->elements_in_tree())
      row_eligible= FALSE;
  }
3319 3320

  TREE_ELEMENT *el= 0;                          // Only for safety
3321
  if (row_eligible && tree)
unknown's avatar
unknown committed
3322 3323
    el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
                    tree->custom_arg);
3324 3325 3326 3327 3328
  /*
    If the row is not a duplicate (el->count == 1)
    we can dump the row here in case of GROUP_CONCAT(DISTINCT...)
    instead of doing tree traverse later.
  */
3329
  if (row_eligible && !warning_for_row &&
unknown's avatar
unknown committed
3330 3331
      (!tree || (el->count == 1 && distinct && !arg_count_order)))
    dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3332

3333 3334 3335
  return 0;
}

unknown's avatar
SCRUM  
unknown committed
3336

3337
bool
3338
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3339
{
unknown's avatar
unknown committed
3340
  uint i;                       /* for loop variable */
3341
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
3342

unknown's avatar
unknown committed
3343
  if (init_sum_func_check(thd))
unknown's avatar
unknown committed
3344
    return TRUE;
unknown's avatar
unknown committed
3345

3346
  maybe_null= 1;
unknown's avatar
unknown committed
3347

unknown's avatar
SCRUM  
unknown committed
3348
  /*
unknown's avatar
unknown committed
3349
    Fix fields for select list and ORDER clause
unknown's avatar
SCRUM  
unknown committed
3350
  */
unknown's avatar
unknown committed
3351

unknown's avatar
unknown committed
3352
  for (i=0 ; i < arg_count ; i++)
3353
  {
unknown's avatar
unknown committed
3354
    if ((!args[i]->fixed &&
3355
         args[i]->fix_fields(thd, args + i)) ||
unknown's avatar
unknown committed
3356
        args[i]->check_cols(1))
unknown's avatar
unknown committed
3357
      return TRUE;
3358
  }
unknown's avatar
unknown committed
3359

3360
  if (agg_item_charsets(collation, func_name(),
3361 3362 3363
                        args,
			/* skip charset aggregation for order columns */
			arg_count - arg_count_order,
3364
			MY_COLL_ALLOW_CONV, 1))
3365 3366
    return 1;

unknown's avatar
unknown committed
3367
  result.set_charset(collation.collation);
unknown's avatar
SCRUM  
unknown committed
3368 3369
  result_field= 0;
  null_value= 1;
unknown's avatar
unknown committed
3370
  max_length= thd->variables.group_concat_max_len;
unknown's avatar
unknown committed
3371

3372 3373 3374 3375 3376 3377 3378 3379 3380
  uint32 offset;
  if (separator->needs_conversion(separator->length(), separator->charset(),
                                  collation.collation, &offset))
  {
    uint32 buflen= collation.collation->mbmaxlen * separator->length();
    uint errors, conv_length;
    char *buf;
    String *new_separator;

unknown's avatar
unknown committed
3381
    if (!(buf= (char*) thd->stmt_arena->alloc(buflen)) ||
3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392
        !(new_separator= new(thd->stmt_arena->mem_root)
                           String(buf, buflen, collation.collation)))
      return TRUE;
    
    conv_length= copy_and_convert(buf, buflen, collation.collation,
                                  separator->ptr(), separator->length(),
                                  separator->charset(), &errors);
    new_separator->length(conv_length);
    separator= new_separator;
  }

unknown's avatar
unknown committed
3393 3394 3395
  if (check_sum_func(thd, ref))
    return TRUE;

3396
  memcpy (orig_args, args, sizeof (Item *) * arg_count);
3397
  fixed= 1;
unknown's avatar
unknown committed
3398
  return FALSE;
3399 3400
}

unknown's avatar
SCRUM  
unknown committed
3401

3402 3403 3404
bool Item_func_group_concat::setup(THD *thd)
{
  List<Item> list;
unknown's avatar
unknown committed
3405
  SELECT_LEX *select_lex= thd->lex->current_select;
unknown's avatar
unknown committed
3406
  DBUG_ENTER("Item_func_group_concat::setup");
3407

unknown's avatar
SCRUM  
unknown committed
3408
  /*
unknown's avatar
unknown committed
3409 3410
    Currently setup() can be called twice. Please add
    assertion here when this is fixed.
unknown's avatar
unknown committed
3411
  */
unknown's avatar
unknown committed
3412 3413 3414 3415 3416 3417 3418
  if (table || tree)
    DBUG_RETURN(FALSE);

  if (!(tmp_table_param= new TMP_TABLE_PARAM))
    DBUG_RETURN(TRUE);

  /* We'll convert all blobs to varchar fields in the temporary table */
unknown's avatar
unknown committed
3419 3420
  tmp_table_param->convert_blob_length= max_length *
                                        collation.collation->mbmaxlen;
unknown's avatar
unknown committed
3421
  /* Push all not constant fields to the list and create a temp table */
unknown's avatar
BUG  
unknown committed
3422
  always_null= 0;
unknown's avatar
unknown committed
3423
  for (uint i= 0; i < arg_count_field; i++)
3424
  {
unknown's avatar
SCRUM  
unknown committed
3425
    Item *item= args[i];
3426
    if (list.push_back(item))
unknown's avatar
unknown committed
3427
      DBUG_RETURN(TRUE);
3428 3429
    if (item->const_item())
    {
3430
      if (item->is_null())
unknown's avatar
unknown committed
3431 3432
      {
        always_null= 1;
unknown's avatar
unknown committed
3433
        DBUG_RETURN(FALSE);
unknown's avatar
unknown committed
3434
      }
3435 3436
    }
  }
unknown's avatar
unknown committed
3437

3438
  List<Item> all_fields(list);
unknown's avatar
unknown committed
3439 3440 3441 3442 3443 3444 3445
  /*
    Try to find every ORDER expression in the list of GROUP_CONCAT
    arguments. If an expression is not found, prepend it to
    "all_fields". The resulting field list is used as input to create
    tmp table columns.
  */
  if (arg_count_order &&
3446
      setup_order(thd, args, context->table_list, list, all_fields, *order))
unknown's avatar
unknown committed
3447
    DBUG_RETURN(TRUE);
unknown's avatar
unknown committed
3448

3449
  count_field_types(select_lex, tmp_table_param, all_fields, 0);
3450
  tmp_table_param->force_copy_fields= force_copy_fields;
unknown's avatar
unknown committed
3451
  DBUG_ASSERT(table == 0);
unknown's avatar
unknown committed
3452
  if (arg_count_order > 0 || distinct)
3453 3454 3455 3456 3457 3458 3459
  {
    /*
      Currently we have to force conversion of BLOB values to VARCHAR's
      if we are to store them in TREE objects used for ORDER BY and
      DISTINCT. This leads to truncation if the BLOB's size exceeds
      Field_varstring::MAX_SIZE.
    */
unknown's avatar
unknown committed
3460 3461
    set_if_smaller(tmp_table_param->convert_blob_length, 
                   Field_varstring::MAX_SIZE);
3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479

    /*
      Force the create_tmp_table() to convert BIT columns to INT
      as we cannot compare two table records containg BIT fields
      stored in the the tree used for distinct/order by.
      Moreover we don't even save in the tree record null bits 
      where BIT fields store parts of their data.
    */
    List_iterator_fast<Item> li(all_fields);
    Item *item;
    while ((item= li++))
    {
      if (item->type() == Item::FIELD_ITEM && 
          ((Item_field*) item)->field->type() == FIELD_TYPE_BIT)
        item->marker= 4;
    }
  }

unknown's avatar
SCRUM  
unknown committed
3480
  /*
unknown's avatar
unknown committed
3481
    We have to create a temporary table to get descriptions of fields
unknown's avatar
SCRUM  
unknown committed
3482
    (types, sizes and so on).
unknown's avatar
unknown committed
3483 3484 3485

    Note that in the table, we first have the ORDER BY fields, then the
    field list.
unknown's avatar
SCRUM  
unknown committed
3486
  */
unknown's avatar
unknown committed
3487 3488
  if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
                                (ORDER*) 0, 0, TRUE,
3489
                                (select_lex->options | thd->options),
unknown's avatar
unknown committed
3490 3491
                                HA_POS_ERROR, (char*) "")))
    DBUG_RETURN(TRUE);
3492
  table->file->extra(HA_EXTRA_NO_ROWS);
unknown's avatar
SCRUM  
unknown committed
3493
  table->no_rows= 1;
unknown's avatar
unknown committed
3494

3495 3496 3497 3498 3499 3500
  /*
     Need sorting or uniqueness: init tree and choose a function to sort.
     Don't reserve space for NULLs: if any of gconcat arguments is NULL,
     the row is not added to the result.
  */
  uint tree_key_length= table->s->reclength - table->s->null_bytes;
unknown's avatar
unknown committed
3501

3502
  if (arg_count_order)
3503
  {
unknown's avatar
unknown committed
3504
    tree= &tree_base;
unknown's avatar
SCRUM  
unknown committed
3505
    /*
3506 3507 3508
      Create a tree for sorting. The tree is used to sort (according to the
      syntax of this function). If there is no ORDER BY clause, we don't
      create this tree.
unknown's avatar
SCRUM  
unknown committed
3509
    */
3510 3511
    init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
                               thd->variables.sortbuff_size/16), 0,
3512 3513
              tree_key_length, 
              group_concat_key_cmp_with_order , 0, NULL, (void*) this);
3514
  }
unknown's avatar
unknown committed
3515

3516 3517 3518 3519 3520 3521
  if (distinct)
    unique_filter= new Unique(group_concat_key_cmp_with_distinct,
                              (void*)this,
                              tree_key_length,
                              thd->variables.max_heap_table_size);
  
unknown's avatar
unknown committed
3522
  DBUG_RETURN(FALSE);
3523 3524
}

unknown's avatar
unknown committed
3525

3526 3527 3528 3529
/* This is used by rollup to create a separate usable copy of the function */

void Item_func_group_concat::make_unique()
{
unknown's avatar
unknown committed
3530
  tmp_table_param= 0;
3531 3532
  table=0;
  original= 0;
3533
  force_copy_fields= 1;
unknown's avatar
unknown committed
3534
  tree= 0;
3535 3536 3537
}


3538 3539
String* Item_func_group_concat::val_str(String* str)
{
3540
  DBUG_ASSERT(fixed == 1);
unknown's avatar
SCRUM  
unknown committed
3541 3542
  if (null_value)
    return 0;
3543
  if (no_appended && tree)
3544 3545 3546
    /* Tree is used for sorting as in ORDER BY */
    tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
              left_root_right);
3547
  if (count_cut_values && !warning)
unknown's avatar
unknown committed
3548
  {
3549 3550 3551 3552
    /*
      ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in
      Item_func_group_concat::cleanup().
    */
unknown's avatar
unknown committed
3553 3554
    DBUG_ASSERT(table);
    warning= push_warning(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
3555 3556
                          ER_CUT_VALUE_GROUP_CONCAT,
                          ER(ER_CUT_VALUE_GROUP_CONCAT));
unknown's avatar
unknown committed
3557
  }
3558 3559
  return &result;
}
3560

unknown's avatar
unknown committed
3561

3562
void Item_func_group_concat::print(String *str, enum_query_type query_type)
3563
{
3564
  str->append(STRING_WITH_LEN("group_concat("));
3565
  if (distinct)
3566
    str->append(STRING_WITH_LEN("distinct "));
unknown's avatar
unknown committed
3567
  for (uint i= 0; i < arg_count_field; i++)
3568 3569 3570
  {
    if (i)
      str->append(',');
3571
    args[i]->print(str, query_type);
3572 3573 3574
  }
  if (arg_count_order)
  {
3575
    str->append(STRING_WITH_LEN(" order by "));
3576 3577 3578
    for (uint i= 0 ; i < arg_count_order ; i++)
    {
      if (i)
unknown's avatar
unknown committed
3579
        str->append(',');
3580
      (*order[i]->item)->print(str, query_type);
3581
      if (order[i]->asc)
3582
        str->append(STRING_WITH_LEN(" ASC"));
3583
      else
3584
        str->append(STRING_WITH_LEN(" DESC"));
3585 3586
    }
  }
3587
  str->append(STRING_WITH_LEN(" separator \'"));
3588
  str->append(*separator);
3589
  str->append(STRING_WITH_LEN("\')"));
3590
}
3591 3592 3593 3594


Item_func_group_concat::~Item_func_group_concat()
{
3595
  if (!original && unique_filter)
3596 3597
    delete unique_filter;    
}