item_sum.cc 83.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 17 18
   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 */


/* Sum functions (COUNT, MIN...) */

19
#ifdef USE_PRAGMA_IMPLEMENTATION
unknown's avatar
unknown committed
20 21 22 23
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
24
#include "sql_select.h"
unknown's avatar
unknown committed
25

unknown's avatar
unknown committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/* 
  Prepare an aggregate function item for checking context conditions

  SYNOPSIS
    init_sum_func_check()
    thd      reference to the thread context info

  DESCRIPTION
    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.

  NOTES
    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.
  
  RETURN
    TRUE   if an error is reported     
    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;
66
  aggr_sel= NULL;
unknown's avatar
unknown committed
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 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
  max_arg_level= -1;
  max_sum_func_level= -1;
  return FALSE;
}

/* 
  Check constraints imposed on a usage of a set function

  SYNOPSIS
    check_sum_func()
    thd      reference to the thread context info
    ref      location of the pointer to this item in the embedding expression 

  DESCRIPTION
    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.

  NOTES
    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.

  IMPLEMENTATION
    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:
      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);
    allow_sum_func will contain: 
    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.

  RETURN
    TRUE   if an error is reported     
    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
152 153
    if (!invalid && thd->variables.sql_mode & MODE_ANSI)
      invalid= aggr_level < 0 && max_arg_level < nest_level;
unknown's avatar
unknown committed
154 155
  }
  if (!invalid && aggr_level < 0)
156
  {
unknown's avatar
unknown committed
157
    aggr_level= nest_level;
158 159
    aggr_sel= thd->lex->current_select;
  }
unknown's avatar
unknown committed
160 161 162 163 164 165 166 167 168
  /*
    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
169 170 171
  */
  if (!invalid) 
    invalid= aggr_level <= max_sum_func_level;
unknown's avatar
unknown committed
172 173 174 175 176 177
  if (invalid)  
  {
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
               MYF(0));
    return TRUE;
  }
unknown's avatar
unknown committed
178
  if (in_sum_func)
unknown's avatar
unknown committed
179 180 181 182
  {
    /*
      If the set function is nested adjust the value of
      max_sum_func_level for the nesting set function.
unknown's avatar
unknown committed
183 184 185 186 187 188 189 190 191 192
      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
193
    */
unknown's avatar
unknown committed
194 195 196
    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
197
  }
unknown's avatar
unknown committed
198
  update_used_tables();
unknown's avatar
unknown committed
199 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
  thd->lex->in_sum_func= in_sum_func;
  return FALSE;
}

/* 
  Attach a set function to the subquery where it must be aggregated

  SYNOPSIS
    register_sum_func()
    thd      reference to the thread context info
    ref      location of the pointer to this item in the embedding expression
 
  DESCRIPTION
    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.

  NOTES.
    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.

  RETURN
    FALSE  if the executes without failures (currently always)
    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;
242
      aggr_sel= sl;
unknown's avatar
unknown committed
243 244 245 246 247 248 249 250 251 252
    }
  }
  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;
253 254
    aggr_sel= sl;

unknown's avatar
unknown committed
255 256 257 258
  }
  if (aggr_level >= 0)
  {
    ref_by= ref;
259 260
    /* 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
261 262 263
      next= this;
    else
    {
264 265
      next= aggr_sel->inner_sum_func_list->next;
      aggr_sel->inner_sum_func_list->next= this;
unknown's avatar
unknown committed
266
    }
267 268
    aggr_sel->inner_sum_func_list= this;
    aggr_sel->with_sum_func= 1;
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285

    /* 
      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; 
286
         sl && sl != aggr_sel && sl->master_unit()->item;
287 288
         sl= sl->master_unit()->outer_select() )
      sl->master_unit()->item->with_sum_func= 1;
unknown's avatar
unknown committed
289
  }
290
  thd->lex->current_select->mark_as_dependent(aggr_sel);
unknown's avatar
unknown committed
291 292 293 294
  return FALSE;
}


unknown's avatar
unknown committed
295 296
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), 
  forced_const(FALSE)
unknown's avatar
unknown committed
297 298 299 300
{
  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
  {
    uint i=0;
unknown's avatar
unknown committed
301
    List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
302 303 304 305 306 307 308
    Item *item;

    while ((item=li++))
    {
      args[i++]= item;
    }
  }
309
  mark_as_sum_func();
unknown's avatar
unknown committed
310 311 312
  list.empty();					// Fields are used
}

unknown's avatar
unknown committed
313 314 315 316 317

/*
  Constructor used in processing select with temporary tebles
*/

318
Item_sum::Item_sum(THD *thd, Item_sum *item):
unknown's avatar
unknown committed
319
  Item_result_field(thd, item), arg_count(item->arg_count),
320
  aggr_sel(item->aggr_sel),
unknown's avatar
unknown committed
321 322
  nest_level(item->nest_level), aggr_level(item->aggr_level),
  quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
323
  forced_const(item->forced_const) 
324 325 326 327
{
  if (arg_count <= 2)
    args=tmp_args;
  else
unknown's avatar
unknown committed
328
    if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
329
      return;
unknown's avatar
unknown committed
330 331 332 333
  memcpy(args, item->args, sizeof(Item*)*arg_count);
}


334
void Item_sum::mark_as_sum_func()
335
{
336 337 338
  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
339
  with_sum_func= 1;
340
}
unknown's avatar
unknown committed
341

342

unknown's avatar
unknown committed
343 344 345 346
void Item_sum::make_field(Send_field *tmp_field)
{
  if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
  {
347
    ((Item_field*) args[0])->field->make_field(tmp_field);
348 349 350 351 352 353 354
    /* 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;
355 356
    if (maybe_null)
      tmp_field->flags&= ~NOT_NULL_FLAG;
unknown's avatar
unknown committed
357
  }
358 359
  else
    init_make_field(tmp_field, field_type());
unknown's avatar
unknown committed
360 361
}

362

unknown's avatar
unknown committed
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
void Item_sum::print(String *str)
{
  str->append(func_name());
  for (uint i=0 ; i < arg_count ; i++)
  {
    if (i)
      str->append(',');
    args[i]->print(str);
  }
  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);
}

383
Item *Item_sum::get_tmp_table_item(THD *thd)
384
{
385
  Item_sum* sum_item= (Item_sum *) copy_or_same(thd);
386 387
  if (sum_item && sum_item->result_field)	   // If not a const sum func
  {
388
    Field *result_field_tmp= sum_item->result_field;
389 390 391 392 393 394
    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)
395
	  ((Item_field*) arg)->field= result_field_tmp++;
396
	else
397
	  sum_item->args[i]= new Item_field(result_field_tmp++);
398 399 400 401 402
      }
    }
  }
  return sum_item;
}
unknown's avatar
unknown committed
403

unknown's avatar
unknown committed
404

405 406 407 408 409 410 411 412 413 414 415 416 417 418
bool Item_sum::walk (Item_processor processor, byte *argument)
{
  if (arg_count)
  {
    Item **arg,**arg_end;
    for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
    {
      if ((*arg)->walk(processor, argument))
	return 1;
    }
  }
  return (this->*processor)(argument);
}

419

unknown's avatar
unknown committed
420 421 422 423 424
Field *Item_sum::create_tmp_field(bool group, TABLE *table,
                                  uint convert_blob_length)
{
  switch (result_type()) {
  case REAL_RESULT:
unknown's avatar
unknown committed
425 426
    return new Field_double(max_length, maybe_null, name, table, decimals, 
                            TRUE);
unknown's avatar
unknown committed
427 428 429
  case INT_RESULT:
    return new Field_longlong(max_length,maybe_null,name,table,unsigned_flag);
  case STRING_RESULT:
430 431 432 433 434
    /* 
      Make sure that the blob fits into a Field_varstring which has 
      2-byte lenght. 
    */
    if (max_length/collation.collation->mbmaxlen > 255 && 
unknown's avatar
unknown committed
435
        convert_blob_length <= Field_varstring::MAX_SIZE && convert_blob_length)
unknown's avatar
unknown committed
436 437 438 439
      return new Field_varstring(convert_blob_length, maybe_null,
                                 name, table,
                                 collation.collation);
    return make_string_field(table);
unknown's avatar
unknown committed
440
case DECIMAL_RESULT:
unknown's avatar
unknown committed
441 442
    return new Field_new_decimal(max_length, maybe_null, name, table,
                                 decimals, unsigned_flag);
unknown's avatar
unknown committed
443 444 445 446 447 448 449 450 451
  case ROW_RESULT:
  default:
    // This case should never be choosen
    DBUG_ASSERT(0);
    return 0;
  }
}


unknown's avatar
unknown committed
452 453 454 455 456 457 458 459 460 461 462 463 464 465
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();
    }

    used_tables_cache&= PSEUDO_TABLE_BITS;

    /* the aggregate function is aggregated into its local context */
466
    used_tables_cache |=  (1 << aggr_sel->join->tables) - 1;
unknown's avatar
unknown committed
467 468 469 470
  }
}


unknown's avatar
unknown committed
471 472 473
String *
Item_sum_num::val_str(String *str)
{
474
  return val_string_from_real(str);
unknown's avatar
unknown committed
475 476 477
}


unknown's avatar
unknown committed
478 479
my_decimal *Item_sum_num::val_decimal(my_decimal *decimal_value)
{
480
  return val_decimal_from_real(decimal_value);
unknown's avatar
unknown committed
481 482 483
}


unknown's avatar
unknown committed
484 485 486
String *
Item_sum_int::val_str(String *str)
{
487 488 489 490 491 492 493
  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
494 495 496 497
}


bool
498
Item_sum_num::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
499
{
500
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
501

unknown's avatar
unknown committed
502
  if (init_sum_func_check(thd))
unknown's avatar
unknown committed
503
    return TRUE;
unknown's avatar
unknown committed
504

unknown's avatar
unknown committed
505 506 507 508
  decimals=0;
  maybe_null=0;
  for (uint i=0 ; i < arg_count ; i++)
  {
509
    if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
unknown's avatar
unknown committed
510
      return TRUE;
unknown's avatar
unknown committed
511
    set_if_bigger(decimals, args[i]->decimals);
unknown's avatar
unknown committed
512 513 514 515 516 517
    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
518 519 520 521

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

522
  fixed= 1;
unknown's avatar
unknown committed
523
  return FALSE;
unknown's avatar
unknown committed
524 525 526
}


unknown's avatar
unknown committed
527 528 529
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
530
  was_values(item->was_values)
unknown's avatar
unknown committed
531
{
532 533
  /* copy results from old value */
  switch (hybrid_type) {
unknown's avatar
unknown committed
534 535 536 537 538 539 540 541 542
  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
543 544 545 546 547 548
  case STRING_RESULT:
    /*
      This can happen with ROLLUP. Note that the value is already
      copied at function call.
    */
    break;
unknown's avatar
unknown committed
549 550 551 552 553 554 555
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
  }
  collation.set(item->collation);
}

unknown's avatar
unknown committed
556
bool
557
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
558
{
559
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
560

561
  Item *item= args[0];
unknown's avatar
unknown committed
562 563

  if (init_sum_func_check(thd))
unknown's avatar
unknown committed
564
    return TRUE;
565 566

  // 'item' can be changed during fix_fields
567
  if (!item->fixed &&
568
      item->fix_fields(thd, args) ||
569
      (item= args[0])->check_cols(1))
unknown's avatar
unknown committed
570
    return TRUE;
unknown's avatar
unknown committed
571
  decimals=item->decimals;
572

573
  switch (hybrid_type= item->result_type()) {
unknown's avatar
unknown committed
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
  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);
  };
593 594
  /* MIN/MAX can return NULL for empty set indepedent of the used column */
  maybe_null= 1;
595
  unsigned_flag=item->unsigned_flag;
596
  collation.set(item->collation);
unknown's avatar
unknown committed
597 598 599
  result_field=0;
  null_value=1;
  fix_length_and_dec();
600 601 602 603
  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
604 605 606 607

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

608
  fixed= 1;
unknown's avatar
unknown committed
609
  return FALSE;
unknown's avatar
unknown committed
610 611
}

612 613 614 615 616 617 618
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
					 uint convert_blob_length)
{
  if (args[0]->type() == Item::FIELD_ITEM)
  {
    Field *field= ((Item_field*) args[0])->field;
    
unknown's avatar
unknown committed
619 620
    if ((field= create_tmp_field_from_field(current_thd, field, name, table,
					    NULL, convert_blob_length)))
621 622 623
      field->flags&= ~NOT_NULL_FLAG;
    return field;
  }
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
  /*
    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:
    return new Field_date(maybe_null, name, table, collation.collation);
  case MYSQL_TYPE_TIME:
    return new Field_time(maybe_null, name, table, collation.collation);
  case MYSQL_TYPE_TIMESTAMP:
  case MYSQL_TYPE_DATETIME:
    return new Field_datetime(maybe_null, name, table, collation.collation);
  default:
    break;
  }
640 641 642
  return Item_sum::create_tmp_field(group, table, convert_blob_length);
}

unknown's avatar
unknown committed
643 644 645 646 647

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

unknown's avatar
unknown committed
648 649 650 651
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)
{
652
  /* TODO: check if the following assignments are really needed */
unknown's avatar
unknown committed
653 654 655 656 657 658 659 660 661
  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;
}

662
Item *Item_sum_sum::copy_or_same(THD* thd)
unknown's avatar
unknown committed
663
{
unknown's avatar
unknown committed
664
  return new (thd->mem_root) Item_sum_sum(thd, this);
unknown's avatar
unknown committed
665 666
}

667

668
void Item_sum_sum::clear()
669
{
unknown's avatar
unknown committed
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
  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;
688
  switch (args[0]->result_type()) {
unknown's avatar
unknown committed
689 690 691 692 693 694 695
  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
696
  {
unknown's avatar
unknown committed
697
    /* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
unknown's avatar
unknown committed
698 699 700
    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
701 702 703 704
    curr_dec_buff= 0;
    hybrid_type= DECIMAL_RESULT;
    my_decimal_set_zero(dec_buffs);
    break;
unknown's avatar
unknown committed
705
  }
unknown's avatar
unknown committed
706 707 708 709 710 711 712 713 714 715 716 717
  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;
718 719 720
}


unknown's avatar
unknown committed
721 722
bool Item_sum_sum::add()
{
unknown's avatar
unknown committed
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
  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;
  }
755
  return (longlong) rint(val_real());
unknown's avatar
unknown committed
756 757
}

758

759
double Item_sum_sum::val_real()
unknown's avatar
unknown committed
760
{
761
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
762 763
  if (hybrid_type == DECIMAL_RESULT)
    my_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum);
unknown's avatar
unknown committed
764 765 766 767
  return sum;
}


768
String *Item_sum_sum::val_str(String *str)
unknown's avatar
unknown committed
769 770
{
  if (hybrid_type == DECIMAL_RESULT)
771 772
    return val_string_from_decimal(str);
  return val_string_from_real(str);
unknown's avatar
unknown committed
773 774 775 776 777
}


my_decimal *Item_sum_sum::val_decimal(my_decimal *val)
{
778 779 780
  if (hybrid_type == DECIMAL_RESULT)
    return (dec_buffs + curr_dec_buff);
  return val_decimal_from_real(val);
unknown's avatar
unknown committed
781 782
}

783
/***************************************************************************/
784

785 786 787
C_MODE_START

/* Declarations for auxilary C-callbacks */
788

789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806
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)
{
    return ((Item_sum_distinct*) (item))->unique_walk_function(element);
}

C_MODE_END

/* Item_sum_distinct */

Item_sum_distinct::Item_sum_distinct(Item *item_arg)
  :Item_sum_num(item_arg), tree(0)
807 808 809 810 811 812 813 814 815 816 817
{
  /*
    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;
}


818 819 820
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)
821 822 823 824 825
{
  quick_group= 0;
}


826 827 828 829 830 831 832 833 834
/*
  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
835
{
836 837 838 839 840
  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
841
  {
842 843 844 845
    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
846
  }
unknown's avatar
unknown committed
847
  static const Hybrid_type_traits_fast_decimal *instance();
848
  Hybrid_type_traits_fast_decimal() {};
849
};
unknown's avatar
unknown committed
850

unknown's avatar
unknown committed
851 852 853 854 855 856 857
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
858

859
void Item_sum_distinct::fix_length_and_dec()
860
{
861
  DBUG_ASSERT(args[0]->fixed);
862

863
  table_field_type= args[0]->field_type();
864

865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
  /* 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 ||
      table_field_type >= MYSQL_TYPE_TINY &&
      table_field_type <= MYSQL_TYPE_LONG)
  {
    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]);
900 901 902
}


903
bool Item_sum_distinct::setup(THD *thd)
904
{
905 906 907
  List<create_field> field_list;
  create_field field_def;                              /* field definition */
  DBUG_ENTER("Item_sum_distinct::setup");
unknown's avatar
unknown committed
908
  DBUG_ASSERT(tree == 0);
909 910

  /*
911 912 913
    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.
914
  */
915 916 917
  if (field_list.push_back(&field_def))
    return TRUE;

918
  null_value= maybe_null= 1;
919 920 921 922 923 924 925 926 927
  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
928
    return TRUE;
929 930 931

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

  /*
934 935 936 937
    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.
938
  */
939
  tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
940 941
                   thd->variables.max_heap_table_size);

942
  is_evaluated= FALSE;
943
  DBUG_RETURN(tree == 0);
944 945 946
}


947
bool Item_sum_distinct::add()
948
{
949
  args[0]->save_in_field(table->field[0], FALSE);
950
  is_evaluated= FALSE;
951
  if (!table->field[0]->is_null())
952
  {
953 954 955 956 957 958 959
    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);
960
  }
961
  return 0;
unknown's avatar
unknown committed
962 963 964
}


965
bool Item_sum_distinct::unique_walk_function(void *element)
unknown's avatar
unknown committed
966
{
967 968 969 970
  memcpy(table->field[0]->ptr, element, tree_key_length);
  ++count;
  val.traits->add(&val, table->field[0]);
  return 0;
unknown's avatar
unknown committed
971 972 973
}


974
void Item_sum_distinct::clear()
unknown's avatar
unknown committed
975
{
976 977 978 979
  DBUG_ENTER("Item_sum_distinct::clear");
  DBUG_ASSERT(tree != 0);                        /* we always have a tree */
  null_value= 1;
  tree->reset();
980
  is_evaluated= FALSE;
981
  DBUG_VOID_RETURN;
982 983
}

984 985 986 987 988 989
void Item_sum_distinct::cleanup()
{
  Item_sum_num::cleanup();
  delete tree;
  tree= 0;
  table= 0;
990
  is_evaluated= FALSE;
unknown's avatar
unknown committed
991 992
}

993 994 995 996
Item_sum_distinct::~Item_sum_distinct()
{
  delete tree;
  /* no need to free the table */
997 998
}

999

1000
void Item_sum_distinct::calculate_val_and_count()
1001
{
1002
  if (!is_evaluated)
unknown's avatar
unknown committed
1003
  {
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
    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
1016
  }
1017 1018
}

unknown's avatar
unknown committed
1019

1020
double Item_sum_distinct::val_real()
unknown's avatar
unknown committed
1021
{
1022 1023
  calculate_val_and_count();
  return val.traits->val_real(&val);
unknown's avatar
unknown committed
1024 1025 1026
}


1027
my_decimal *Item_sum_distinct::val_decimal(my_decimal *to)
unknown's avatar
unknown committed
1028
{
1029 1030 1031 1032
  calculate_val_and_count();
  if (null_value)
    return 0;
  return val.traits->val_decimal(&val, to);
unknown's avatar
unknown committed
1033 1034 1035
}


1036
longlong Item_sum_distinct::val_int()
unknown's avatar
unknown committed
1037
{
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
  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
1049 1050
}

1051 1052 1053 1054
/* end of Item_sum_distinct */

/* Item_sum_avg_distinct */

1055 1056 1057 1058
void
Item_sum_avg_distinct::fix_length_and_dec()
{
  Item_sum_distinct::fix_length_and_dec();
unknown's avatar
unknown committed
1059
  prec_increment= current_thd->variables.div_precincrement;
1060 1061 1062 1063
  /*
    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
1064
  decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
1065 1066 1067
}


1068 1069 1070
void
Item_sum_avg_distinct::calculate_val_and_count()
{
1071 1072 1073 1074 1075 1076 1077
  if (!is_evaluated)
  {
    Item_sum_distinct::calculate_val_and_count();
    if (count)
      val.traits->div(&val, count);
    is_evaluated= TRUE;
  }
1078
}
unknown's avatar
unknown committed
1079

1080

1081
Item *Item_sum_count::copy_or_same(THD* thd)
unknown's avatar
unknown committed
1082
{
unknown's avatar
unknown committed
1083
  return new (thd->mem_root) Item_sum_count(thd, this);
unknown's avatar
unknown committed
1084 1085
}

1086

1087
void Item_sum_count::clear()
1088
{
1089
  count= 0;
1090 1091 1092
}


unknown's avatar
unknown committed
1093 1094
bool Item_sum_count::add()
{
1095
  if (!args[0]->maybe_null || !args[0]->is_null())
unknown's avatar
unknown committed
1096 1097 1098 1099 1100 1101
    count++;
  return 0;
}

longlong Item_sum_count::val_int()
{
1102
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1103 1104 1105
  return (longlong) count;
}

1106 1107 1108 1109

void Item_sum_count::cleanup()
{
  DBUG_ENTER("Item_sum_count::cleanup");
1110
  count= 0;
1111 1112 1113 1114 1115
  Item_sum_int::cleanup();
  DBUG_VOID_RETURN;
}


unknown's avatar
unknown committed
1116
/*
1117
  Avgerage
unknown's avatar
unknown committed
1118
*/
unknown's avatar
unknown committed
1119 1120 1121 1122
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
1123
  prec_increment= current_thd->variables.div_precincrement;
unknown's avatar
unknown committed
1124 1125
  if (hybrid_type == DECIMAL_RESULT)
  {
unknown's avatar
unknown committed
1126 1127 1128 1129 1130 1131
    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
1132 1133
    dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
  }
1134
  else {
unknown's avatar
unknown committed
1135
    decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
1136 1137
    max_length= args[0]->max_length + prec_increment;
  }
unknown's avatar
unknown committed
1138 1139
}

unknown's avatar
unknown committed
1140

1141
Item *Item_sum_avg::copy_or_same(THD* thd)
unknown's avatar
unknown committed
1142
{
unknown's avatar
unknown committed
1143
  return new (thd->mem_root) Item_sum_avg(thd, this);
unknown's avatar
unknown committed
1144 1145
}

1146

unknown's avatar
unknown committed
1147 1148 1149
Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table,
                                      uint convert_blob_len)
{
1150
  if (group)
unknown's avatar
unknown committed
1151
  {
1152 1153
    /*
      We must store both value and counter in the temporary table in one field.
1154
      The easiest way is to do this is to store both value in a string
1155 1156 1157 1158 1159
      and unpack on access.
    */
    return new Field_string(((hybrid_type == DECIMAL_RESULT) ?
                             dec_bin_size : sizeof(double)) + sizeof(longlong),
                            0, name, table, &my_charset_bin);
unknown's avatar
unknown committed
1160
  }
1161
  if (hybrid_type == DECIMAL_RESULT)
unknown's avatar
unknown committed
1162 1163
    return new Field_new_decimal(max_length, maybe_null, name, table,
                                 decimals, unsigned_flag);
unknown's avatar
unknown committed
1164
  return new Field_double(max_length, maybe_null, name, table, decimals, TRUE);
unknown's avatar
unknown committed
1165 1166 1167
}


1168
void Item_sum_avg::clear()
1169
{
unknown's avatar
unknown committed
1170 1171
  Item_sum_sum::clear();
  count=0;
1172 1173 1174
}


unknown's avatar
unknown committed
1175 1176
bool Item_sum_avg::add()
{
unknown's avatar
unknown committed
1177 1178
  if (Item_sum_sum::add())
    return TRUE;
unknown's avatar
unknown committed
1179 1180
  if (!args[0]->null_value)
    count++;
unknown's avatar
unknown committed
1181
  return FALSE;
unknown's avatar
unknown committed
1182 1183
}

1184
double Item_sum_avg::val_real()
unknown's avatar
unknown committed
1185
{
1186
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1187 1188 1189 1190 1191
  if (!count)
  {
    null_value=1;
    return 0.0;
  }
unknown's avatar
unknown committed
1192 1193 1194 1195 1196 1197
  return Item_sum_sum::val_real() / ulonglong2double(count);
}


my_decimal *Item_sum_avg::val_decimal(my_decimal *val)
{
1198
  my_decimal sum_buff, cnt;
1199
  const my_decimal *sum_dec;
unknown's avatar
unknown committed
1200 1201 1202 1203 1204 1205
  DBUG_ASSERT(fixed == 1);
  if (!count)
  {
    null_value=1;
    return NULL;
  }
1206
  sum_dec= Item_sum_sum::val_decimal(&sum_buff);
unknown's avatar
unknown committed
1207
  int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &cnt);
unknown's avatar
unknown committed
1208
  my_decimal_div(E_DEC_FATAL_ERROR, val, sum_dec, &cnt, prec_increment);
unknown's avatar
unknown committed
1209 1210 1211 1212 1213 1214 1215
  return val;
}


String *Item_sum_avg::val_str(String *str)
{
  if (hybrid_type == DECIMAL_RESULT)
1216 1217
    return val_string_from_decimal(str);
  return val_string_from_real(str);
unknown's avatar
unknown committed
1218 1219 1220 1221
}


/*
1222
  Standard deviation
unknown's avatar
unknown committed
1223 1224
*/

1225
double Item_sum_std::val_real()
unknown's avatar
unknown committed
1226
{
1227
  DBUG_ASSERT(fixed == 1);
1228 1229 1230
  double nr= Item_sum_variance::val_real();
  DBUG_ASSERT(nr >= 0.0);
  return sqrt(nr);
unknown's avatar
unknown committed
1231 1232
}

1233 1234
Item *Item_sum_std::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1235
  return new (thd->mem_root) Item_sum_std(thd, this);
1236 1237 1238
}


unknown's avatar
unknown committed
1239
/*
1240
  Variance
unknown's avatar
unknown committed
1241 1242
*/

unknown's avatar
unknown committed
1243

1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
/**
  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
1257
{
1258 1259 1260
  *count += 1;

  if (*count == 1) 
unknown's avatar
unknown committed
1261
  {
1262 1263
    *m= nr;
    *s= 0;
unknown's avatar
unknown committed
1264 1265 1266
  }
  else
  {
1267 1268 1269
    double m_kminusone= *m;
    *m= m_kminusone + (nr - m_kminusone) / (double) *count;
    *s= *s + (nr - m_kminusone) * (nr - *m);
unknown's avatar
unknown committed
1270 1271 1272 1273
  }
}


1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
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
1297 1298
void Item_sum_variance::fix_length_and_dec()
{
1299 1300
  DBUG_ENTER("Item_sum_variance::fix_length_and_dec");
  maybe_null= null_value= 1;
unknown's avatar
unknown committed
1301
  prec_increment= current_thd->variables.div_precincrement;
1302 1303 1304 1305 1306 1307 1308 1309 1310

  /*
    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;

1311
  switch (args[0]->result_type()) {
unknown's avatar
unknown committed
1312 1313
  case REAL_RESULT:
  case STRING_RESULT:
unknown's avatar
unknown committed
1314
    decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
unknown's avatar
unknown committed
1315 1316 1317
    break;
  case INT_RESULT:
  case DECIMAL_RESULT:
unknown's avatar
unknown committed
1318 1319 1320 1321 1322
  {
    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);
1323

unknown's avatar
unknown committed
1324
    break;
unknown's avatar
unknown committed
1325
  }
unknown's avatar
unknown committed
1326 1327 1328 1329
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
  }
1330
  DBUG_PRINT("info", ("Type: REAL_RESULT (%d, %d)", max_length, (int)decimals));
unknown's avatar
unknown committed
1331 1332 1333 1334
  DBUG_VOID_RETURN;
}


1335 1336
Item *Item_sum_variance::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1337
  return new (thd->mem_root) Item_sum_variance(thd, this);
1338 1339 1340
}


1341 1342 1343 1344 1345
/**
  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
1346 1347 1348
Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table,
                                           uint convert_blob_len)
{
1349
  if (group)
unknown's avatar
unknown committed
1350
  {
1351 1352
    /*
      We must store both value and counter in the temporary table in one field.
1353
      The easiest way is to do this is to store both value in a string
1354 1355
      and unpack on access.
    */
1356
    return new Field_string(sizeof(double)*2 + sizeof(longlong), 0, name, table, &my_charset_bin);
unknown's avatar
unknown committed
1357
  }
unknown's avatar
unknown committed
1358
  return new Field_double(max_length, maybe_null, name, table, decimals, TRUE);
unknown's avatar
unknown committed
1359 1360 1361
}


1362
void Item_sum_variance::clear()
unknown's avatar
unknown committed
1363
{
1364
  count= 0; 
unknown's avatar
unknown committed
1365 1366 1367
}

bool Item_sum_variance::add()
unknown's avatar
unknown committed
1368
{
1369 1370 1371 1372 1373 1374 1375 1376
  /* 
    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
1377 1378 1379
  return 0;
}

1380
double Item_sum_variance::val_real()
unknown's avatar
unknown committed
1381
{
1382
  DBUG_ASSERT(fixed == 1);
1383

1384 1385 1386 1387 1388 1389 1390 1391 1392 1393
  /*
    '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));
1394
  if (count <= sample)
unknown's avatar
unknown committed
1395 1396 1397 1398
  {
    null_value=1;
    return 0.0;
  }
1399

unknown's avatar
unknown committed
1400
  null_value=0;
1401
  return variance_fp_recurrence_result(recurrence_s, count, sample);
unknown's avatar
unknown committed
1402 1403 1404 1405 1406
}


my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf)
{
1407 1408
  DBUG_ASSERT(fixed == 1);
  return val_decimal_from_real(dec_buf);
unknown's avatar
unknown committed
1409 1410
}

1411

unknown's avatar
unknown committed
1412 1413
void Item_sum_variance::reset_field()
{
1414 1415 1416
  double nr;
  char *res= result_field->ptr;

1417
  nr= args[0]->val_real();              /* sets null_value as side-effect */
unknown's avatar
unknown committed
1418 1419 1420 1421 1422

  if (args[0]->null_value)
    bzero(res,sizeof(double)*2+sizeof(longlong));
  else
  {
1423 1424 1425 1426 1427 1428 1429 1430
    /* 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
1431 1432 1433
  }
}

1434

unknown's avatar
unknown committed
1435
void Item_sum_variance::update_field()
unknown's avatar
unknown committed
1436
{
1437
  ulonglong field_count;
unknown's avatar
unknown committed
1438
  char *res=result_field->ptr;
1439 1440 1441 1442

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

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

1445 1446 1447 1448
  /* 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
1449
  field_count=sint8korr(res+sizeof(double)*2);
unknown's avatar
unknown committed
1450

1451 1452 1453 1454
  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);
1455 1456
  res+= sizeof(double)*2;
  int8store(res,field_count);
unknown's avatar
unknown committed
1457 1458
}

1459

unknown's avatar
unknown committed
1460 1461
/* min & max */

1462 1463
void Item_sum_hybrid::clear()
{
1464
  switch (hybrid_type) {
unknown's avatar
unknown committed
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476
  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);
  }
1477 1478 1479
  null_value= 1;
}

1480
double Item_sum_hybrid::val_real()
unknown's avatar
unknown committed
1481
{
1482
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1483 1484
  if (null_value)
    return 0.0;
1485 1486
  switch (hybrid_type) {
  case STRING_RESULT:
1487 1488 1489
  {
    char *end_not_used;
    int err_not_used;
unknown's avatar
unknown committed
1490
    String *res;  res=val_str(&str_value);
1491 1492 1493
    return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
			     &end_not_used, &err_not_used) : 0.0);
  }
1494 1495 1496 1497
  case INT_RESULT:
    if (unsigned_flag)
      return ulonglong2double(sum_int);
    return (double) sum_int;
unknown's avatar
unknown committed
1498 1499 1500
  case DECIMAL_RESULT:
    my_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
    return sum;
1501 1502
  case REAL_RESULT:
    return sum;
1503
  case ROW_RESULT:
unknown's avatar
unknown committed
1504
  default:
unknown's avatar
unknown committed
1505 1506 1507
    // This case should never be choosen
    DBUG_ASSERT(0);
    return 0;
unknown's avatar
unknown committed
1508
  }
1509 1510 1511 1512
}

longlong Item_sum_hybrid::val_int()
{
1513
  DBUG_ASSERT(fixed == 1);
1514 1515
  if (null_value)
    return 0;
1516
  switch (hybrid_type) {
unknown's avatar
unknown committed
1517 1518 1519 1520 1521 1522
  case INT_RESULT:
    return sum_int;
  case DECIMAL_RESULT:
  {
    longlong result;
    my_decimal2int(E_DEC_FATAL_ERROR, &sum_dec, unsigned_flag, &result);
1523
    return sum_int;
unknown's avatar
unknown committed
1524 1525
  }
  default:
1526
    return (longlong) rint(Item_sum_hybrid::val_real());
unknown's avatar
unknown committed
1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555
  }
}


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
1556 1557 1558 1559 1560 1561
}


String *
Item_sum_hybrid::val_str(String *str)
{
1562
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1563 1564
  if (null_value)
    return 0;
1565 1566
  switch (hybrid_type) {
  case STRING_RESULT:
unknown's avatar
unknown committed
1567
    return &value;
1568
  case REAL_RESULT:
unknown's avatar
unknown committed
1569
    str->set(sum,decimals, &my_charset_bin);
1570
    break;
unknown's avatar
unknown committed
1571 1572 1573
  case DECIMAL_RESULT:
    my_decimal2string(E_DEC_FATAL_ERROR, &sum_dec, 0, 0, 0, str);
    return str;
1574 1575
  case INT_RESULT:
    if (unsigned_flag)
unknown's avatar
unknown committed
1576
      str->set((ulonglong) sum_int, &my_charset_bin);
1577
    else
unknown's avatar
unknown committed
1578
      str->set((longlong) sum_int, &my_charset_bin);
1579
    break;
1580
  case ROW_RESULT:
unknown's avatar
unknown committed
1581
  default:
unknown's avatar
unknown committed
1582 1583 1584
    // This case should never be choosen
    DBUG_ASSERT(0);
    break;
1585 1586
  }
  return str;					// Keep compiler happy
unknown's avatar
unknown committed
1587 1588
}

1589

1590 1591 1592 1593
void Item_sum_hybrid::cleanup()
{
  DBUG_ENTER("Item_sum_hybrid::cleanup");
  Item_sum::cleanup();
unknown's avatar
unknown committed
1594
  forced_const= FALSE;
unknown's avatar
unknown committed
1595

1596
  /*
unknown's avatar
unknown committed
1597
    by default it is TRUE to avoid TRUE reporting by
1598 1599 1600
    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
1601
    If some results found it will be left unchanged.
1602 1603
  */
  was_values= TRUE;
1604 1605 1606
  DBUG_VOID_RETURN;
}

1607 1608 1609
void Item_sum_hybrid::no_rows_in_result()
{
  was_values= FALSE;
1610
  clear();
1611 1612
}

1613

1614 1615
Item *Item_sum_min::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1616
  return new (thd->mem_root) Item_sum_min(thd, this);
1617 1618 1619
}


unknown's avatar
unknown committed
1620 1621
bool Item_sum_min::add()
{
1622 1623
  switch (hybrid_type) {
  case STRING_RESULT:
unknown's avatar
unknown committed
1624 1625 1626
  {
    String *result=args[0]->val_str(&tmp_value);
    if (!args[0]->null_value &&
1627
	(null_value || sortcmp(&value,result,collation.collation) > 0))
unknown's avatar
unknown committed
1628 1629 1630 1631 1632
    {
      value.copy(*result);
      null_value=0;
    }
  }
1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646
  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
1647 1648
  case DECIMAL_RESULT:
  {
1649
    my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
unknown's avatar
unknown committed
1650 1651 1652 1653 1654 1655 1656 1657
    if (!args[0]->null_value &&
        (null_value || (my_decimal_cmp(&sum_dec, val) > 0)))
    {
      my_decimal2decimal(val, &sum_dec);
      null_value= 0;
    }
  }
  break;
1658
  case REAL_RESULT:
unknown's avatar
unknown committed
1659
  {
1660
    double nr= args[0]->val_real();
1661
    if (!args[0]->null_value && (null_value || nr < sum))
unknown's avatar
unknown committed
1662 1663 1664 1665 1666
    {
      sum=nr;
      null_value=0;
    }
  }
1667
  break;
1668
  case ROW_RESULT:
unknown's avatar
unknown committed
1669
  default:
unknown's avatar
unknown committed
1670 1671 1672
    // This case should never be choosen
    DBUG_ASSERT(0);
    break;
1673 1674 1675 1676 1677
  }
  return 0;
}


1678 1679
Item *Item_sum_max::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1680
  return new (thd->mem_root) Item_sum_max(thd, this);
1681 1682 1683
}


1684 1685 1686 1687
bool Item_sum_max::add()
{
  switch (hybrid_type) {
  case STRING_RESULT:
unknown's avatar
unknown committed
1688 1689 1690
  {
    String *result=args[0]->val_str(&tmp_value);
    if (!args[0]->null_value &&
1691
	(null_value || sortcmp(&value,result,collation.collation) < 0))
unknown's avatar
unknown committed
1692 1693 1694 1695 1696
    {
      value.copy(*result);
      null_value=0;
    }
  }
1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710
  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
1711 1712
  case DECIMAL_RESULT:
  {
1713
    my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
unknown's avatar
unknown committed
1714 1715 1716 1717 1718 1719 1720 1721
    if (!args[0]->null_value &&
        (null_value || (my_decimal_cmp(val, &sum_dec) > 0)))
    {
      my_decimal2decimal(val, &sum_dec);
      null_value= 0;
    }
  }
  break;
1722 1723
  case REAL_RESULT:
  {
1724
    double nr= args[0]->val_real();
1725 1726 1727 1728 1729 1730 1731
    if (!args[0]->null_value && (null_value || nr > sum))
    {
      sum=nr;
      null_value=0;
    }
  }
  break;
1732
  case ROW_RESULT:
unknown's avatar
unknown committed
1733
  default:
unknown's avatar
unknown committed
1734 1735 1736
    // This case should never be choosen
    DBUG_ASSERT(0);
    break;
1737
  }
unknown's avatar
unknown committed
1738 1739 1740 1741 1742 1743 1744 1745
  return 0;
}


/* bit_or and bit_and */

longlong Item_sum_bit::val_int()
{
1746
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1747 1748 1749
  return (longlong) bits;
}

1750

1751
void Item_sum_bit::clear()
1752
{
1753
  bits= reset_bits;
1754 1755 1756
}

Item *Item_sum_or::copy_or_same(THD* thd)
unknown's avatar
unknown committed
1757
{
unknown's avatar
unknown committed
1758
  return new (thd->mem_root) Item_sum_or(thd, this);
unknown's avatar
unknown committed
1759 1760
}

1761

unknown's avatar
unknown committed
1762 1763 1764 1765 1766 1767 1768 1769
bool Item_sum_or::add()
{
  ulonglong value= (ulonglong) args[0]->val_int();
  if (!args[0]->null_value)
    bits|=value;
  return 0;
}

1770 1771
Item *Item_sum_xor::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1772
  return new (thd->mem_root) Item_sum_xor(thd, this);
1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783
}


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

1784 1785
Item *Item_sum_and::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
1786
  return new (thd->mem_root) Item_sum_and(thd, this);
1787 1788 1789
}


unknown's avatar
unknown committed
1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803
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()
{
1804
  double nr= args[0]->val_real();
unknown's avatar
unknown committed
1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822
  char *res=result_field->ptr;

  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()
{
1823
  switch(hybrid_type) {
unknown's avatar
unknown committed
1824
  case STRING_RESULT:
unknown's avatar
unknown committed
1825 1826
  {
    char buff[MAX_FIELD_WIDTH];
1827
    String tmp(buff,sizeof(buff),result_field->charset()),*res;
unknown's avatar
unknown committed
1828 1829 1830 1831 1832 1833 1834 1835 1836 1837

    res=args[0]->val_str(&tmp);
    if (args[0]->null_value)
    {
      result_field->set_null();
      result_field->reset();
    }
    else
    {
      result_field->set_notnull();
1838
      result_field->store(res->ptr(),res->length(),tmp.charset());
unknown's avatar
unknown committed
1839
    }
unknown's avatar
unknown committed
1840
    break;
unknown's avatar
unknown committed
1841
  }
unknown's avatar
unknown committed
1842
  case INT_RESULT:
unknown's avatar
unknown committed
1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855
  {
    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();
    }
1856
    result_field->store(nr, unsigned_flag);
unknown's avatar
unknown committed
1857
    break;
unknown's avatar
unknown committed
1858
  }
unknown's avatar
unknown committed
1859
  case REAL_RESULT:
unknown's avatar
unknown committed
1860
  {
1861
    double nr= args[0]->val_real();
unknown's avatar
unknown committed
1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873

    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
1874 1875 1876 1877
    break;
  }
  case DECIMAL_RESULT:
  {
1878
    my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
unknown's avatar
unknown committed
1879 1880 1881 1882 1883 1884 1885 1886

    if (maybe_null)
    {
      if (args[0]->null_value)
        result_field->set_null();
      else
        result_field->set_notnull();
    }
1887 1888 1889 1890 1891 1892 1893
    /*
      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
1894 1895 1896 1897 1898
    break;
  }
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
unknown's avatar
unknown committed
1899 1900 1901 1902 1903 1904
  }
}


void Item_sum_sum::reset_field()
{
unknown's avatar
unknown committed
1905 1906 1907
  if (hybrid_type == DECIMAL_RESULT)
  {
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
1908 1909 1910
    if (!arg_val)                               // Null
      arg_val= &decimal_zero;
    result_field->store_decimal(arg_val);
unknown's avatar
unknown committed
1911 1912 1913 1914 1915 1916 1917
  }
  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
1918 1919 1920 1921
  if (args[0]->null_value)
    result_field->set_null();
  else
    result_field->set_notnull();
unknown's avatar
unknown committed
1922 1923 1924 1925 1926 1927 1928 1929
}


void Item_sum_count::reset_field()
{
  char *res=result_field->ptr;
  longlong nr=0;

1930
  if (!args[0]->maybe_null || !args[0]->is_null())
unknown's avatar
unknown committed
1931 1932 1933 1934 1935 1936 1937 1938
    nr=1;
  int8store(res,nr);
}


void Item_sum_avg::reset_field()
{
  char *res=result_field->ptr;
unknown's avatar
unknown committed
1939 1940
  if (hybrid_type == DECIMAL_RESULT)
  {
1941
    longlong tmp;
unknown's avatar
unknown committed
1942 1943 1944
    my_decimal value, *arg_dec= args[0]->val_decimal(&value);
    if (args[0]->null_value)
    {
1945 1946
      arg_dec= &decimal_zero;
      tmp= 0;
unknown's avatar
unknown committed
1947 1948
    }
    else
1949 1950 1951 1952
      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
1953
  }
unknown's avatar
unknown committed
1954 1955
  else
  {
unknown's avatar
unknown committed
1956 1957 1958 1959 1960 1961
    double nr= args[0]->val_real();

    if (args[0]->null_value)
      bzero(res,sizeof(double)+sizeof(longlong));
    else
    {
1962
      longlong tmp= 1;
unknown's avatar
unknown committed
1963 1964 1965 1966
      float8store(res,nr);
      res+=sizeof(double);
      int8store(res,tmp);
    }
unknown's avatar
unknown committed
1967 1968 1969
  }
}

1970

unknown's avatar
unknown committed
1971
void Item_sum_bit::reset_field()
unknown's avatar
unknown committed
1972
{
1973 1974
  reset();
  int8store(result_field->ptr, bits);
unknown's avatar
unknown committed
1975 1976 1977
}

void Item_sum_bit::update_field()
unknown's avatar
unknown committed
1978 1979
{
  char *res=result_field->ptr;
unknown's avatar
unknown committed
1980 1981 1982
  bits= uint8korr(res);
  add();
  int8store(res, bits);
unknown's avatar
unknown committed
1983 1984
}

1985

unknown's avatar
unknown committed
1986 1987 1988 1989
/*
** calc next value and merge it with field_value
*/

unknown's avatar
unknown committed
1990
void Item_sum_sum::update_field()
unknown's avatar
unknown committed
1991
{
unknown's avatar
unknown committed
1992
  if (hybrid_type == DECIMAL_RESULT)
unknown's avatar
unknown committed
1993
  {
unknown's avatar
unknown committed
1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
    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;
    char *res=result_field->ptr;

    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
2024
  }
unknown's avatar
unknown committed
2025 2026 2027
}


unknown's avatar
unknown committed
2028
void Item_sum_count::update_field()
unknown's avatar
unknown committed
2029 2030 2031 2032
{
  longlong nr;
  char *res=result_field->ptr;

unknown's avatar
unknown committed
2033
  nr=sint8korr(res);
2034
  if (!args[0]->maybe_null || !args[0]->is_null())
unknown's avatar
unknown committed
2035 2036 2037 2038 2039
    nr++;
  int8store(res,nr);
}


unknown's avatar
unknown committed
2040
void Item_sum_avg::update_field()
unknown's avatar
unknown committed
2041 2042 2043
{
  longlong field_count;
  char *res=result_field->ptr;
unknown's avatar
unknown committed
2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055
  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;
2056
      field_count++;
unknown's avatar
unknown committed
2057 2058 2059 2060 2061
      int8store(res, field_count);
    }
  }
  else
  {
2062
    double nr;
unknown's avatar
unknown committed
2063

unknown's avatar
unknown committed
2064 2065 2066
    nr= args[0]->val_real();
    if (!args[0]->null_value)
    {
2067 2068 2069
      double old_nr;
      float8get(old_nr, res);
      field_count= sint8korr(res + sizeof(double));
unknown's avatar
unknown committed
2070
      old_nr+= nr;
2071 2072
      float8store(res,old_nr);
      res+= sizeof(double);
unknown's avatar
unknown committed
2073
      field_count++;
2074
      int8store(res, field_count);
unknown's avatar
unknown committed
2075
    }
unknown's avatar
unknown committed
2076 2077 2078
  }
}

2079

unknown's avatar
unknown committed
2080
void Item_sum_hybrid::update_field()
unknown's avatar
unknown committed
2081
{
2082
  switch (hybrid_type) {
unknown's avatar
unknown committed
2083
  case STRING_RESULT:
unknown's avatar
unknown committed
2084
    min_max_update_str_field();
unknown's avatar
unknown committed
2085 2086
    break;
  case INT_RESULT:
unknown's avatar
unknown committed
2087
    min_max_update_int_field();
unknown's avatar
unknown committed
2088 2089 2090 2091 2092
    break;
  case DECIMAL_RESULT:
    min_max_update_decimal_field();
    break;
  default:
unknown's avatar
unknown committed
2093
    min_max_update_real_field();
unknown's avatar
unknown committed
2094
  }
unknown's avatar
unknown committed
2095 2096 2097 2098
}


void
unknown's avatar
unknown committed
2099
Item_sum_hybrid::min_max_update_str_field()
unknown's avatar
unknown committed
2100 2101 2102
{
  String *res_str=args[0]->val_str(&value);

unknown's avatar
unknown committed
2103
  if (!args[0]->null_value)
unknown's avatar
unknown committed
2104
  {
2105
    result_field->val_str(&tmp_value);
unknown's avatar
unknown committed
2106 2107

    if (result_field->is_null() ||
2108
	(cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
2109
      result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
unknown's avatar
unknown committed
2110 2111 2112 2113 2114 2115
    result_field->set_notnull();
  }
}


void
unknown's avatar
unknown committed
2116
Item_sum_hybrid::min_max_update_real_field()
unknown's avatar
unknown committed
2117 2118 2119 2120
{
  double nr,old_nr;

  old_nr=result_field->val_real();
2121
  nr= args[0]->val_real();
unknown's avatar
unknown committed
2122 2123
  if (!args[0]->null_value)
  {
unknown's avatar
unknown committed
2124
    if (result_field->is_null(0) ||
unknown's avatar
unknown committed
2125 2126 2127 2128
	(cmp_sign > 0 ? old_nr > nr : old_nr < nr))
      old_nr=nr;
    result_field->set_notnull();
  }
unknown's avatar
unknown committed
2129
  else if (result_field->is_null(0))
unknown's avatar
unknown committed
2130 2131 2132 2133 2134 2135
    result_field->set_null();
  result_field->store(old_nr);
}


void
unknown's avatar
unknown committed
2136
Item_sum_hybrid::min_max_update_int_field()
unknown's avatar
unknown committed
2137 2138 2139 2140 2141 2142 2143
{
  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
2144
    if (result_field->is_null(0))
unknown's avatar
unknown committed
2145
      old_nr=nr;
2146 2147 2148 2149 2150 2151
    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
2152
      if ((cmp_sign > 0) ^ (!res))
2153 2154
	old_nr=nr;
    }
unknown's avatar
unknown committed
2155 2156
    result_field->set_notnull();
  }
unknown's avatar
unknown committed
2157
  else if (result_field->is_null(0))
unknown's avatar
unknown committed
2158
    result_field->set_null();
2159
  result_field->store(old_nr, unsigned_flag);
unknown's avatar
unknown committed
2160 2161 2162
}


unknown's avatar
unknown committed
2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189
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
2190 2191 2192
{
  name=item->name;
  decimals=item->decimals;
unknown's avatar
unknown committed
2193 2194
  max_length= item->max_length;
  unsigned_flag= item->unsigned_flag;
unknown's avatar
unknown committed
2195 2196
  field=item->result_field;
  maybe_null=1;
unknown's avatar
unknown committed
2197
  hybrid_type= res_type;
unknown's avatar
unknown committed
2198
  prec_increment= item->prec_increment;
unknown's avatar
unknown committed
2199 2200 2201 2202 2203 2204
  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
2205 2206
}

2207
double Item_avg_field::val_real()
unknown's avatar
unknown committed
2208
{
2209
  // fix_fields() never calls for this Item
2210 2211 2212 2213
  double nr;
  longlong count;
  char *res;

unknown's avatar
unknown committed
2214
  if (hybrid_type == DECIMAL_RESULT)
2215
    return val_real_from_decimal();
unknown's avatar
unknown committed
2216

2217 2218 2219 2220 2221 2222 2223
  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
2224 2225
}

2226

unknown's avatar
unknown committed
2227 2228
longlong Item_avg_field::val_int()
{
2229
  return (longlong) rint(val_real());
unknown's avatar
unknown committed
2230 2231 2232
}


2233
my_decimal *Item_avg_field::val_decimal(my_decimal *dec_buf)
unknown's avatar
unknown committed
2234 2235
{
  // fix_fields() never calls for this Item
2236 2237 2238
  if (hybrid_type == REAL_RESULT)
    return val_decimal_from_real(dec_buf);

unknown's avatar
unknown committed
2239 2240
  longlong count= sint8korr(field->ptr + dec_bin_size);
  if ((null_value= !count))
2241
    return 0;
unknown's avatar
unknown committed
2242 2243 2244 2245 2246

  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
2247 2248
  my_decimal_div(E_DEC_FATAL_ERROR, dec_buf,
                 &dec_field, &dec_count, prec_increment);
2249
  return dec_buf;
unknown's avatar
unknown committed
2250 2251
}

unknown's avatar
unknown committed
2252

unknown's avatar
unknown committed
2253 2254
String *Item_avg_field::val_str(String *str)
{
2255
  // fix_fields() never calls for this Item
unknown's avatar
unknown committed
2256
  if (hybrid_type == DECIMAL_RESULT)
2257 2258
    return val_string_from_decimal(str);
  return val_string_from_real(str);
unknown's avatar
unknown committed
2259 2260
}

2261

unknown's avatar
unknown committed
2262
Item_std_field::Item_std_field(Item_sum_std *item)
unknown's avatar
unknown committed
2263 2264 2265 2266
  : Item_variance_field(item)
{
}

2267

2268
double Item_std_field::val_real()
unknown's avatar
unknown committed
2269
{
2270
  double nr;
2271
  // fix_fields() never calls for this Item
2272 2273 2274
  nr= Item_variance_field::val_real();
  DBUG_ASSERT(nr >= 0.0);
  return sqrt(nr);
unknown's avatar
unknown committed
2275 2276
}

2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287

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);
2288

2289 2290 2291 2292
  dec= Item_variance_field::val_decimal(dec_buf);
  if (!dec)
    return 0;
  my_decimal2double(E_DEC_FATAL_ERROR, dec, &nr);
2293 2294
  DBUG_ASSERT(nr >= 0.0);
  nr= sqrt(nr);
2295 2296 2297 2298 2299 2300
  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
2301
Item_variance_field::Item_variance_field(Item_sum_variance *item)
unknown's avatar
unknown committed
2302 2303 2304 2305
{
  name=item->name;
  decimals=item->decimals;
  max_length=item->max_length;
unknown's avatar
unknown committed
2306
  unsigned_flag= item->unsigned_flag;
unknown's avatar
unknown committed
2307 2308
  field=item->result_field;
  maybe_null=1;
2309
  sample= item->sample;
unknown's avatar
unknown committed
2310
  prec_increment= item->prec_increment;
unknown's avatar
unknown committed
2311 2312 2313 2314 2315 2316 2317 2318 2319
  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
2320 2321
}

2322

2323
double Item_variance_field::val_real()
unknown's avatar
unknown committed
2324
{
2325
  // fix_fields() never calls for this Item
unknown's avatar
unknown committed
2326
  if (hybrid_type == DECIMAL_RESULT)
2327 2328
    return val_real_from_decimal();

2329 2330 2331
  double recurrence_s;
  ulonglong count;
  float8get(recurrence_s, (field->ptr + sizeof(double)));
unknown's avatar
unknown committed
2332 2333
  count=sint8korr(field->ptr+sizeof(double)*2);

2334
  if ((null_value= (count <= sample)))
unknown's avatar
unknown committed
2335
    return 0.0;
2336

2337
  return variance_fp_recurrence_result(recurrence_s, count, sample);
unknown's avatar
unknown committed
2338 2339 2340
}


unknown's avatar
unknown committed
2341 2342 2343 2344
/****************************************************************************
** COUNT(DISTINCT ...)
****************************************************************************/

2345
int simple_str_key_cmp(void* arg, byte* key1, byte* key2)
2346
{
2347
  Field *f= (Field*) arg;
unknown's avatar
unknown committed
2348
  return f->cmp((const char*)key1, (const char*)key2);
2349 2350
}

unknown's avatar
unknown committed
2351 2352 2353 2354 2355 2356 2357
/*
  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
*/

2358 2359 2360
int composite_key_cmp(void* arg, byte* key1, byte* key2)
{
  Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
unknown's avatar
unknown committed
2361
  Field **field    = item->table->field;
2362
  Field **field_end= field + item->table->s->fields;
unknown's avatar
unknown committed
2363 2364 2365 2366 2367
  uint32 *lengths=item->field_lengths;
  for (; field < field_end; ++field)
  {
    Field* f = *field;
    int len = *lengths++;
unknown's avatar
unknown committed
2368
    int res = f->cmp((char *) key1, (char *) key2);
unknown's avatar
unknown committed
2369 2370 2371 2372 2373
    if (res)
      return res;
    key1 += len;
    key2 += len;
  }
2374 2375 2376 2377
  return 0;
}


2378 2379
C_MODE_START

2380
static int count_distinct_walk(void *elem, element_count count, void *arg)
2381
{
2382
  (*((ulonglong*)arg))++;
2383 2384
  return 0;
}
2385

2386 2387
C_MODE_END

unknown's avatar
unknown committed
2388

unknown's avatar
unknown committed
2389
void Item_sum_count_distinct::cleanup()
unknown's avatar
unknown committed
2390
{
unknown's avatar
unknown committed
2391
  DBUG_ENTER("Item_sum_count_distinct::cleanup");
unknown's avatar
unknown committed
2392
  Item_sum_int::cleanup();
2393 2394

  /* Free objects only if we own them. */
2395 2396
  if (!original)
  {
2397 2398 2399 2400 2401 2402 2403
    /*
      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;
2404
    is_evaluated= FALSE;
2405
    if (table)
unknown's avatar
unknown committed
2406
    {
2407
      free_tmp_table(table->in_use, table);
unknown's avatar
unknown committed
2408 2409
      table= 0;
    }
2410
    delete tmp_table_param;
unknown's avatar
unknown committed
2411
    tmp_table_param= 0;
2412
  }
2413
  always_null= FALSE;
unknown's avatar
unknown committed
2414
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
2415 2416
}

unknown's avatar
unknown committed
2417

2418 2419 2420 2421 2422 2423
/* This is used by rollup to create a separate usable copy of the function */

void Item_sum_count_distinct::make_unique()
{
  table=0;
  original= 0;
2424
  force_copy_fields= 1;
2425
  tree= 0;
2426
  is_evaluated= FALSE;
2427 2428 2429 2430 2431 2432 2433 2434
  tmp_table_param= 0;
  always_null= FALSE;
}


Item_sum_count_distinct::~Item_sum_count_distinct()
{
  cleanup();
2435 2436 2437
}


unknown's avatar
unknown committed
2438 2439 2440
bool Item_sum_count_distinct::setup(THD *thd)
{
  List<Item> list;
unknown's avatar
unknown committed
2441
  SELECT_LEX *select_lex= thd->lex->current_select;
2442 2443 2444 2445 2446 2447 2448 2449

  /*
    Setup can be called twice for ROLLUP items. This is a bug.
    Please add DBUG_ASSERT(tree == 0) here when it's fixed.
  */
  if (tree || table || tmp_table_param)
    return FALSE;

2450
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
unknown's avatar
unknown committed
2451
    return TRUE;
2452

unknown's avatar
unknown committed
2453 2454
  /* Create a table with an unique key over all parameters */
  for (uint i=0; i < arg_count ; i++)
2455 2456 2457
  {
    Item *item=args[i];
    if (list.push_back(item))
unknown's avatar
unknown committed
2458
      return TRUE;                              // End of memory
2459 2460
    if (item->const_item() && item->is_null())
      always_null= 1;
2461 2462
  }
  if (always_null)
unknown's avatar
unknown committed
2463
    return FALSE;
unknown's avatar
unknown committed
2464
  count_field_types(tmp_table_param,list,0);
2465
  tmp_table_param->force_copy_fields= force_copy_fields;
2466
  DBUG_ASSERT(table == 0);
2467
  if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
unknown's avatar
unknown committed
2468
				0,
2469
				(select_lex->options | thd->options),
2470
				HA_POS_ERROR, (char*)"")))
unknown's avatar
unknown committed
2471
    return TRUE;
unknown's avatar
unknown committed
2472
  table->file->extra(HA_EXTRA_NO_ROWS);		// Don't update rows
2473
  table->no_rows=1;
2474

2475
  if (table->s->db_type == DB_TYPE_HEAP)
unknown's avatar
unknown committed
2476
  {
2477 2478 2479 2480
    /*
      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
2481 2482
    qsort_cmp2 compare_key;
    void* cmp_arg;
2483 2484 2485
    Field **field= table->field;
    Field **field_end= field + table->s->fields;
    bool all_binary= TRUE;
unknown's avatar
unknown committed
2486

2487
    for (tree_key_length= 0; field < field_end; ++field)
unknown's avatar
unknown committed
2488
    {
2489
      Field *f= *field;
2490
      enum enum_field_types f_type= f->type();
2491
      tree_key_length+= f->pack_length();
2492 2493 2494
      if ((f_type == MYSQL_TYPE_VARCHAR) ||
          !f->binary() && (f_type == MYSQL_TYPE_STRING ||
                           f_type == MYSQL_TYPE_VAR_STRING))
2495 2496 2497
      {
        all_binary= FALSE;
        break;
unknown's avatar
unknown committed
2498
      }
2499
    }
2500
    if (all_binary)
unknown's avatar
unknown committed
2501
    {
2502 2503 2504 2505 2506 2507
      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
2508
      {
2509 2510 2511 2512 2513 2514 2515 2516 2517
        /*
          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
2518 2519 2520
      }
      else
      {
2521 2522 2523 2524 2525 2526 2527 2528 2529 2530
        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
2531 2532
      }
    }
2533 2534 2535
    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
2536
    /*
2537
      The only time tree_key_length could be 0 is if someone does
unknown's avatar
unknown committed
2538 2539 2540 2541
      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
    */
2542
    is_evaluated= FALSE;
2543 2544
    if (! tree)
      return TRUE;
unknown's avatar
unknown committed
2545
  }
2546
  return FALSE;
2547
}
unknown's avatar
unknown committed
2548

2549 2550 2551

Item *Item_sum_count_distinct::copy_or_same(THD* thd) 
{
unknown's avatar
unknown committed
2552
  return new (thd->mem_root) Item_sum_count_distinct(thd, this);
2553 2554 2555
}


2556
void Item_sum_count_distinct::clear()
unknown's avatar
unknown committed
2557
{
2558
  /* tree and table can be both null only if always_null */
2559
  is_evaluated= FALSE;
2560
  if (tree)
2561
  {
2562
    tree->reset();
2563
  }
unknown's avatar
merge  
unknown committed
2564
  else if (table)
2565 2566 2567 2568 2569
  {
    table->file->extra(HA_EXTRA_NO_CACHE);
    table->file->delete_all_rows();
    table->file->extra(HA_EXTRA_WRITE_CACHE);
  }
unknown's avatar
unknown committed
2570 2571 2572 2573 2574
}

bool Item_sum_count_distinct::add()
{
  int error;
2575 2576
  if (always_null)
    return 0;
unknown's avatar
unknown committed
2577
  copy_fields(tmp_table_param);
unknown's avatar
unknown committed
2578
  copy_funcs(tmp_table_param->items_to_copy);
unknown's avatar
unknown committed
2579

2580 2581 2582 2583
  for (Field **field=table->field ; *field ; field++)
    if ((*field)->is_real_null(0))
      return 0;					// Don't count NULL

2584
  is_evaluated= FALSE;
2585
  if (tree)
unknown's avatar
unknown committed
2586 2587
  {
    /*
2588 2589 2590 2591
      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
2592
    */
2593
    return tree->unique_add(table->record[0] + table->s->null_bytes);
unknown's avatar
unknown committed
2594
  }
2595 2596 2597 2598 2599
  if ((error= table->file->write_row(table->record[0])) &&
      error != HA_ERR_FOUND_DUPP_KEY &&
      error != HA_ERR_FOUND_DUPP_UNIQUE)
    return TRUE;
  return FALSE;
unknown's avatar
unknown committed
2600 2601
}

unknown's avatar
unknown committed
2602

unknown's avatar
unknown committed
2603 2604
longlong Item_sum_count_distinct::val_int()
{
2605
  int error;
2606
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2607 2608
  if (!table)					// Empty query
    return LL(0);
2609 2610
  if (tree)
  {
2611 2612
    if (is_evaluated)
      return count;
2613 2614 2615 2616 2617

    if (tree->elements == 0)
      return (longlong) tree->elements_in_tree(); // everything fits in memory
    count= 0;
    tree->walk(count_distinct_walk, (void*) &count);
2618
    is_evaluated= TRUE;
2619 2620
    return (longlong) count;
  }
2621 2622 2623 2624 2625 2626 2627 2628

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

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

unknown's avatar
unknown committed
2629 2630 2631
  return table->file->records;
}

2632

unknown's avatar
unknown committed
2633 2634 2635 2636 2637 2638 2639 2640 2641
/****************************************************************************
** 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

2642
void Item_udf_sum::clear()
unknown's avatar
unknown committed
2643
{
2644
  DBUG_ENTER("Item_udf_sum::clear");
2645
  udf.clear();
2646
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
2647 2648 2649 2650
}

bool Item_udf_sum::add()
{
2651
  DBUG_ENTER("Item_udf_sum::add");
unknown's avatar
unknown committed
2652 2653 2654 2655
  udf.add(&null_value);
  DBUG_RETURN(0);
}

2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666
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();
}


2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680
void Item_udf_sum::print(String *str)
{
  str->append(func_name());
  str->append('(');
  for (uint i=0 ; i < arg_count ; i++)
  {
    if (i)
      str->append(',');
    args[i]->print(str);
  }
  str->append(')');
}


2681 2682
Item *Item_sum_udf_float::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
2683
  return new (thd->mem_root) Item_sum_udf_float(thd, this);
2684 2685
}

2686
double Item_sum_udf_float::val_real()
unknown's avatar
unknown committed
2687
{
2688
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2689 2690 2691 2692 2693 2694
  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));
}

2695

unknown's avatar
unknown committed
2696 2697
String *Item_sum_udf_float::val_str(String *str)
{
2698
  return val_string_from_real(str);
unknown's avatar
unknown committed
2699 2700 2701
}


2702
my_decimal *Item_sum_udf_float::val_decimal(my_decimal *dec)
2703
{
2704
  return val_decimal_from_real(dec);
2705 2706 2707
}


unknown's avatar
unknown committed
2708 2709
String *Item_sum_udf_decimal::val_str(String *str)
{
2710
  return val_string_from_decimal(str);
unknown's avatar
unknown committed
2711 2712 2713 2714 2715
}


double Item_sum_udf_decimal::val_real()
{
2716
  return val_real_from_decimal();
unknown's avatar
unknown committed
2717 2718 2719 2720 2721
}


longlong Item_sum_udf_decimal::val_int()
{
2722
  return val_int_from_decimal();
unknown's avatar
unknown committed
2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742
}


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);
}


2743 2744 2745 2746 2747
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
2748 2749
longlong Item_sum_udf_int::val_int()
{
2750
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2751 2752 2753 2754 2755 2756
  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));
}

2757

unknown's avatar
unknown committed
2758 2759
String *Item_sum_udf_int::val_str(String *str)
{
2760
  return val_string_from_int(str);
unknown's avatar
unknown committed
2761 2762
}

2763 2764 2765 2766 2767 2768
my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
{
  return val_decimal_from_int(dec);
}


unknown's avatar
unknown committed
2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779
/* Default max_length is max argument length */

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;
}

2780 2781 2782

Item *Item_sum_udf_str::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
2783
  return new (thd->mem_root) Item_sum_udf_str(thd, this);
2784 2785 2786
}


2787 2788 2789 2790 2791
my_decimal *Item_sum_udf_str::val_decimal(my_decimal *dec)
{
  return val_decimal_from_string(dec);
}

unknown's avatar
unknown committed
2792 2793
String *Item_sum_udf_str::val_str(String *str)
{
2794
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2795 2796 2797 2798 2799 2800 2801
  DBUG_ENTER("Item_sum_udf_str::str");
  String *res=udf.val_str(str,&str_value);
  null_value = !res;
  DBUG_RETURN(res);
}

#endif /* HAVE_DLOPEN */
2802 2803 2804 2805


/*****************************************************************************
 GROUP_CONCAT function
unknown's avatar
unknown committed
2806 2807

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

2811
 concat of values from "group by" operation
unknown's avatar
unknown committed
2812 2813 2814 2815 2816

 BUGS
   DISTINCT and ORDER BY only works if ORDER BY uses all fields and only fields
   in expression list
   Blobs doesn't work with DISTINCT or ORDER BY
2817 2818 2819
*****************************************************************************/

/*
unknown's avatar
SCRUM  
unknown committed
2820 2821
  function of sort for syntax:
  GROUP_CONCAT(DISTINCT expr,...)
2822 2823
*/

unknown's avatar
unknown committed
2824 2825
int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
				       byte* key2)
2826
{
unknown's avatar
unknown committed
2827
  Item_func_group_concat* grp_item= (Item_func_group_concat*)arg;
unknown's avatar
unknown committed
2828
  TABLE *table= grp_item->table;
unknown's avatar
unknown committed
2829
  Item **field_item, **end;
unknown's avatar
unknown committed
2830

unknown's avatar
unknown committed
2831
  for (field_item= grp_item->args, end= field_item + grp_item->arg_count_field;
unknown's avatar
unknown committed
2832 2833
       field_item < end;
       field_item++)
2834
  {
unknown's avatar
unknown committed
2835 2836 2837 2838 2839 2840
    /*
      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= (*field_item)->get_tmp_table_field();
unknown's avatar
unknown committed
2841 2842 2843 2844 2845
    /* 
      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 (field && !(*field_item)->const_item())
2846
    {
unknown's avatar
unknown committed
2847
      int res;
unknown's avatar
unknown committed
2848
      uint offset= field->offset() - table->s->null_bytes;
unknown's avatar
unknown committed
2849
      if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
unknown's avatar
unknown committed
2850
	return res;
2851
    }
unknown's avatar
unknown committed
2852
  }
2853 2854 2855
  return 0;
}

2856

2857
/*
unknown's avatar
SCRUM  
unknown committed
2858 2859
  function of sort for syntax:
  GROUP_CONCAT(expr,... ORDER BY col,... )
2860 2861
*/

unknown's avatar
unknown committed
2862
int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
2863
{
unknown's avatar
unknown committed
2864
  Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
unknown's avatar
unknown committed
2865
  ORDER **order_item, **end;
unknown's avatar
unknown committed
2866
  TABLE *table= grp_item->table;
unknown's avatar
unknown committed
2867

unknown's avatar
unknown committed
2868
  for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
unknown's avatar
unknown committed
2869 2870
       order_item < end;
       order_item++)
2871
  {
unknown's avatar
unknown committed
2872
    Item *item= *(*order_item)->item;
unknown's avatar
unknown committed
2873 2874 2875 2876 2877 2878
    /*
      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
2879 2880 2881 2882 2883
    /* 
      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())
2884
    {
unknown's avatar
unknown committed
2885
      int res;
unknown's avatar
unknown committed
2886
      uint offset= field->offset() - table->s->null_bytes;
unknown's avatar
unknown committed
2887
      if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
unknown's avatar
unknown committed
2888
        return (*order_item)->asc ? res : -res;
2889
    }
unknown's avatar
unknown committed
2890
  }
unknown's avatar
SCRUM  
unknown committed
2891
  /*
unknown's avatar
unknown committed
2892 2893
    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
2894
    if the returned values are not the same we do the sort on.
unknown's avatar
unknown committed
2895
  */
2896 2897 2898
  return 1;
}

2899

2900
/*
unknown's avatar
SCRUM  
unknown committed
2901 2902
  function of sort for syntax:
  GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
unknown's avatar
unknown committed
2903 2904 2905 2906 2907

  BUG:
    This doesn't work in the case when the order by contains data that
    is not part of the field list because tree-insert will not notice
    the duplicated values when inserting things sorted by ORDER BY
2908
*/
unknown's avatar
SCRUM  
unknown committed
2909

unknown's avatar
unknown committed
2910 2911
int group_concat_key_cmp_with_distinct_and_order(void* arg,byte* key1,
						 byte* key2)
2912 2913 2914 2915 2916 2917
{
  if (!group_concat_key_cmp_with_distinct(arg,key1,key2))
    return 0;
  return(group_concat_key_cmp_with_order(arg,key1,key2));
}

2918

2919
/*
unknown's avatar
unknown committed
2920
  Append data from current leaf to item->result
2921
*/
unknown's avatar
SCRUM  
unknown committed
2922

2923
int dump_leaf_key(byte* key, element_count count __attribute__((unused)),
unknown's avatar
unknown committed
2924
                  Item_func_group_concat *item)
2925
{
unknown's avatar
unknown committed
2926
  TABLE *table= item->table;
unknown's avatar
unknown committed
2927 2928 2929
  String tmp((char *)table->record[1], table->s->reclength,
             default_charset_info);
  String tmp2;
unknown's avatar
unknown committed
2930
  String *result= &item->result;
unknown's avatar
unknown committed
2931
  Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
2932
  uint old_length= result->length();
unknown's avatar
unknown committed
2933

2934 2935 2936
  if (item->no_appended)
    item->no_appended= FALSE;
  else
unknown's avatar
unknown committed
2937
    result->append(*item->separator);
unknown's avatar
a fix  
unknown committed
2938

2939
  tmp.length(0);
unknown's avatar
unknown committed
2940 2941

  for (; arg < arg_end; arg++)
2942
  {
unknown's avatar
unknown committed
2943 2944
    String *res;
    if (! (*arg)->const_item())
2945
    {
unknown's avatar
unknown committed
2946 2947 2948 2949
      /*
	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
2950 2951
        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
2952
      */
unknown's avatar
unknown committed
2953
      Field *field= (*arg)->get_tmp_table_field();
unknown's avatar
unknown committed
2954
      uint offset= field->offset() - table->s->null_bytes;
unknown's avatar
unknown committed
2955
      DBUG_ASSERT(offset < table->s->reclength);
unknown's avatar
unknown committed
2956
      res= field->val_str(&tmp, (char *) key + offset);
2957
    }
unknown's avatar
unknown committed
2958 2959 2960
    else
      res= (*arg)->val_str(&tmp);
    if (res)
unknown's avatar
unknown committed
2961
      result->append(*res);
2962
  }
unknown's avatar
unknown committed
2963

unknown's avatar
unknown committed
2964
  /* stop if length of result more than max_length */
unknown's avatar
unknown committed
2965
  if (result->length() > item->max_length)
2966
  {
2967 2968
    int well_formed_error;
    CHARSET_INFO *cs= item->collation.collation;
unknown's avatar
unknown committed
2969
    const char *ptr= result->ptr();
2970 2971 2972 2973 2974 2975 2976 2977
    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
2978 2979
                                          ptr + item->max_length,
                                          result->length(),
2980
                                          &well_formed_error);
unknown's avatar
unknown committed
2981
    result->length(old_length + add_length);
unknown's avatar
unknown committed
2982 2983
    item->count_cut_values++;
    item->warning_for_row= TRUE;
2984 2985 2986 2987 2988
    return 1;
  }
  return 0;
}

2989

2990
/*
unknown's avatar
SCRUM  
unknown committed
2991
  Constructor of Item_func_group_concat
unknown's avatar
unknown committed
2992 2993 2994 2995
  distinct_arg - distinct
  select_list - list of expression for show values
  order_list - list of sort columns
  separator_arg - string value of separator
2996
*/
unknown's avatar
SCRUM  
unknown committed
2997

unknown's avatar
unknown committed
2998
Item_func_group_concat::
2999 3000
Item_func_group_concat(Name_resolution_context *context_arg,
                       bool distinct_arg, List<Item> *select_list,
unknown's avatar
unknown committed
3001 3002
                       SQL_LIST *order_list, String *separator_arg)
  :tmp_table_param(0), warning(0),
unknown's avatar
unknown committed
3003
   separator(separator_arg), tree(0), table(0),
3004
   order(0), context(context_arg),
unknown's avatar
unknown committed
3005 3006 3007 3008 3009
   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
3010
   force_copy_fields(0), original(0)
3011
{
unknown's avatar
unknown committed
3012 3013 3014
  Item *item_select;
  Item **arg_ptr;

unknown's avatar
unknown committed
3015
  quick_group= FALSE;
unknown's avatar
unknown committed
3016
  arg_count= arg_count_field + arg_count_order;
unknown's avatar
unknown committed
3017

unknown's avatar
SCRUM  
unknown committed
3018 3019
  /*
    We need to allocate:
unknown's avatar
unknown committed
3020 3021
    args - arg_count_field+arg_count_order
           (for possible order items in temporare tables)
unknown's avatar
SCRUM  
unknown committed
3022 3023
    order - arg_count_order
  */
unknown's avatar
unknown committed
3024
  if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
unknown's avatar
unknown committed
3025
                                 sizeof(ORDER*)*arg_count_order)))
unknown's avatar
unknown committed
3026
    return;
unknown's avatar
unknown committed
3027

unknown's avatar
unknown committed
3028 3029
  order= (ORDER**)(args + arg_count);

unknown's avatar
unknown committed
3030
  /* fill args items of show and sort */
unknown's avatar
unknown committed
3031
  List_iterator_fast<Item> li(*select_list);
3032

unknown's avatar
unknown committed
3033 3034
  for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
    *arg_ptr= item_select;
unknown's avatar
unknown committed
3035

unknown's avatar
unknown committed
3036
  if (arg_count_order)
unknown's avatar
SCRUM  
unknown committed
3037
  {
unknown's avatar
unknown committed
3038
    ORDER **order_ptr= order;
unknown's avatar
unknown committed
3039 3040 3041
    for (ORDER *order_item= (ORDER*) order_list->first;
         order_item != NULL;
         order_item= order_item->next)
3042
    {
unknown's avatar
unknown committed
3043 3044 3045
      (*order_ptr++)= order_item;
      *arg_ptr= *order_item->item;
      order_item->item= arg_ptr++;
3046 3047 3048
    }
  }
}
unknown's avatar
unknown committed
3049

unknown's avatar
unknown committed
3050 3051

Item_func_group_concat::Item_func_group_concat(THD *thd,
unknown's avatar
unknown committed
3052 3053
                                               Item_func_group_concat *item)
  :Item_sum(thd, item),
unknown's avatar
unknown committed
3054 3055 3056 3057 3058 3059
  tmp_table_param(item->tmp_table_param),
  warning(item->warning),
  separator(item->separator),
  tree(item->tree),
  table(item->table),
  order(item->order),
3060
  context(item->context),
unknown's avatar
unknown committed
3061 3062 3063
  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
3064 3065 3066
  distinct(item->distinct),
  warning_for_row(item->warning_for_row),
  always_null(item->always_null),
unknown's avatar
unknown committed
3067
  force_copy_fields(item->force_copy_fields),
unknown's avatar
unknown committed
3068 3069 3070 3071 3072
  original(item)
{
  quick_group= item->quick_group;
}

3073

unknown's avatar
SCRUM  
unknown committed
3074

unknown's avatar
unknown committed
3075 3076
void Item_func_group_concat::cleanup()
{
unknown's avatar
unknown committed
3077
  DBUG_ENTER("Item_func_group_concat::cleanup");
3078
  Item_sum::cleanup();
unknown's avatar
unknown committed
3079

3080 3081 3082 3083 3084
  /* 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);
3085
    warning->set_msg(current_thd, warn_buff);
3086 3087 3088
    warning= 0;
  }

unknown's avatar
unknown committed
3089 3090 3091 3092 3093 3094
  /*
    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
3095 3096
    delete tmp_table_param;
    tmp_table_param= 0;
unknown's avatar
unknown committed
3097
    if (table)
unknown's avatar
unknown committed
3098
    {
unknown's avatar
unknown committed
3099
      THD *thd= table->in_use;
unknown's avatar
unknown committed
3100
      free_tmp_table(thd, table);
unknown's avatar
unknown committed
3101
      table= 0;
unknown's avatar
unknown committed
3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113
      if (tree)
      {
        delete_tree(tree);
        tree= 0;
      }
      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
3114
    }
3115
    DBUG_ASSERT(tree == 0 && warning == 0);
unknown's avatar
unknown committed
3116
  }
unknown's avatar
unknown committed
3117
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
3118 3119
}

unknown's avatar
unknown committed
3120

3121 3122
Item *Item_func_group_concat::copy_or_same(THD* thd)
{
unknown's avatar
unknown committed
3123
  return new (thd->mem_root) Item_func_group_concat(thd, this);
3124 3125 3126
}


3127
void Item_func_group_concat::clear()
3128 3129 3130
{
  result.length(0);
  result.copy();
unknown's avatar
SCRUM  
unknown committed
3131
  null_value= TRUE;
unknown's avatar
unknown committed
3132
  warning_for_row= FALSE;
3133
  no_appended= TRUE;
unknown's avatar
unknown committed
3134
  if (tree)
3135
    reset_tree(tree);
unknown's avatar
unknown committed
3136
  /* No need to reset the table as we never call write_row */
3137 3138
}

unknown's avatar
SCRUM  
unknown committed
3139

3140 3141
bool Item_func_group_concat::add()
{
unknown's avatar
BUG  
unknown committed
3142 3143
  if (always_null)
    return 0;
3144 3145 3146
  copy_fields(tmp_table_param);
  copy_funcs(tmp_table_param->items_to_copy);

unknown's avatar
unknown committed
3147
  for (uint i= 0; i < arg_count_field; i++)
3148
  {
unknown's avatar
unknown committed
3149
    Item *show_item= args[i];
unknown's avatar
SCRUM  
unknown committed
3150
    if (!show_item->const_item())
3151
    {
unknown's avatar
unknown committed
3152 3153
      Field *f= show_item->get_tmp_table_field();
      if (f->is_null_in_record((const uchar*) table->record[0]))
unknown's avatar
unknown committed
3154
        return 0;                               // Skip row if it contains null
3155 3156
    }
  }
unknown's avatar
unknown committed
3157

unknown's avatar
SCRUM  
unknown committed
3158
  null_value= FALSE;
3159 3160

  TREE_ELEMENT *el= 0;                          // Only for safety
unknown's avatar
unknown committed
3161 3162 3163
  if (tree)
    el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
                    tree->custom_arg);
3164 3165 3166 3167 3168
  /*
    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.
  */
3169
  if (!warning_for_row &&
unknown's avatar
unknown committed
3170 3171
      (!tree || (el->count == 1 && distinct && !arg_count_order)))
    dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3172

3173 3174 3175
  return 0;
}

unknown's avatar
SCRUM  
unknown committed
3176

3177
bool
3178
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3179
{
unknown's avatar
unknown committed
3180
  uint i;                       /* for loop variable */
3181
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
3182

unknown's avatar
unknown committed
3183
  if (init_sum_func_check(thd))
unknown's avatar
unknown committed
3184
    return TRUE;
unknown's avatar
unknown committed
3185

3186
  maybe_null= 1;
unknown's avatar
unknown committed
3187

unknown's avatar
SCRUM  
unknown committed
3188
  /*
unknown's avatar
unknown committed
3189
    Fix fields for select list and ORDER clause
unknown's avatar
SCRUM  
unknown committed
3190
  */
unknown's avatar
unknown committed
3191

unknown's avatar
unknown committed
3192
  for (i=0 ; i < arg_count ; i++)
3193
  {
unknown's avatar
unknown committed
3194
    if ((!args[i]->fixed &&
3195
         args[i]->fix_fields(thd, args + i)) ||
unknown's avatar
unknown committed
3196
        args[i]->check_cols(1))
unknown's avatar
unknown committed
3197
      return TRUE;
3198
  }
unknown's avatar
unknown committed
3199

3200
  if (agg_item_charsets(collation, func_name(),
3201 3202 3203
                        args,
			/* skip charset aggregation for order columns */
			arg_count - arg_count_order,
3204
			MY_COLL_ALLOW_CONV, 1))
3205 3206
    return 1;

unknown's avatar
unknown committed
3207
  result.set_charset(collation.collation);
unknown's avatar
SCRUM  
unknown committed
3208 3209
  result_field= 0;
  null_value= 1;
unknown's avatar
unknown committed
3210
  max_length= thd->variables.group_concat_max_len;
unknown's avatar
unknown committed
3211

3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232
  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;

    if (!(buf= thd->stmt_arena->alloc(buflen)) ||
        !(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
3233 3234 3235
  if (check_sum_func(thd, ref))
    return TRUE;

3236
  fixed= 1;
unknown's avatar
unknown committed
3237
  return FALSE;
3238 3239
}

unknown's avatar
SCRUM  
unknown committed
3240

3241 3242 3243
bool Item_func_group_concat::setup(THD *thd)
{
  List<Item> list;
unknown's avatar
unknown committed
3244
  SELECT_LEX *select_lex= thd->lex->current_select;
unknown's avatar
unknown committed
3245 3246
  qsort_cmp2 compare_key;
  DBUG_ENTER("Item_func_group_concat::setup");
3247

unknown's avatar
SCRUM  
unknown committed
3248
  /*
unknown's avatar
unknown committed
3249 3250
    Currently setup() can be called twice. Please add
    assertion here when this is fixed.
unknown's avatar
unknown committed
3251
  */
unknown's avatar
unknown committed
3252 3253 3254 3255 3256 3257 3258
  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
3259 3260
  tmp_table_param->convert_blob_length= max_length *
                                        collation.collation->mbmaxlen;
unknown's avatar
unknown committed
3261
  /* Push all not constant fields to the list and create a temp table */
unknown's avatar
BUG  
unknown committed
3262
  always_null= 0;
unknown's avatar
unknown committed
3263
  for (uint i= 0; i < arg_count_field; i++)
3264
  {
unknown's avatar
SCRUM  
unknown committed
3265
    Item *item= args[i];
3266
    if (list.push_back(item))
unknown's avatar
unknown committed
3267
      DBUG_RETURN(TRUE);
3268 3269
    if (item->const_item())
    {
3270
      if (item->is_null())
unknown's avatar
unknown committed
3271 3272
      {
        always_null= 1;
unknown's avatar
unknown committed
3273
        DBUG_RETURN(FALSE);
unknown's avatar
unknown committed
3274
      }
3275 3276
    }
  }
unknown's avatar
unknown committed
3277

3278
  List<Item> all_fields(list);
unknown's avatar
unknown committed
3279 3280 3281 3282 3283 3284 3285
  /*
    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 &&
3286
      setup_order(thd, args, context->table_list, list, all_fields, *order))
unknown's avatar
unknown committed
3287
    DBUG_RETURN(TRUE);
unknown's avatar
unknown committed
3288

3289
  count_field_types(tmp_table_param,all_fields,0);
3290
  tmp_table_param->force_copy_fields= force_copy_fields;
unknown's avatar
unknown committed
3291
  DBUG_ASSERT(table == 0);
unknown's avatar
unknown committed
3292 3293 3294 3295 3296 3297 3298 3299 3300
  /*
    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.
  */
  if (arg_count_order > 0 || distinct)
    set_if_smaller(tmp_table_param->convert_blob_length, 
                   Field_varstring::MAX_SIZE);
unknown's avatar
SCRUM  
unknown committed
3301
  /*
unknown's avatar
unknown committed
3302
    We have to create a temporary table to get descriptions of fields
unknown's avatar
SCRUM  
unknown committed
3303
    (types, sizes and so on).
unknown's avatar
unknown committed
3304 3305 3306

    Note that in the table, we first have the ORDER BY fields, then the
    field list.
unknown's avatar
SCRUM  
unknown committed
3307
  */
unknown's avatar
unknown committed
3308 3309
  if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
                                (ORDER*) 0, 0, TRUE,
3310
                                (select_lex->options | thd->options),
unknown's avatar
unknown committed
3311 3312
                                HA_POS_ERROR, (char*) "")))
    DBUG_RETURN(TRUE);
3313
  table->file->extra(HA_EXTRA_NO_ROWS);
unknown's avatar
SCRUM  
unknown committed
3314
  table->no_rows= 1;
unknown's avatar
unknown committed
3315 3316


unknown's avatar
unknown committed
3317
  if (distinct || arg_count_order)
3318
  {
unknown's avatar
unknown committed
3319 3320 3321 3322 3323 3324 3325 3326
    /*
      Need sorting: 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;

    tree= &tree_base;
3327 3328 3329
    if (arg_count_order)
    {
      if (distinct)
unknown's avatar
SCRUM  
unknown committed
3330
        compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct_and_order;
3331
      else
unknown's avatar
SCRUM  
unknown committed
3332
        compare_key= (qsort_cmp2) group_concat_key_cmp_with_order;
3333 3334 3335
    }
    else
    {
3336
      compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct;
3337
    }
unknown's avatar
SCRUM  
unknown committed
3338
    /*
unknown's avatar
unknown committed
3339 3340 3341
      Create a tree for sorting. The tree is used to sort and to remove
      duplicate values (according to the syntax of this function). If there
      is no DISTINCT or ORDER BY clauses, we don't create this tree.
unknown's avatar
SCRUM  
unknown committed
3342
    */
3343 3344
    init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
                               thd->variables.sortbuff_size/16), 0,
unknown's avatar
unknown committed
3345
              tree_key_length, compare_key, 0, NULL, (void*) this);
3346
  }
unknown's avatar
unknown committed
3347 3348

  DBUG_RETURN(FALSE);
3349 3350
}

unknown's avatar
unknown committed
3351

3352 3353 3354 3355
/* 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
3356
  tmp_table_param= 0;
3357 3358
  table=0;
  original= 0;
3359
  force_copy_fields= 1;
unknown's avatar
unknown committed
3360
  tree= 0;
3361 3362 3363
}


3364 3365
String* Item_func_group_concat::val_str(String* str)
{
3366
  DBUG_ASSERT(fixed == 1);
unknown's avatar
SCRUM  
unknown committed
3367 3368
  if (null_value)
    return 0;
3369 3370 3371 3372
  if (!result.length() && tree)
    /* Tree is used for sorting as in ORDER BY */
    tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
              left_root_right);
3373
  if (count_cut_values && !warning)
unknown's avatar
unknown committed
3374
  {
3375 3376 3377 3378
    /*
      ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in
      Item_func_group_concat::cleanup().
    */
unknown's avatar
unknown committed
3379 3380
    DBUG_ASSERT(table);
    warning= push_warning(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
3381 3382
                          ER_CUT_VALUE_GROUP_CONCAT,
                          ER(ER_CUT_VALUE_GROUP_CONCAT));
unknown's avatar
unknown committed
3383
  }
3384 3385
  return &result;
}
3386

unknown's avatar
unknown committed
3387

3388 3389
void Item_func_group_concat::print(String *str)
{
3390
  str->append(STRING_WITH_LEN("group_concat("));
3391
  if (distinct)
3392
    str->append(STRING_WITH_LEN("distinct "));
unknown's avatar
unknown committed
3393
  for (uint i= 0; i < arg_count_field; i++)
3394 3395 3396 3397 3398 3399 3400
  {
    if (i)
      str->append(',');
    args[i]->print(str);
  }
  if (arg_count_order)
  {
3401
    str->append(STRING_WITH_LEN(" order by "));
3402 3403 3404
    for (uint i= 0 ; i < arg_count_order ; i++)
    {
      if (i)
unknown's avatar
unknown committed
3405
        str->append(',');
3406
      (*order[i]->item)->print(str);
3407
      if (order[i]->asc)
3408
        str->append(STRING_WITH_LEN(" ASC"));
3409
      else
3410
        str->append(STRING_WITH_LEN(" DESC"));
3411 3412
    }
  }
3413
  str->append(STRING_WITH_LEN(" separator \'"));
3414
  str->append(*separator);
3415
  str->append(STRING_WITH_LEN("\')"));
3416
}