~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
17
/**
18
  @file
19
20
  @brief
21
  Sum functions (COUNT, MIN...)
22
*/
23
24
#ifdef USE_PRAGMA_IMPLEMENTATION
25
#pragma implementation				// gcc: Class implementation
26
#endif
27
28
#include "mysql_priv.h"
29
#include "sql_select.h"
30
31
/**
32
  Prepare an aggregate function item for checking context conditions.
33
34
    The function initializes the members of the Item_sum object created
35
    for a set function that are used to check validity of the set function
36
    occurrence.
37
    If the set function is not allowed in any subquery where it occurs
38
    an error is reported immediately.
39
40
  @param thd      reference to the thread context info
41
42
  @note
43
    This function is to be called for any item created for a set function
44
    object when the traversal of trees built for expressions used in the query
45
    is performed at the phase of context analysis. This function is to
46
    be invoked at the descent of this traversal.
47
  @retval
48
    TRUE   if an error is reported
49
  @retval
50
    FALSE  otherwise
51
*/
52
 
53
bool Item_sum::init_sum_func_check(THD *thd)
54
{
55
  if (!thd->lex->allow_sum_func)
56
  {
57
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
58
               MYF(0));
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
59
    return true;
1 by brian
clean slate
60
  }
61
  /* Set a reference to the nesting set function if there is  any */
62
  in_sum_func= thd->lex->in_sum_func;
63
  /* Save a pointer to object to be used in items for nested set functions */
64
  thd->lex->in_sum_func= this;
65
  nest_level= thd->lex->current_select->nest_level;
66
  ref_by= 0;
67
  aggr_level= -1;
68
  aggr_sel= NULL;
69
  max_arg_level= -1;
70
  max_sum_func_level= -1;
71
  outer_fields.empty();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
72
  return false;
1 by brian
clean slate
73
}
74
75
/**
76
  Check constraints imposed on a usage of a set function.
77
78
    The method verifies whether context conditions imposed on a usage
79
    of any set function are met for this occurrence.
80
    It checks whether the set function occurs in the position where it
81
    can be aggregated and, when it happens to occur in argument of another
82
    set function, the method checks that these two functions are aggregated in
83
    different subqueries.
84
    If the context conditions are not met the method reports an error.
85
    If the set function is aggregated in some outer subquery the method
86
    adds it to the chain of items for such set functions that is attached
87
    to the the st_select_lex structure for this subquery.
88
89
    A number of designated members of the object are used to check the
90
    conditions. They are specified in the comment before the Item_sum
91
    class declaration.
92
    Additionally a bitmap variable called allow_sum_func is employed.
93
    It is included into the thd->lex structure.
94
    The bitmap contains 1 at n-th position if the set function happens
95
    to occur under a construct of the n-th level subquery where usage
96
    of set functions are allowed (i.e either in the SELECT list or
97
    in the HAVING clause of the corresponding subquery)
98
    Consider the query:
99
    @code
100
       SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
101
         HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
102
                t1.a > (SELECT MIN(t2.d) FROM t2);
103
    @endcode
104
    allow_sum_func will contain: 
105
    - for SUM(t1.b) - 1 at the first position 
106
    - for AVG(t1.b) - 1 at the first position, 0 at the second position
107
    - for MIN(t2.d) - 1 at the first position, 1 at the second position.
108
109
  @param thd  reference to the thread context info
110
  @param ref  location of the pointer to this item in the embedding expression
111
112
  @note
113
    This function is to be called for any item created for a set function
114
    object when the traversal of trees built for expressions used in the query
115
    is performed at the phase of context analysis. This function is to
116
    be invoked at the ascent of this traversal.
117
118
  @retval
119
    TRUE   if an error is reported
120
  @retval
121
    FALSE  otherwise
122
*/
123
 
124
bool Item_sum::check_sum_func(THD *thd, Item **ref)
125
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
126
  bool invalid= false;
1 by brian
clean slate
127
  nesting_map allow_sum_func= thd->lex->allow_sum_func;
128
  /*  
129
    The value of max_arg_level is updated if an argument of the set function
130
    contains a column reference resolved  against a subquery whose level is
131
    greater than the current value of max_arg_level.
132
    max_arg_level cannot be greater than nest level.
133
    nest level is always >= 0  
134
  */ 
135
  if (nest_level == max_arg_level)
136
  {
137
    /*
138
      The function must be aggregated in the current subquery, 
139
      If it is there under a construct where it is not allowed 
140
      we report an error. 
141
    */ 
142
    invalid= !(allow_sum_func & (1 << max_arg_level));
143
  }
144
  else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
145
  {
146
    /*
147
      The set function can be aggregated only in outer subqueries.
148
      Try to find a subquery where it can be aggregated;
149
      If we fail to find such a subquery report an error.
150
    */
151
    if (register_sum_func(thd, ref))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
152
      return true;
1 by brian
clean slate
153
    invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
154
    if (!invalid && thd->variables.sql_mode & MODE_ANSI)
155
      invalid= aggr_level < 0 && max_arg_level < nest_level;
156
  }
157
  if (!invalid && aggr_level < 0)
158
  {
159
    aggr_level= nest_level;
160
    aggr_sel= thd->lex->current_select;
161
  }
162
  /*
163
    By this moment we either found a subquery where the set function is
164
    to be aggregated  and assigned a value that is  >= 0 to aggr_level,
165
    or set the value of 'invalid' to TRUE to report later an error. 
166
  */
167
  /* 
168
    Additionally we have to check whether possible nested set functions
169
    are acceptable here: they are not, if the level of aggregation of
170
    some of them is less than aggr_level.
171
  */
172
  if (!invalid) 
173
    invalid= aggr_level <= max_sum_func_level;
174
  if (invalid)  
175
  {
176
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
177
               MYF(0));
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
178
    return true;
1 by brian
clean slate
179
  }
180
181
  if (in_sum_func)
182
  {
183
    /*
184
      If the set function is nested adjust the value of
185
      max_sum_func_level for the nesting set function.
186
      We take into account only enclosed set functions that are to be 
187
      aggregated on the same level or above of the nest level of 
188
      the enclosing set function.
189
      But we must always pass up the max_sum_func_level because it is
190
      the maximum nested level of all directly and indirectly enclosed
191
      set functions. We must do that even for set functions that are
192
      aggregated inside of their enclosing set function's nest level
193
      because the enclosing function may contain another enclosing
194
      function that is to be aggregated outside or on the same level
195
      as its parent's nest level.
196
    */
197
    if (in_sum_func->nest_level >= aggr_level)
198
      set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
199
    set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level);
200
  }
201
202
  /*
203
    Check that non-aggregated fields and sum functions aren't mixed in the
204
    same select in the ONLY_FULL_GROUP_BY mode.
205
  */
206
  if (outer_fields.elements)
207
  {
208
    Item_field *field;
209
    /*
210
      Here we compare the nesting level of the select to which an outer field
211
      belongs to with the aggregation level of the sum function. All fields in
212
      the outer_fields list are checked.
213
214
      If the nesting level is equal to the aggregation level then the field is
215
        aggregated by this sum function.
216
      If the nesting level is less than the aggregation level then the field
217
        belongs to an outer select. In this case if there is an embedding sum
218
        function add current field to functions outer_fields list. If there is
219
        no embedding function then the current field treated as non aggregated
220
        and the select it belongs to is marked accordingly.
221
      If the nesting level is greater than the aggregation level then it means
222
        that this field was added by an inner sum function.
223
        Consider an example:
224
225
          select avg ( <-- we are here, checking outer.f1
226
            select (
227
              select sum(outer.f1 + inner.f1) from inner
228
            ) from outer)
229
          from most_outer;
230
231
        In this case we check that no aggregate functions are used in the
232
        select the field belongs to. If there are some then an error is
233
        raised.
234
    */
235
    List_iterator<Item_field> of(outer_fields);
236
    while ((field= of++))
237
    {
238
      SELECT_LEX *sel= field->cached_table->select_lex;
239
      if (sel->nest_level < aggr_level)
240
      {
241
        if (in_sum_func)
242
        {
243
          /*
244
            Let upper function decide whether this field is a non
245
            aggregated one.
246
          */
247
          in_sum_func->outer_fields.push_back(field);
248
        }
249
        else
250
          sel->full_group_by_flag|= NON_AGG_FIELD_USED;
251
      }
252
      if (sel->nest_level > aggr_level &&
253
          (sel->full_group_by_flag & SUM_FUNC_USED) &&
254
          !sel->group_list.elements)
255
      {
256
        my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
257
                   ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
258
        return true;
1 by brian
clean slate
259
      }
260
    }
261
  }
262
  aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
263
  update_used_tables();
264
  thd->lex->in_sum_func= in_sum_func;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
265
  return false;
1 by brian
clean slate
266
}
267
268
/**
269
  Attach a set function to the subquery where it must be aggregated.
270
271
    The function looks for an outer subquery where the set function must be
272
    aggregated. If it finds such a subquery then aggr_level is set to
273
    the nest level of this subquery and the item for the set function
274
    is added to the list of set functions used in nested subqueries
275
    inner_sum_func_list defined for each subquery. When the item is placed 
276
    there the field 'ref_by' is set to ref.
277
278
  @note
279
    Now we 'register' only set functions that are aggregated in outer
280
    subqueries. Actually it makes sense to link all set function for
281
    a subquery in one chain. It would simplify the process of 'splitting'
282
    for set functions.
283
284
  @param thd  reference to the thread context info
285
  @param ref  location of the pointer to this item in the embedding expression
286
287
  @retval
288
    FALSE  if the executes without failures (currently always)
289
  @retval
290
    TRUE   otherwise
291
*/  
292
293
bool Item_sum::register_sum_func(THD *thd, Item **ref)
294
{
295
  SELECT_LEX *sl;
296
  nesting_map allow_sum_func= thd->lex->allow_sum_func;
297
  for (sl= thd->lex->current_select->master_unit()->outer_select() ;
298
       sl && sl->nest_level > max_arg_level;
299
       sl= sl->master_unit()->outer_select() )
300
  {
301
    if (aggr_level < 0 && (allow_sum_func & (1 << sl->nest_level)))
302
    {
303
      /* Found the most nested subquery where the function can be aggregated */
304
      aggr_level= sl->nest_level;
305
      aggr_sel= sl;
306
    }
307
  }
308
  if (sl && (allow_sum_func & (1 << sl->nest_level)))
309
  {
310
    /* 
311
      We reached the subquery of level max_arg_level and checked
312
      that the function can be aggregated here. 
313
      The set function will be aggregated in this subquery.
314
    */   
315
    aggr_level= sl->nest_level;
316
    aggr_sel= sl;
317
318
  }
319
  if (aggr_level >= 0)
320
  {
321
    ref_by= ref;
322
    /* Add the object to the list of registered objects assigned to aggr_sel */
323
    if (!aggr_sel->inner_sum_func_list)
324
      next= this;
325
    else
326
    {
327
      next= aggr_sel->inner_sum_func_list->next;
328
      aggr_sel->inner_sum_func_list->next= this;
329
    }
330
    aggr_sel->inner_sum_func_list= this;
331
    aggr_sel->with_sum_func= 1;
332
333
    /* 
334
      Mark Item_subselect(s) as containing aggregate function all the way up
335
      to aggregate function's calculation context.
336
      Note that we must not mark the Item of calculation context itself
337
      because with_sum_func on the calculation context st_select_lex is
338
      already set above.
339
340
      with_sum_func being set for an Item means that this Item refers 
341
      (somewhere in it, e.g. one of its arguments if it's a function) directly
342
      or through intermediate items to an aggregate function that is calculated
343
      in a context "outside" of the Item (e.g. in the current or outer select).
344
345
      with_sum_func being set for an st_select_lex means that this st_select_lex
346
      has aggregate functions directly referenced (i.e. not through a sub-select).
347
    */
348
    for (sl= thd->lex->current_select; 
349
         sl && sl != aggr_sel && sl->master_unit()->item;
350
         sl= sl->master_unit()->outer_select() )
351
      sl->master_unit()->item->with_sum_func= 1;
352
  }
353
  thd->lex->current_select->mark_as_dependent(aggr_sel);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
354
  return false;
1 by brian
clean slate
355
}
356
357
358
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), 
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
359
  forced_const(false)
1 by brian
clean slate
360
{
361
  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
362
  {
363
    uint i=0;
364
    List_iterator_fast<Item> li(list);
365
    Item *item;
366
367
    while ((item=li++))
368
    {
369
      args[i++]= item;
370
    }
371
  }
372
  mark_as_sum_func();
373
  list.empty();					// Fields are used
374
}
375
376
377
/**
378
  Constructor used in processing select with temporary tebles.
379
*/
380
381
Item_sum::Item_sum(THD *thd, Item_sum *item):
382
  Item_result_field(thd, item), arg_count(item->arg_count),
383
  aggr_sel(item->aggr_sel),
384
  nest_level(item->nest_level), aggr_level(item->aggr_level),
385
  quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
386
  forced_const(item->forced_const) 
387
{
388
  if (arg_count <= 2)
389
    args=tmp_args;
390
  else
391
    if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
392
      return;
393
  memcpy(args, item->args, sizeof(Item*)*arg_count);
394
}
395
396
397
void Item_sum::mark_as_sum_func()
398
{
399
  SELECT_LEX *cur_select= current_thd->lex->current_select;
400
  cur_select->n_sum_items++;
401
  cur_select->with_sum_func= 1;
402
  with_sum_func= 1;
403
}
404
405
406
void Item_sum::make_field(Send_field *tmp_field)
407
{
408
  if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
409
  {
410
    ((Item_field*) args[0])->field->make_field(tmp_field);
411
    /* For expressions only col_name should be non-empty string. */
412
    char *empty_string= (char*)"";
413
    tmp_field->db_name= empty_string;
414
    tmp_field->org_table_name= empty_string;
415
    tmp_field->table_name= empty_string;
416
    tmp_field->org_col_name= empty_string;
417
    tmp_field->col_name= name;
418
    if (maybe_null)
419
      tmp_field->flags&= ~NOT_NULL_FLAG;
420
  }
421
  else
422
    init_make_field(tmp_field, field_type());
423
}
424
425
426
void Item_sum::print(String *str, enum_query_type query_type)
427
{
428
  str->append(func_name());
429
  for (uint i=0 ; i < arg_count ; i++)
430
  {
431
    if (i)
432
      str->append(',');
433
    args[i]->print(str, query_type);
434
  }
435
  str->append(')');
436
}
437
438
void Item_sum::fix_num_length_and_dec()
439
{
440
  decimals=0;
441
  for (uint i=0 ; i < arg_count ; i++)
442
    set_if_bigger(decimals,args[i]->decimals);
443
  max_length=float_length(decimals);
444
}
445
446
Item *Item_sum::get_tmp_table_item(THD *thd)
447
{
448
  Item_sum* sum_item= (Item_sum *) copy_or_same(thd);
449
  if (sum_item && sum_item->result_field)	   // If not a const sum func
450
  {
451
    Field *result_field_tmp= sum_item->result_field;
452
    for (uint i=0 ; i < sum_item->arg_count ; i++)
453
    {
454
      Item *arg= sum_item->args[i];
455
      if (!arg->const_item())
456
      {
457
	if (arg->type() == Item::FIELD_ITEM)
458
	  ((Item_field*) arg)->field= result_field_tmp++;
459
	else
460
	  sum_item->args[i]= new Item_field(result_field_tmp++);
461
      }
462
    }
463
  }
464
  return sum_item;
465
}
466
467
468
bool Item_sum::walk (Item_processor processor, bool walk_subquery,
469
                     uchar *argument)
470
{
471
  if (arg_count)
472
  {
473
    Item **arg,**arg_end;
474
    for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
475
    {
476
      if ((*arg)->walk(processor, walk_subquery, argument))
477
	return 1;
478
    }
479
  }
480
  return (this->*processor)(argument);
481
}
482
483
77.1.15 by Monty Taylor
Bunch of warning cleanups.
484
Field *Item_sum::create_tmp_field(bool group __attribute__((__unused__)),
485
                                  TABLE *table,
1 by brian
clean slate
486
                                  uint convert_blob_length)
487
{
488
  Field *field;
489
  switch (result_type()) {
490
  case REAL_RESULT:
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
491
    field= new Field_double(max_length, maybe_null, name, decimals, true);
1 by brian
clean slate
492
    break;
493
  case INT_RESULT:
152 by Brian Aker
longlong replacement
494
    field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
1 by brian
clean slate
495
    break;
496
  case STRING_RESULT:
497
    if (max_length/collation.collation->mbmaxlen <= 255 ||
498
        convert_blob_length > Field_varstring::MAX_SIZE ||
499
        !convert_blob_length)
500
      return make_string_field(table);
501
    field= new Field_varstring(convert_blob_length, maybe_null,
502
                               name, table->s, collation.collation);
503
    break;
504
  case DECIMAL_RESULT:
505
    field= new Field_new_decimal(max_length, maybe_null, name,
506
                                 decimals, unsigned_flag);
507
    break;
508
  case ROW_RESULT:
509
  default:
510
    // This case should never be choosen
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
511
    assert(0);
1 by brian
clean slate
512
    return 0;
513
  }
514
  if (field)
515
    field->init(table);
516
  return field;
517
}
518
519
520
void Item_sum::update_used_tables ()
521
{
522
  if (!forced_const)
523
  {
524
    used_tables_cache= 0;
525
    for (uint i=0 ; i < arg_count ; i++)
526
    {
527
      args[i]->update_used_tables();
528
      used_tables_cache|= args[i]->used_tables();
529
    }
530
531
    used_tables_cache&= PSEUDO_TABLE_BITS;
532
533
    /* the aggregate function is aggregated into its local context */
534
    used_tables_cache |=  (1 << aggr_sel->join->tables) - 1;
535
  }
536
}
537
538
539
String *
540
Item_sum_num::val_str(String *str)
541
{
542
  return val_string_from_real(str);
543
}
544
545
546
my_decimal *Item_sum_num::val_decimal(my_decimal *decimal_value)
547
{
548
  return val_decimal_from_real(decimal_value);
549
}
550
551
552
String *
553
Item_sum_int::val_str(String *str)
554
{
555
  return val_string_from_int(str);
556
}
557
558
559
my_decimal *Item_sum_int::val_decimal(my_decimal *decimal_value)
560
{
561
  return val_decimal_from_int(decimal_value);
562
}
563
564
565
bool
566
Item_sum_num::fix_fields(THD *thd, Item **ref)
567
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
568
  assert(fixed == 0);
1 by brian
clean slate
569
570
  if (init_sum_func_check(thd))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
571
    return true;
1 by brian
clean slate
572
573
  decimals=0;
574
  maybe_null=0;
575
  for (uint i=0 ; i < arg_count ; i++)
576
  {
577
    if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
578
      return true;
1 by brian
clean slate
579
    set_if_bigger(decimals, args[i]->decimals);
580
    maybe_null |= args[i]->maybe_null;
581
  }
582
  result_field=0;
583
  max_length=float_length(decimals);
584
  null_value=1;
585
  fix_length_and_dec();
586
587
  if (check_sum_func(thd, ref))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
588
    return true;
1 by brian
clean slate
589
590
  fixed= 1;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
591
  return false;
1 by brian
clean slate
592
}
593
594
595
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
596
  :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
597
  hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
598
  was_values(item->was_values)
599
{
600
  /* copy results from old value */
601
  switch (hybrid_type) {
602
  case INT_RESULT:
603
    sum_int= item->sum_int;
604
    break;
605
  case DECIMAL_RESULT:
606
    my_decimal2decimal(&item->sum_dec, &sum_dec);
607
    break;
608
  case REAL_RESULT:
609
    sum= item->sum;
610
    break;
611
  case STRING_RESULT:
612
    /*
613
      This can happen with ROLLUP. Note that the value is already
614
      copied at function call.
615
    */
616
    break;
617
  case ROW_RESULT:
618
  default:
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
619
    assert(0);
1 by brian
clean slate
620
  }
621
  collation.set(item->collation);
622
}
623
624
bool
625
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
626
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
627
  assert(fixed == 0);
1 by brian
clean slate
628
629
  Item *item= args[0];
630
631
  if (init_sum_func_check(thd))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
632
    return true;
1 by brian
clean slate
633
634
  // 'item' can be changed during fix_fields
635
  if ((!item->fixed && item->fix_fields(thd, args)) ||
636
      (item= args[0])->check_cols(1))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
637
    return true;
1 by brian
clean slate
638
  decimals=item->decimals;
639
640
  switch (hybrid_type= item->result_type()) {
641
  case INT_RESULT:
642
    max_length= 20;
643
    sum_int= 0;
644
    break;
645
  case DECIMAL_RESULT:
646
    max_length= item->max_length;
647
    my_decimal_set_zero(&sum_dec);
648
    break;
649
  case REAL_RESULT:
650
    max_length= float_length(decimals);
651
    sum= 0.0;
652
    break;
653
  case STRING_RESULT:
654
    max_length= item->max_length;
655
    break;
656
  case ROW_RESULT:
657
  default:
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
658
    assert(0);
1 by brian
clean slate
659
  };
660
  /* MIN/MAX can return NULL for empty set indepedent of the used column */
661
  maybe_null= 1;
662
  unsigned_flag=item->unsigned_flag;
663
  collation.set(item->collation);
664
  result_field=0;
665
  null_value=1;
666
  fix_length_and_dec();
667
  item= item->real_item();
668
  if (item->type() == Item::FIELD_ITEM)
669
    hybrid_field_type= ((Item_field*) item)->field->type();
670
  else
671
    hybrid_field_type= Item::field_type();
672
673
  if (check_sum_func(thd, ref))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
674
    return true;
1 by brian
clean slate
675
676
  fixed= 1;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
677
  return false;
1 by brian
clean slate
678
}
679
680
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
681
					 uint convert_blob_length)
682
{
683
  Field *field;
684
  if (args[0]->type() == Item::FIELD_ITEM)
685
  {
686
    field= ((Item_field*) args[0])->field;
687
    
688
    if ((field= create_tmp_field_from_field(current_thd, field, name, table,
689
					    NULL, convert_blob_length)))
690
      field->flags&= ~NOT_NULL_FLAG;
691
    return field;
692
  }
693
  /*
694
    DATE/TIME fields have STRING_RESULT result types.
695
    In order to preserve field type, it's needed to handle DATE/TIME
696
    fields creations separately.
697
  */
698
  switch (args[0]->field_type()) {
97 by Brian Aker
DATE cleanup.
699
  case MYSQL_TYPE_NEWDATE:
1 by brian
clean slate
700
    field= new Field_newdate(maybe_null, name, collation.collation);
701
    break;
702
  case MYSQL_TYPE_TIME:
703
    field= new Field_time(maybe_null, name, collation.collation);
704
    break;
705
  case MYSQL_TYPE_TIMESTAMP:
706
  case MYSQL_TYPE_DATETIME:
707
    field= new Field_datetime(maybe_null, name, collation.collation);
708
    break;
709
  default:
710
    return Item_sum::create_tmp_field(group, table, convert_blob_length);
711
  }
712
  if (field)
713
    field->init(table);
714
  return field;
715
}
716
717
718
/***********************************************************************
719
** reset and add of sum_func
720
***********************************************************************/
721
722
/**
723
  @todo
724
  check if the following assignments are really needed
725
*/
726
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item) 
727
  :Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
728
   curr_dec_buff(item->curr_dec_buff)
729
{
730
  /* TODO: check if the following assignments are really needed */
731
  if (hybrid_type == DECIMAL_RESULT)
732
  {
733
    my_decimal2decimal(item->dec_buffs, dec_buffs);
734
    my_decimal2decimal(item->dec_buffs + 1, dec_buffs + 1);
735
  }
736
  else
737
    sum= item->sum;
738
}
739
740
Item *Item_sum_sum::copy_or_same(THD* thd)
741
{
742
  return new (thd->mem_root) Item_sum_sum(thd, this);
743
}
744
745
746
void Item_sum_sum::clear()
747
{
748
  null_value=1;
749
  if (hybrid_type == DECIMAL_RESULT)
750
  {
751
    curr_dec_buff= 0;
752
    my_decimal_set_zero(dec_buffs);
753
  }
754
  else
755
    sum= 0.0;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
756
  return;
1 by brian
clean slate
757
}
758
759
760
void Item_sum_sum::fix_length_and_dec()
761
{
762
  maybe_null=null_value=1;
763
  decimals= args[0]->decimals;
764
  switch (args[0]->result_type()) {
765
  case REAL_RESULT:
766
  case STRING_RESULT:
767
    hybrid_type= REAL_RESULT;
768
    sum= 0.0;
769
    break;
770
  case INT_RESULT:
771
  case DECIMAL_RESULT:
772
  {
773
    /* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
774
    int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
775
    max_length= my_decimal_precision_to_length(precision, decimals,
776
                                               unsigned_flag);
777
    curr_dec_buff= 0;
778
    hybrid_type= DECIMAL_RESULT;
779
    my_decimal_set_zero(dec_buffs);
780
    break;
781
  }
782
  case ROW_RESULT:
783
  default:
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
784
    assert(0);
1 by brian
clean slate
785
  }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
786
  return;
1 by brian
clean slate
787
}
788
789
790
bool Item_sum_sum::add()
791
{
792
  if (hybrid_type == DECIMAL_RESULT)
793
  {
794
    my_decimal value, *val= args[0]->val_decimal(&value);
795
    if (!args[0]->null_value)
796
    {
797
      my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1),
798
                     val, dec_buffs + curr_dec_buff);
799
      curr_dec_buff^= 1;
800
      null_value= 0;
801
    }
802
  }
803
  else
804
  {
805
    sum+= args[0]->val_real();
806
    if (!args[0]->null_value)
807
      null_value= 0;
808
  }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
809
  return(0);
1 by brian
clean slate
810
}
811
812
152 by Brian Aker
longlong replacement
813
int64_t Item_sum_sum::val_int()
1 by brian
clean slate
814
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
815
  assert(fixed == 1);
1 by brian
clean slate
816
  if (hybrid_type == DECIMAL_RESULT)
817
  {
152 by Brian Aker
longlong replacement
818
    int64_t result;
1 by brian
clean slate
819
    my_decimal2int(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, unsigned_flag,
820
                   &result);
821
    return result;
822
  }
152 by Brian Aker
longlong replacement
823
  return (int64_t) rint(val_real());
1 by brian
clean slate
824
}
825
826
827
double Item_sum_sum::val_real()
828
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
829
  assert(fixed == 1);
1 by brian
clean slate
830
  if (hybrid_type == DECIMAL_RESULT)
831
    my_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum);
832
  return sum;
833
}
834
835
836
String *Item_sum_sum::val_str(String *str)
837
{
838
  if (hybrid_type == DECIMAL_RESULT)
839
    return val_string_from_decimal(str);
840
  return val_string_from_real(str);
841
}
842
843
844
my_decimal *Item_sum_sum::val_decimal(my_decimal *val)
845
{
846
  if (hybrid_type == DECIMAL_RESULT)
847
    return (dec_buffs + curr_dec_buff);
848
  return val_decimal_from_real(val);
849
}
850
851
/***************************************************************************/
852
853
C_MODE_START
854
855
/* Declarations for auxilary C-callbacks */
856
857
static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
858
{
859
    return memcmp(key1, key2, *(uint *) arg);
860
}
861
862
77.1.15 by Monty Taylor
Bunch of warning cleanups.
863
static int item_sum_distinct_walk(void *element,
864
                                  element_count num_of_dups __attribute__((__unused__)),
1 by brian
clean slate
865
                                  void *item)
866
{
867
  return ((Item_sum_distinct*) (item))->unique_walk_function(element);
868
}
869
870
C_MODE_END
871
872
/* Item_sum_distinct */
873
874
Item_sum_distinct::Item_sum_distinct(Item *item_arg)
875
  :Item_sum_num(item_arg), tree(0)
876
{
877
  /*
878
    quick_group is an optimizer hint, which means that GROUP BY can be
879
    handled with help of index on grouped columns.
880
    By setting quick_group to zero we force creation of temporary table
881
    to perform GROUP BY.
882
  */
883
  quick_group= 0;
884
}
885
886
887
Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
888
  :Item_sum_num(thd, original), val(original->val), tree(0),
889
  table_field_type(original->table_field_type)
890
{
891
  quick_group= 0;
892
}
893
894
895
/**
896
  Behaves like an Integer except to fix_length_and_dec().
897
  Additionally div() converts val with this traits to a val with true
898
  decimal traits along with conversion of integer value to decimal value.
899
  This is to speedup SUM/AVG(DISTINCT) evaluation for 8-32 bit integer
900
  values.
901
*/
902
struct Hybrid_type_traits_fast_decimal: public
903
       Hybrid_type_traits_integer
904
{
905
  virtual Item_result type() const { return DECIMAL_RESULT; }
906
  virtual void fix_length_and_dec(Item *item, Item *arg) const
907
  { Hybrid_type_traits_decimal::instance()->fix_length_and_dec(item, arg); }
908
151 by Brian Aker
Ulonglong to uint64_t
909
  virtual void div(Hybrid_type *val, uint64_t u) const
1 by brian
clean slate
910
  {
911
    int2my_decimal(E_DEC_FATAL_ERROR, val->integer, 0, val->dec_buf);
912
    val->used_dec_buf_no= 0;
913
    val->traits= Hybrid_type_traits_decimal::instance();
914
    val->traits->div(val, u);
915
  }
916
  static const Hybrid_type_traits_fast_decimal *instance();
917
  Hybrid_type_traits_fast_decimal() {};
918
};
919
920
static const Hybrid_type_traits_fast_decimal fast_decimal_traits_instance;
921
922
const Hybrid_type_traits_fast_decimal
923
  *Hybrid_type_traits_fast_decimal::instance()
924
{
925
  return &fast_decimal_traits_instance;
926
}
927
928
void Item_sum_distinct::fix_length_and_dec()
929
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
930
  assert(args[0]->fixed);
1 by brian
clean slate
931
932
  table_field_type= args[0]->field_type();
933
934
  /* Adjust tmp table type according to the chosen aggregation type */
935
  switch (args[0]->result_type()) {
936
  case STRING_RESULT:
937
  case REAL_RESULT:
938
    val.traits= Hybrid_type_traits::instance();
166 by Brian Aker
Removal of FLOAT type
939
    table_field_type= MYSQL_TYPE_DOUBLE;
1 by brian
clean slate
940
    break;
941
  case INT_RESULT:
942
  /*
943
    Preserving int8, int16, int32 field types gives ~10% performance boost
944
    as the size of result tree becomes significantly smaller.
152 by Brian Aker
longlong replacement
945
    Another speed up we gain by using int64_t for intermediate
1 by brian
clean slate
946
    calculations. The range of int64 is enough to hold sum 2^32 distinct
947
    integers each <= 2^32.
948
  */
68 by Brian Aker
Second pass remove MEDIUMINT
949
  if (table_field_type >= MYSQL_TYPE_TINY && table_field_type <= MYSQL_TYPE_LONG)
1 by brian
clean slate
950
  {
951
    val.traits= Hybrid_type_traits_fast_decimal::instance();
952
    break;
953
  }
954
  table_field_type= MYSQL_TYPE_LONGLONG;
955
  /* fallthrough */
956
  case DECIMAL_RESULT:
957
    val.traits= Hybrid_type_traits_decimal::instance();
958
    if (table_field_type != MYSQL_TYPE_LONGLONG)
959
      table_field_type= MYSQL_TYPE_NEWDECIMAL;
960
    break;
961
  case ROW_RESULT:
962
  default:
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
963
    assert(0);
1 by brian
clean slate
964
  }
965
  val.traits->fix_length_and_dec(this, args[0]);
966
}
967
968
969
/**
970
  @todo
971
  check that the case of CHAR(0) works OK
972
*/
973
bool Item_sum_distinct::setup(THD *thd)
974
{
975
  List<Create_field> field_list;
976
  Create_field field_def;                              /* field definition */
977
  /* It's legal to call setup() more than once when in a subquery */
978
  if (tree)
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
979
    return(false);
1 by brian
clean slate
980
981
  /*
982
    Virtual table and the tree are created anew on each re-execution of
983
    PS/SP. Hence all further allocations are performed in the runtime
984
    mem_root.
985
  */
986
  if (field_list.push_back(&field_def))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
987
    return(true);
1 by brian
clean slate
988
989
  null_value= maybe_null= 1;
990
  quick_group= 0;
991
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
992
  assert(args[0]->fixed);
1 by brian
clean slate
993
994
  field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
995
                               args[0]->decimals, args[0]->maybe_null,
996
                               args[0]->unsigned_flag);
997
998
  if (! (table= create_virtual_tmp_table(thd, field_list)))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
999
    return(true);
1 by brian
clean slate
1000
1001
  /* XXX: check that the case of CHAR(0) works OK */
1002
  tree_key_length= table->s->reclength - table->s->null_bytes;
1003
1004
  /*
1005
    Unique handles all unique elements in a tree until they can't fit
1006
    in.  Then the tree is dumped to the temporary file. We can use
1007
    simple_raw_key_cmp because the table contains numbers only; decimals
1008
    are converted to binary representation as well.
1009
  */
1010
  tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
1011
                   thd->variables.max_heap_table_size);
1012
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1013
  is_evaluated= false;
1014
  return(tree == 0);
1 by brian
clean slate
1015
}
1016
1017
1018
bool Item_sum_distinct::add()
1019
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1020
  args[0]->save_in_field(table->field[0], false);
1021
  is_evaluated= false;
1 by brian
clean slate
1022
  if (!table->field[0]->is_null())
1023
  {
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1024
    assert(tree);
1 by brian
clean slate
1025
    null_value= 0;
1026
    /*
1027
      '0' values are also stored in the tree. This doesn't matter
1028
      for SUM(DISTINCT), but is important for AVG(DISTINCT)
1029
    */
1030
    return tree->unique_add(table->field[0]->ptr);
1031
  }
1032
  return 0;
1033
}
1034
1035
1036
bool Item_sum_distinct::unique_walk_function(void *element)
1037
{
1038
  memcpy(table->field[0]->ptr, element, tree_key_length);
1039
  ++count;
1040
  val.traits->add(&val, table->field[0]);
1041
  return 0;
1042
}
1043
1044
1045
void Item_sum_distinct::clear()
1046
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1047
  assert(tree != 0);                        /* we always have a tree */
1 by brian
clean slate
1048
  null_value= 1;
1049
  tree->reset();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1050
  is_evaluated= false;
1051
  return;
1 by brian
clean slate
1052
}
1053
1054
void Item_sum_distinct::cleanup()
1055
{
1056
  Item_sum_num::cleanup();
1057
  delete tree;
1058
  tree= 0;
1059
  table= 0;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1060
  is_evaluated= false;
1 by brian
clean slate
1061
}
1062
1063
Item_sum_distinct::~Item_sum_distinct()
1064
{
1065
  delete tree;
1066
  /* no need to free the table */
1067
}
1068
1069
1070
void Item_sum_distinct::calculate_val_and_count()
1071
{
1072
  if (!is_evaluated)
1073
  {
1074
    count= 0;
1075
    val.traits->set_zero(&val);
1076
    /*
1077
      We don't have a tree only if 'setup()' hasn't been called;
1078
      this is the case of sql_select.cc:return_zero_rows.
1079
     */
1080
    if (tree)
1081
    {
1082
      table->field[0]->set_notnull();
1083
      tree->walk(item_sum_distinct_walk, (void*) this);
1084
    }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1085
    is_evaluated= true;
1 by brian
clean slate
1086
  }
1087
}
1088
1089
1090
double Item_sum_distinct::val_real()
1091
{
1092
  calculate_val_and_count();
1093
  return val.traits->val_real(&val);
1094
}
1095
1096
1097
my_decimal *Item_sum_distinct::val_decimal(my_decimal *to)
1098
{
1099
  calculate_val_and_count();
1100
  if (null_value)
1101
    return 0;
1102
  return val.traits->val_decimal(&val, to);
1103
}
1104
1105
152 by Brian Aker
longlong replacement
1106
int64_t Item_sum_distinct::val_int()
1 by brian
clean slate
1107
{
1108
  calculate_val_and_count();
1109
  return val.traits->val_int(&val, unsigned_flag);
1110
}
1111
1112
1113
String *Item_sum_distinct::val_str(String *str)
1114
{
1115
  calculate_val_and_count();
1116
  if (null_value)
1117
    return 0;
1118
  return val.traits->val_str(&val, str, decimals);
1119
}
1120
1121
/* end of Item_sum_distinct */
1122
1123
/* Item_sum_avg_distinct */
1124
1125
void
1126
Item_sum_avg_distinct::fix_length_and_dec()
1127
{
1128
  Item_sum_distinct::fix_length_and_dec();
1129
  prec_increment= current_thd->variables.div_precincrement;
1130
  /*
1131
    AVG() will divide val by count. We need to reserve digits
1132
    after decimal point as the result can be fractional.
1133
  */
1134
  decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
1135
}
1136
1137
1138
void
1139
Item_sum_avg_distinct::calculate_val_and_count()
1140
{
1141
  if (!is_evaluated)
1142
  {
1143
    Item_sum_distinct::calculate_val_and_count();
1144
    if (count)
1145
      val.traits->div(&val, count);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1146
    is_evaluated= true;
1 by brian
clean slate
1147
  }
1148
}
1149
1150
1151
Item *Item_sum_count::copy_or_same(THD* thd)
1152
{
1153
  return new (thd->mem_root) Item_sum_count(thd, this);
1154
}
1155
1156
1157
void Item_sum_count::clear()
1158
{
1159
  count= 0;
1160
}
1161
1162
1163
bool Item_sum_count::add()
1164
{
1165
  if (!args[0]->maybe_null || !args[0]->is_null())
1166
    count++;
1167
  return 0;
1168
}
1169
152 by Brian Aker
longlong replacement
1170
int64_t Item_sum_count::val_int()
1 by brian
clean slate
1171
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1172
  assert(fixed == 1);
152 by Brian Aker
longlong replacement
1173
  return (int64_t) count;
1 by brian
clean slate
1174
}
1175
1176
1177
void Item_sum_count::cleanup()
1178
{
1179
  count= 0;
1180
  Item_sum_int::cleanup();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1181
  return;
1 by brian
clean slate
1182
}
1183
1184
1185
/*
1186
  Avgerage
1187
*/
1188
void Item_sum_avg::fix_length_and_dec()
1189
{
1190
  Item_sum_sum::fix_length_and_dec();
1191
  maybe_null=null_value=1;
1192
  prec_increment= current_thd->variables.div_precincrement;
1193
  if (hybrid_type == DECIMAL_RESULT)
1194
  {
1195
    int precision= args[0]->decimal_precision() + prec_increment;
1196
    decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
1197
    max_length= my_decimal_precision_to_length(precision, decimals,
1198
                                               unsigned_flag);
1199
    f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1200
    f_scale=  args[0]->decimals;
1201
    dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
1202
  }
1203
  else {
1204
    decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
1205
    max_length= args[0]->max_length + prec_increment;
1206
  }
1207
}
1208
1209
1210
Item *Item_sum_avg::copy_or_same(THD* thd)
1211
{
1212
  return new (thd->mem_root) Item_sum_avg(thd, this);
1213
}
1214
1215
1216
Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table,
77.1.15 by Monty Taylor
Bunch of warning cleanups.
1217
                                      uint convert_blob_len __attribute__((__unused__)))
1 by brian
clean slate
1218
{
1219
  Field *field;
1220
  if (group)
1221
  {
1222
    /*
1223
      We must store both value and counter in the temporary table in one field.
1224
      The easiest way is to do this is to store both value in a string
1225
      and unpack on access.
1226
    */
1227
    field= new Field_string(((hybrid_type == DECIMAL_RESULT) ?
152 by Brian Aker
longlong replacement
1228
                             dec_bin_size : sizeof(double)) + sizeof(int64_t),
1 by brian
clean slate
1229
                            0, name, &my_charset_bin);
1230
  }
1231
  else if (hybrid_type == DECIMAL_RESULT)
1232
    field= new Field_new_decimal(max_length, maybe_null, name,
1233
                                 decimals, unsigned_flag);
1234
  else
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1235
    field= new Field_double(max_length, maybe_null, name, decimals, true);
1 by brian
clean slate
1236
  if (field)
1237
    field->init(table);
1238
  return field;
1239
}
1240
1241
1242
void Item_sum_avg::clear()
1243
{
1244
  Item_sum_sum::clear();
1245
  count=0;
1246
}
1247
1248
1249
bool Item_sum_avg::add()
1250
{
1251
  if (Item_sum_sum::add())
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1252
    return true;
1 by brian
clean slate
1253
  if (!args[0]->null_value)
1254
    count++;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1255
  return false;
1 by brian
clean slate
1256
}
1257
1258
double Item_sum_avg::val_real()
1259
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1260
  assert(fixed == 1);
1 by brian
clean slate
1261
  if (!count)
1262
  {
1263
    null_value=1;
1264
    return 0.0;
1265
  }
151 by Brian Aker
Ulonglong to uint64_t
1266
  return Item_sum_sum::val_real() / uint64_t2double(count);
1 by brian
clean slate
1267
}
1268
1269
1270
my_decimal *Item_sum_avg::val_decimal(my_decimal *val)
1271
{
1272
  my_decimal sum_buff, cnt;
1273
  const my_decimal *sum_dec;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1274
  assert(fixed == 1);
1 by brian
clean slate
1275
  if (!count)
1276
  {
1277
    null_value=1;
1278
    return NULL;
1279
  }
1280
1281
  /*
1282
    For non-DECIMAL hybrid_type the division will be done in
1283
    Item_sum_avg::val_real().
1284
  */
1285
  if (hybrid_type != DECIMAL_RESULT)
1286
    return val_decimal_from_real(val);
1287
1288
  sum_dec= dec_buffs + curr_dec_buff;
1289
  int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &cnt);
1290
  my_decimal_div(E_DEC_FATAL_ERROR, val, sum_dec, &cnt, prec_increment);
1291
  return val;
1292
}
1293
1294
1295
String *Item_sum_avg::val_str(String *str)
1296
{
1297
  if (hybrid_type == DECIMAL_RESULT)
1298
    return val_string_from_decimal(str);
1299
  return val_string_from_real(str);
1300
}
1301
1302
1303
/*
1304
  Standard deviation
1305
*/
1306
1307
double Item_sum_std::val_real()
1308
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1309
  assert(fixed == 1);
1 by brian
clean slate
1310
  double nr= Item_sum_variance::val_real();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1311
  assert(nr >= 0.0);
1 by brian
clean slate
1312
  return sqrt(nr);
1313
}
1314
1315
Item *Item_sum_std::copy_or_same(THD* thd)
1316
{
1317
  return new (thd->mem_root) Item_sum_std(thd, this);
1318
}
1319
1320
1321
/*
1322
  Variance
1323
*/
1324
1325
1326
/**
1327
  Variance implementation for floating-point implementations, without
1328
  catastrophic cancellation, from Knuth's _TAoCP_, 3rd ed, volume 2, pg232.
1329
  This alters the value at m, s, and increments count.
1330
*/
1331
1332
/*
1333
  These two functions are used by the Item_sum_variance and the
1334
  Item_variance_field classes, which are unrelated, and each need to calculate
1335
  variance.  The difference between the two classes is that the first is used
1336
  for a mundane SELECT, while the latter is used in a GROUPing SELECT.
1337
*/
151 by Brian Aker
Ulonglong to uint64_t
1338
static void variance_fp_recurrence_next(double *m, double *s, uint64_t *count, double nr)
1 by brian
clean slate
1339
{
1340
  *count += 1;
1341
1342
  if (*count == 1) 
1343
  {
1344
    *m= nr;
1345
    *s= 0;
1346
  }
1347
  else
1348
  {
1349
    double m_kminusone= *m;
1350
    *m= m_kminusone + (nr - m_kminusone) / (double) *count;
1351
    *s= *s + (nr - m_kminusone) * (nr - *m);
1352
  }
1353
}
1354
1355
151 by Brian Aker
Ulonglong to uint64_t
1356
static double variance_fp_recurrence_result(double s, uint64_t count, bool is_sample_variance)
1 by brian
clean slate
1357
{
1358
  if (count == 1)
1359
    return 0.0;
1360
1361
  if (is_sample_variance)
1362
    return s / (count - 1);
1363
1364
  /* else, is a population variance */
1365
  return s / count;
1366
}
1367
1368
1369
Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item):
1370
  Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
1371
    count(item->count), sample(item->sample),
1372
    prec_increment(item->prec_increment)
1373
{
1374
  recurrence_m= item->recurrence_m;
1375
  recurrence_s= item->recurrence_s;
1376
}
1377
1378
1379
void Item_sum_variance::fix_length_and_dec()
1380
{
1381
  maybe_null= null_value= 1;
1382
  prec_increment= current_thd->variables.div_precincrement;
1383
1384
  /*
1385
    According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
1386
    aggregate function; paragraph 7h of Syntax Rules), "the declared 
1387
    type of the result is an implementation-defined aproximate numeric
1388
    type.
1389
  */
1390
  hybrid_type= REAL_RESULT;
1391
1392
  switch (args[0]->result_type()) {
1393
  case REAL_RESULT:
1394
  case STRING_RESULT:
1395
    decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
1396
    break;
1397
  case INT_RESULT:
1398
  case DECIMAL_RESULT:
1399
  {
1400
    int precision= args[0]->decimal_precision()*2 + prec_increment;
1401
    decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
1402
    max_length= my_decimal_precision_to_length(precision, decimals,
1403
                                               unsigned_flag);
1404
1405
    break;
1406
  }
1407
  case ROW_RESULT:
1408
  default:
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1409
    assert(0);
1 by brian
clean slate
1410
  }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1411
  return;
1 by brian
clean slate
1412
}
1413
1414
1415
Item *Item_sum_variance::copy_or_same(THD* thd)
1416
{
1417
  return new (thd->mem_root) Item_sum_variance(thd, this);
1418
}
1419
1420
1421
/**
1422
  Create a new field to match the type of value we're expected to yield.
1423
  If we're grouping, then we need some space to serialize variables into, to
1424
  pass around.
1425
*/
1426
Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table,
77.1.15 by Monty Taylor
Bunch of warning cleanups.
1427
                                           uint convert_blob_len __attribute__((__unused__)))
1 by brian
clean slate
1428
{
1429
  Field *field;
1430
  if (group)
1431
  {
1432
    /*
1433
      We must store both value and counter in the temporary table in one field.
1434
      The easiest way is to do this is to store both value in a string
1435
      and unpack on access.
1436
    */
152 by Brian Aker
longlong replacement
1437
    field= new Field_string(sizeof(double)*2 + sizeof(int64_t), 0, name, &my_charset_bin);
1 by brian
clean slate
1438
  }
1439
  else
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1440
    field= new Field_double(max_length, maybe_null, name, decimals, true);
1 by brian
clean slate
1441
1442
  if (field != NULL)
1443
    field->init(table);
1444
1445
  return field;
1446
}
1447
1448
1449
void Item_sum_variance::clear()
1450
{
1451
  count= 0; 
1452
}
1453
1454
bool Item_sum_variance::add()
1455
{
1456
  /* 
1457
    Why use a temporary variable?  We don't know if it is null until we
1458
    evaluate it, which has the side-effect of setting null_value .
1459
  */
1460
  double nr= args[0]->val_real();
1461
  
1462
  if (!args[0]->null_value)
1463
    variance_fp_recurrence_next(&recurrence_m, &recurrence_s, &count, nr);
1464
  return 0;
1465
}
1466
1467
double Item_sum_variance::val_real()
1468
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1469
  assert(fixed == 1);
1 by brian
clean slate
1470
1471
  /*
1472
    'sample' is a 1/0 boolean value.  If it is 1/true, id est this is a sample
1473
    variance call, then we should set nullness when the count of the items
1474
    is one or zero.  If it's zero, i.e. a population variance, then we only
1475
    set nullness when the count is zero.
1476
1477
    Another way to read it is that 'sample' is the numerical threshhold, at and
1478
    below which a 'count' number of items is called NULL.
1479
  */
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1480
  assert((sample == 0) || (sample == 1));
1 by brian
clean slate
1481
  if (count <= sample)
1482
  {
1483
    null_value=1;
1484
    return 0.0;
1485
  }
1486
1487
  null_value=0;
1488
  return variance_fp_recurrence_result(recurrence_s, count, sample);
1489
}
1490
1491
1492
my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf)
1493
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1494
  assert(fixed == 1);
1 by brian
clean slate
1495
  return val_decimal_from_real(dec_buf);
1496
}
1497
1498
1499
void Item_sum_variance::reset_field()
1500
{
1501
  double nr;
1502
  uchar *res= result_field->ptr;
1503
1504
  nr= args[0]->val_real();              /* sets null_value as side-effect */
1505
1506
  if (args[0]->null_value)
152 by Brian Aker
longlong replacement
1507
    bzero(res,sizeof(double)*2+sizeof(int64_t));
1 by brian
clean slate
1508
  else
1509
  {
152 by Brian Aker
longlong replacement
1510
    /* Serialize format is (double)m, (double)s, (int64_t)count */
151 by Brian Aker
Ulonglong to uint64_t
1511
    uint64_t tmp_count;
1 by brian
clean slate
1512
    double tmp_s;
1513
    float8store(res, nr);               /* recurrence variable m */
1514
    tmp_s= 0.0;
1515
    float8store(res + sizeof(double), tmp_s);
1516
    tmp_count= 1;
1517
    int8store(res + sizeof(double)*2, tmp_count);
1518
  }
1519
}
1520
1521
1522
void Item_sum_variance::update_field()
1523
{
151 by Brian Aker
Ulonglong to uint64_t
1524
  uint64_t field_count;
1 by brian
clean slate
1525
  uchar *res=result_field->ptr;
1526
1527
  double nr= args[0]->val_real();       /* sets null_value as side-effect */
1528
1529
  if (args[0]->null_value)
1530
    return;
1531
152 by Brian Aker
longlong replacement
1532
  /* Serialize format is (double)m, (double)s, (int64_t)count */
1 by brian
clean slate
1533
  double field_recurrence_m, field_recurrence_s;
1534
  float8get(field_recurrence_m, res);
1535
  float8get(field_recurrence_s, res + sizeof(double));
1536
  field_count=sint8korr(res+sizeof(double)*2);
1537
1538
  variance_fp_recurrence_next(&field_recurrence_m, &field_recurrence_s, &field_count, nr);
1539
1540
  float8store(res, field_recurrence_m);
1541
  float8store(res + sizeof(double), field_recurrence_s);
1542
  res+= sizeof(double)*2;
1543
  int8store(res,field_count);
1544
}
1545
1546
1547
/* min & max */
1548
1549
void Item_sum_hybrid::clear()
1550
{
1551
  switch (hybrid_type) {
1552
  case INT_RESULT:
1553
    sum_int= 0;
1554
    break;
1555
  case DECIMAL_RESULT:
1556
    my_decimal_set_zero(&sum_dec);
1557
    break;
1558
  case REAL_RESULT:
1559
    sum= 0.0;
1560
    break;
1561
  default:
1562
    value.length(0);
1563
  }
1564
  null_value= 1;
1565
}
1566
1567
double Item_sum_hybrid::val_real()
1568
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1569
  assert(fixed == 1);
1 by brian
clean slate
1570
  if (null_value)
1571
    return 0.0;
1572
  switch (hybrid_type) {
1573
  case STRING_RESULT:
1574
  {
1575
    char *end_not_used;
1576
    int err_not_used;
1577
    String *res;  res=val_str(&str_value);
1578
    return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
1579
			     &end_not_used, &err_not_used) : 0.0);
1580
  }
1581
  case INT_RESULT:
1582
    if (unsigned_flag)
151 by Brian Aker
Ulonglong to uint64_t
1583
      return uint64_t2double(sum_int);
1 by brian
clean slate
1584
    return (double) sum_int;
1585
  case DECIMAL_RESULT:
1586
    my_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
1587
    return sum;
1588
  case REAL_RESULT:
1589
    return sum;
1590
  case ROW_RESULT:
1591
  default:
1592
    // This case should never be choosen
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1593
    assert(0);
1 by brian
clean slate
1594
    return 0;
1595
  }
1596
}
1597
152 by Brian Aker
longlong replacement
1598
int64_t Item_sum_hybrid::val_int()
1 by brian
clean slate
1599
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1600
  assert(fixed == 1);
1 by brian
clean slate
1601
  if (null_value)
1602
    return 0;
1603
  switch (hybrid_type) {
1604
  case INT_RESULT:
1605
    return sum_int;
1606
  case DECIMAL_RESULT:
1607
  {
152 by Brian Aker
longlong replacement
1608
    int64_t result;
1 by brian
clean slate
1609
    my_decimal2int(E_DEC_FATAL_ERROR, &sum_dec, unsigned_flag, &result);
1610
    return sum_int;
1611
  }
1612
  default:
152 by Brian Aker
longlong replacement
1613
    return (int64_t) rint(Item_sum_hybrid::val_real());
1 by brian
clean slate
1614
  }
1615
}
1616
1617
1618
my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
1619
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1620
  assert(fixed == 1);
1 by brian
clean slate
1621
  if (null_value)
1622
    return 0;
1623
  switch (hybrid_type) {
1624
  case STRING_RESULT:
1625
    string2my_decimal(E_DEC_FATAL_ERROR, &value, val);
1626
    break;
1627
  case REAL_RESULT:
1628
    double2my_decimal(E_DEC_FATAL_ERROR, sum, val);
1629
    break;
1630
  case DECIMAL_RESULT:
1631
    val= &sum_dec;
1632
    break;
1633
  case INT_RESULT:
1634
    int2my_decimal(E_DEC_FATAL_ERROR, sum_int, unsigned_flag, val);
1635
    break;
1636
  case ROW_RESULT:
1637
  default:
1638
    // This case should never be choosen
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1639
    assert(0);
1 by brian
clean slate
1640
    break;
1641
  }
1642
  return val;					// Keep compiler happy
1643
}
1644
1645
1646
String *
1647
Item_sum_hybrid::val_str(String *str)
1648
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1649
  assert(fixed == 1);
1 by brian
clean slate
1650
  if (null_value)
1651
    return 0;
1652
  switch (hybrid_type) {
1653
  case STRING_RESULT:
1654
    return &value;
1655
  case REAL_RESULT:
1656
    str->set_real(sum,decimals, &my_charset_bin);
1657
    break;
1658
  case DECIMAL_RESULT:
1659
    my_decimal2string(E_DEC_FATAL_ERROR, &sum_dec, 0, 0, 0, str);
1660
    return str;
1661
  case INT_RESULT:
1662
    str->set_int(sum_int, unsigned_flag, &my_charset_bin);
1663
    break;
1664
  case ROW_RESULT:
1665
  default:
1666
    // This case should never be choosen
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1667
    assert(0);
1 by brian
clean slate
1668
    break;
1669
  }
1670
  return str;					// Keep compiler happy
1671
}
1672
1673
1674
void Item_sum_hybrid::cleanup()
1675
{
1676
  Item_sum::cleanup();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1677
  forced_const= false;
1 by brian
clean slate
1678
1679
  /*
1680
    by default it is TRUE to avoid TRUE reporting by
1681
    Item_func_not_all/Item_func_nop_all if this item was never called.
1682
1683
    no_rows_in_result() set it to FALSE if was not results found.
1684
    If some results found it will be left unchanged.
1685
  */
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1686
  was_values= true;
1687
  return;
1 by brian
clean slate
1688
}
1689
1690
void Item_sum_hybrid::no_rows_in_result()
1691
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1692
  was_values= false;
1 by brian
clean slate
1693
  clear();
1694
}
1695
1696
1697
Item *Item_sum_min::copy_or_same(THD* thd)
1698
{
1699
  return new (thd->mem_root) Item_sum_min(thd, this);
1700
}
1701
1702
1703
bool Item_sum_min::add()
1704
{
1705
  switch (hybrid_type) {
1706
  case STRING_RESULT:
1707
  {
1708
    String *result=args[0]->val_str(&tmp_value);
1709
    if (!args[0]->null_value &&
1710
	(null_value || sortcmp(&value,result,collation.collation) > 0))
1711
    {
1712
      value.copy(*result);
1713
      null_value=0;
1714
    }
1715
  }
1716
  break;
1717
  case INT_RESULT:
1718
  {
152 by Brian Aker
longlong replacement
1719
    int64_t nr=args[0]->val_int();
1 by brian
clean slate
1720
    if (!args[0]->null_value && (null_value ||
1721
				 (unsigned_flag && 
151 by Brian Aker
Ulonglong to uint64_t
1722
				  (uint64_t) nr < (uint64_t) sum_int) ||
1 by brian
clean slate
1723
				 (!unsigned_flag && nr < sum_int)))
1724
    {
1725
      sum_int=nr;
1726
      null_value=0;
1727
    }
1728
  }
1729
  break;
1730
  case DECIMAL_RESULT:
1731
  {
1732
    my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1733
    if (!args[0]->null_value &&
1734
        (null_value || (my_decimal_cmp(&sum_dec, val) > 0)))
1735
    {
1736
      my_decimal2decimal(val, &sum_dec);
1737
      null_value= 0;
1738
    }
1739
  }
1740
  break;
1741
  case REAL_RESULT:
1742
  {
1743
    double nr= args[0]->val_real();
1744
    if (!args[0]->null_value && (null_value || nr < sum))
1745
    {
1746
      sum=nr;
1747
      null_value=0;
1748
    }
1749
  }
1750
  break;
1751
  case ROW_RESULT:
1752
  default:
1753
    // This case should never be choosen
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1754
    assert(0);
1 by brian
clean slate
1755
    break;
1756
  }
1757
  return 0;
1758
}
1759
1760
1761
Item *Item_sum_max::copy_or_same(THD* thd)
1762
{
1763
  return new (thd->mem_root) Item_sum_max(thd, this);
1764
}
1765
1766
1767
bool Item_sum_max::add()
1768
{
1769
  switch (hybrid_type) {
1770
  case STRING_RESULT:
1771
  {
1772
    String *result=args[0]->val_str(&tmp_value);
1773
    if (!args[0]->null_value &&
1774
	(null_value || sortcmp(&value,result,collation.collation) < 0))
1775
    {
1776
      value.copy(*result);
1777
      null_value=0;
1778
    }
1779
  }
1780
  break;
1781
  case INT_RESULT:
1782
  {
152 by Brian Aker
longlong replacement
1783
    int64_t nr=args[0]->val_int();
1 by brian
clean slate
1784
    if (!args[0]->null_value && (null_value ||
1785
				 (unsigned_flag && 
151 by Brian Aker
Ulonglong to uint64_t
1786
				  (uint64_t) nr > (uint64_t) sum_int) ||
1 by brian
clean slate
1787
				 (!unsigned_flag && nr > sum_int)))
1788
    {
1789
      sum_int=nr;
1790
      null_value=0;
1791
    }
1792
  }
1793
  break;
1794
  case DECIMAL_RESULT:
1795
  {
1796
    my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1797
    if (!args[0]->null_value &&
1798
        (null_value || (my_decimal_cmp(val, &sum_dec) > 0)))
1799
    {
1800
      my_decimal2decimal(val, &sum_dec);
1801
      null_value= 0;
1802
    }
1803
  }
1804
  break;
1805
  case REAL_RESULT:
1806
  {
1807
    double nr= args[0]->val_real();
1808
    if (!args[0]->null_value && (null_value || nr > sum))
1809
    {
1810
      sum=nr;
1811
      null_value=0;
1812
    }
1813
  }
1814
  break;
1815
  case ROW_RESULT:
1816
  default:
1817
    // This case should never be choosen
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1818
    assert(0);
1 by brian
clean slate
1819
    break;
1820
  }
1821
  return 0;
1822
}
1823
1824
1825
/* bit_or and bit_and */
1826
152 by Brian Aker
longlong replacement
1827
int64_t Item_sum_bit::val_int()
1 by brian
clean slate
1828
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1829
  assert(fixed == 1);
152 by Brian Aker
longlong replacement
1830
  return (int64_t) bits;
1 by brian
clean slate
1831
}
1832
1833
1834
void Item_sum_bit::clear()
1835
{
1836
  bits= reset_bits;
1837
}
1838
1839
Item *Item_sum_or::copy_or_same(THD* thd)
1840
{
1841
  return new (thd->mem_root) Item_sum_or(thd, this);
1842
}
1843
1844
1845
bool Item_sum_or::add()
1846
{
151 by Brian Aker
Ulonglong to uint64_t
1847
  uint64_t value= (uint64_t) args[0]->val_int();
1 by brian
clean slate
1848
  if (!args[0]->null_value)
1849
    bits|=value;
1850
  return 0;
1851
}
1852
1853
Item *Item_sum_xor::copy_or_same(THD* thd)
1854
{
1855
  return new (thd->mem_root) Item_sum_xor(thd, this);
1856
}
1857
1858
1859
bool Item_sum_xor::add()
1860
{
151 by Brian Aker
Ulonglong to uint64_t
1861
  uint64_t value= (uint64_t) args[0]->val_int();
1 by brian
clean slate
1862
  if (!args[0]->null_value)
1863
    bits^=value;
1864
  return 0;
1865
}
1866
1867
Item *Item_sum_and::copy_or_same(THD* thd)
1868
{
1869
  return new (thd->mem_root) Item_sum_and(thd, this);
1870
}
1871
1872
1873
bool Item_sum_and::add()
1874
{
151 by Brian Aker
Ulonglong to uint64_t
1875
  uint64_t value= (uint64_t) args[0]->val_int();
1 by brian
clean slate
1876
  if (!args[0]->null_value)
1877
    bits&=value;
1878
  return 0;
1879
}
1880
1881
/************************************************************************
1882
** reset result of a Item_sum with is saved in a tmp_table
1883
*************************************************************************/
1884
1885
void Item_sum_num::reset_field()
1886
{
1887
  double nr= args[0]->val_real();
1888
  uchar *res=result_field->ptr;
1889
1890
  if (maybe_null)
1891
  {
1892
    if (args[0]->null_value)
1893
    {
1894
      nr=0.0;
1895
      result_field->set_null();
1896
    }
1897
    else
1898
      result_field->set_notnull();
1899
  }
1900
  float8store(res,nr);
1901
}
1902
1903
1904
void Item_sum_hybrid::reset_field()
1905
{
1906
  switch(hybrid_type) {
1907
  case STRING_RESULT:
1908
  {
1909
    char buff[MAX_FIELD_WIDTH];
1910
    String tmp(buff,sizeof(buff),result_field->charset()),*res;
1911
1912
    res=args[0]->val_str(&tmp);
1913
    if (args[0]->null_value)
1914
    {
1915
      result_field->set_null();
1916
      result_field->reset();
1917
    }
1918
    else
1919
    {
1920
      result_field->set_notnull();
1921
      result_field->store(res->ptr(),res->length(),tmp.charset());
1922
    }
1923
    break;
1924
  }
1925
  case INT_RESULT:
1926
  {
152 by Brian Aker
longlong replacement
1927
    int64_t nr=args[0]->val_int();
1 by brian
clean slate
1928
1929
    if (maybe_null)
1930
    {
1931
      if (args[0]->null_value)
1932
      {
1933
	nr=0;
1934
	result_field->set_null();
1935
      }
1936
      else
1937
	result_field->set_notnull();
1938
    }
1939
    result_field->store(nr, unsigned_flag);
1940
    break;
1941
  }
1942
  case REAL_RESULT:
1943
  {
1944
    double nr= args[0]->val_real();
1945
1946
    if (maybe_null)
1947
    {
1948
      if (args[0]->null_value)
1949
      {
1950
	nr=0.0;
1951
	result_field->set_null();
1952
      }
1953
      else
1954
	result_field->set_notnull();
1955
    }
1956
    result_field->store(nr);
1957
    break;
1958
  }
1959
  case DECIMAL_RESULT:
1960
  {
1961
    my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
1962
1963
    if (maybe_null)
1964
    {
1965
      if (args[0]->null_value)
1966
        result_field->set_null();
1967
      else
1968
        result_field->set_notnull();
1969
    }
1970
    /*
1971
      We must store zero in the field as we will use the field value in
1972
      add()
1973
    */
1974
    if (!arg_dec)                               // Null
1975
      arg_dec= &decimal_zero;
1976
    result_field->store_decimal(arg_dec);
1977
    break;
1978
  }
1979
  case ROW_RESULT:
1980
  default:
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1981
    assert(0);
1 by brian
clean slate
1982
  }
1983
}
1984
1985
1986
void Item_sum_sum::reset_field()
1987
{
1988
  if (hybrid_type == DECIMAL_RESULT)
1989
  {
1990
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
1991
    if (!arg_val)                               // Null
1992
      arg_val= &decimal_zero;
1993
    result_field->store_decimal(arg_val);
1994
  }
1995
  else
1996
  {
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1997
    assert(hybrid_type == REAL_RESULT);
1 by brian
clean slate
1998
    double nr= args[0]->val_real();			// Nulls also return 0
1999
    float8store(result_field->ptr, nr);
2000
  }
2001
  if (args[0]->null_value)
2002
    result_field->set_null();
2003
  else
2004
    result_field->set_notnull();
2005
}
2006
2007
2008
void Item_sum_count::reset_field()
2009
{
2010
  uchar *res=result_field->ptr;
152 by Brian Aker
longlong replacement
2011
  int64_t nr=0;
1 by brian
clean slate
2012
2013
  if (!args[0]->maybe_null || !args[0]->is_null())
2014
    nr=1;
2015
  int8store(res,nr);
2016
}
2017
2018
2019
void Item_sum_avg::reset_field()
2020
{
2021
  uchar *res=result_field->ptr;
2022
  if (hybrid_type == DECIMAL_RESULT)
2023
  {
152 by Brian Aker
longlong replacement
2024
    int64_t tmp;
1 by brian
clean slate
2025
    my_decimal value, *arg_dec= args[0]->val_decimal(&value);
2026
    if (args[0]->null_value)
2027
    {
2028
      arg_dec= &decimal_zero;
2029
      tmp= 0;
2030
    }
2031
    else
2032
      tmp= 1;
2033
    my_decimal2binary(E_DEC_FATAL_ERROR, arg_dec, res, f_precision, f_scale);
2034
    res+= dec_bin_size;
2035
    int8store(res, tmp);
2036
  }
2037
  else
2038
  {
2039
    double nr= args[0]->val_real();
2040
2041
    if (args[0]->null_value)
152 by Brian Aker
longlong replacement
2042
      bzero(res,sizeof(double)+sizeof(int64_t));
1 by brian
clean slate
2043
    else
2044
    {
152 by Brian Aker
longlong replacement
2045
      int64_t tmp= 1;
1 by brian
clean slate
2046
      float8store(res,nr);
2047
      res+=sizeof(double);
2048
      int8store(res,tmp);
2049
    }
2050
  }
2051
}
2052
2053
2054
void Item_sum_bit::reset_field()
2055
{
2056
  reset();
2057
  int8store(result_field->ptr, bits);
2058
}
2059
2060
void Item_sum_bit::update_field()
2061
{
2062
  uchar *res=result_field->ptr;
2063
  bits= uint8korr(res);
2064
  add();
2065
  int8store(res, bits);
2066
}
2067
2068
2069
/**
2070
  calc next value and merge it with field_value.
2071
*/
2072
2073
void Item_sum_sum::update_field()
2074
{
2075
  if (hybrid_type == DECIMAL_RESULT)
2076
  {
2077
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
2078
    if (!args[0]->null_value)
2079
    {
2080
      if (!result_field->is_null())
2081
      {
2082
        my_decimal field_value,
2083
                   *field_val= result_field->val_decimal(&field_value);
2084
        my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, field_val);
2085
        result_field->store_decimal(dec_buffs);
2086
      }
2087
      else
2088
      {
2089
        result_field->store_decimal(arg_val);
2090
        result_field->set_notnull();
2091
      }
2092
    }
2093
  }
2094
  else
2095
  {
2096
    double old_nr,nr;
2097
    uchar *res=result_field->ptr;
2098
2099
    float8get(old_nr,res);
2100
    nr= args[0]->val_real();
2101
    if (!args[0]->null_value)
2102
    {
2103
      old_nr+=nr;
2104
      result_field->set_notnull();
2105
    }
2106
    float8store(res,old_nr);
2107
  }
2108
}
2109
2110
2111
void Item_sum_count::update_field()
2112
{
152 by Brian Aker
longlong replacement
2113
  int64_t nr;
1 by brian
clean slate
2114
  uchar *res=result_field->ptr;
2115
2116
  nr=sint8korr(res);
2117
  if (!args[0]->maybe_null || !args[0]->is_null())
2118
    nr++;
2119
  int8store(res,nr);
2120
}
2121
2122
2123
void Item_sum_avg::update_field()
2124
{
152 by Brian Aker
longlong replacement
2125
  int64_t field_count;
1 by brian
clean slate
2126
  uchar *res=result_field->ptr;
2127
  if (hybrid_type == DECIMAL_RESULT)
2128
  {
2129
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
2130
    if (!args[0]->null_value)
2131
    {
2132
      binary2my_decimal(E_DEC_FATAL_ERROR, res,
2133
                        dec_buffs + 1, f_precision, f_scale);
2134
      field_count= sint8korr(res + dec_bin_size);
2135
      my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, dec_buffs + 1);
2136
      my_decimal2binary(E_DEC_FATAL_ERROR, dec_buffs,
2137
                        res, f_precision, f_scale);
2138
      res+= dec_bin_size;
2139
      field_count++;
2140
      int8store(res, field_count);
2141
    }
2142
  }
2143
  else
2144
  {
2145
    double nr;
2146
2147
    nr= args[0]->val_real();
2148
    if (!args[0]->null_value)
2149
    {
2150
      double old_nr;
2151
      float8get(old_nr, res);
2152
      field_count= sint8korr(res + sizeof(double));
2153
      old_nr+= nr;
2154
      float8store(res,old_nr);
2155
      res+= sizeof(double);
2156
      field_count++;
2157
      int8store(res, field_count);
2158
    }
2159
  }
2160
}
2161
2162
2163
void Item_sum_hybrid::update_field()
2164
{
2165
  switch (hybrid_type) {
2166
  case STRING_RESULT:
2167
    min_max_update_str_field();
2168
    break;
2169
  case INT_RESULT:
2170
    min_max_update_int_field();
2171
    break;
2172
  case DECIMAL_RESULT:
2173
    min_max_update_decimal_field();
2174
    break;
2175
  default:
2176
    min_max_update_real_field();
2177
  }
2178
}
2179
2180
2181
void
2182
Item_sum_hybrid::min_max_update_str_field()
2183
{
2184
  String *res_str=args[0]->val_str(&value);
2185
2186
  if (!args[0]->null_value)
2187
  {
2188
    result_field->val_str(&tmp_value);
2189
2190
    if (result_field->is_null() ||
2191
	(cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
2192
      result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
2193
    result_field->set_notnull();
2194
  }
2195
}
2196
2197
2198
void
2199
Item_sum_hybrid::min_max_update_real_field()
2200
{
2201
  double nr,old_nr;
2202
2203
  old_nr=result_field->val_real();
2204
  nr= args[0]->val_real();
2205
  if (!args[0]->null_value)
2206
  {
2207
    if (result_field->is_null(0) ||
2208
	(cmp_sign > 0 ? old_nr > nr : old_nr < nr))
2209
      old_nr=nr;
2210
    result_field->set_notnull();
2211
  }
2212
  else if (result_field->is_null(0))
2213
    result_field->set_null();
2214
  result_field->store(old_nr);
2215
}
2216
2217
2218
void
2219
Item_sum_hybrid::min_max_update_int_field()
2220
{
152 by Brian Aker
longlong replacement
2221
  int64_t nr,old_nr;
1 by brian
clean slate
2222
2223
  old_nr=result_field->val_int();
2224
  nr=args[0]->val_int();
2225
  if (!args[0]->null_value)
2226
  {
2227
    if (result_field->is_null(0))
2228
      old_nr=nr;
2229
    else
2230
    {
2231
      bool res=(unsigned_flag ?
151 by Brian Aker
Ulonglong to uint64_t
2232
		(uint64_t) old_nr > (uint64_t) nr :
1 by brian
clean slate
2233
		old_nr > nr);
2234
      /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
2235
      if ((cmp_sign > 0) ^ (!res))
2236
	old_nr=nr;
2237
    }
2238
    result_field->set_notnull();
2239
  }
2240
  else if (result_field->is_null(0))
2241
    result_field->set_null();
2242
  result_field->store(old_nr, unsigned_flag);
2243
}
2244
2245
2246
/**
2247
  @todo
2248
  optimize: do not get result_field in case of args[0] is NULL
2249
*/
2250
void
2251
Item_sum_hybrid::min_max_update_decimal_field()
2252
{
2253
  /* TODO: optimize: do not get result_field in case of args[0] is NULL */
2254
  my_decimal old_val, nr_val;
2255
  const my_decimal *old_nr= result_field->val_decimal(&old_val);
2256
  const my_decimal *nr= args[0]->val_decimal(&nr_val);
2257
  if (!args[0]->null_value)
2258
  {
2259
    if (result_field->is_null(0))
2260
      old_nr=nr;
2261
    else
2262
    {
2263
      bool res= my_decimal_cmp(old_nr, nr) > 0;
2264
      /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
2265
      if ((cmp_sign > 0) ^ (!res))
2266
        old_nr=nr;
2267
    }
2268
    result_field->set_notnull();
2269
  }
2270
  else if (result_field->is_null(0))
2271
    result_field->set_null();
2272
  result_field->store_decimal(old_nr);
2273
}
2274
2275
2276
Item_avg_field::Item_avg_field(Item_result res_type, Item_sum_avg *item)
2277
{
2278
  name=item->name;
2279
  decimals=item->decimals;
2280
  max_length= item->max_length;
2281
  unsigned_flag= item->unsigned_flag;
2282
  field=item->result_field;
2283
  maybe_null=1;
2284
  hybrid_type= res_type;
2285
  prec_increment= item->prec_increment;
2286
  if (hybrid_type == DECIMAL_RESULT)
2287
  {
2288
    f_scale= item->f_scale;
2289
    f_precision= item->f_precision;
2290
    dec_bin_size= item->dec_bin_size;
2291
  }
2292
}
2293
2294
double Item_avg_field::val_real()
2295
{
2296
  // fix_fields() never calls for this Item
2297
  double nr;
152 by Brian Aker
longlong replacement
2298
  int64_t count;
1 by brian
clean slate
2299
  uchar *res;
2300
2301
  if (hybrid_type == DECIMAL_RESULT)
2302
    return val_real_from_decimal();
2303
2304
  float8get(nr,field->ptr);
2305
  res= (field->ptr+sizeof(double));
2306
  count= sint8korr(res);
2307
2308
  if ((null_value= !count))
2309
    return 0.0;
2310
  return nr/(double) count;
2311
}
2312
2313
152 by Brian Aker
longlong replacement
2314
int64_t Item_avg_field::val_int()
1 by brian
clean slate
2315
{
152 by Brian Aker
longlong replacement
2316
  return (int64_t) rint(val_real());
1 by brian
clean slate
2317
}
2318
2319
2320
my_decimal *Item_avg_field::val_decimal(my_decimal *dec_buf)
2321
{
2322
  // fix_fields() never calls for this Item
2323
  if (hybrid_type == REAL_RESULT)
2324
    return val_decimal_from_real(dec_buf);
2325
152 by Brian Aker
longlong replacement
2326
  int64_t count= sint8korr(field->ptr + dec_bin_size);
1 by brian
clean slate
2327
  if ((null_value= !count))
2328
    return 0;
2329
2330
  my_decimal dec_count, dec_field;
2331
  binary2my_decimal(E_DEC_FATAL_ERROR,
2332
                    field->ptr, &dec_field, f_precision, f_scale);
2333
  int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &dec_count);
2334
  my_decimal_div(E_DEC_FATAL_ERROR, dec_buf,
2335
                 &dec_field, &dec_count, prec_increment);
2336
  return dec_buf;
2337
}
2338
2339
2340
String *Item_avg_field::val_str(String *str)
2341
{
2342
  // fix_fields() never calls for this Item
2343
  if (hybrid_type == DECIMAL_RESULT)
2344
    return val_string_from_decimal(str);
2345
  return val_string_from_real(str);
2346
}
2347
2348
2349
Item_std_field::Item_std_field(Item_sum_std *item)
2350
  : Item_variance_field(item)
2351
{
2352
}
2353
2354
2355
double Item_std_field::val_real()
2356
{
2357
  double nr;
2358
  // fix_fields() never calls for this Item
2359
  nr= Item_variance_field::val_real();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2360
  assert(nr >= 0.0);
1 by brian
clean slate
2361
  return sqrt(nr);
2362
}
2363
2364
2365
my_decimal *Item_std_field::val_decimal(my_decimal *dec_buf)
2366
{
2367
  /*
2368
    We can't call val_decimal_from_real() for DECIMAL_RESULT as
2369
    Item_variance_field::val_real() would cause an infinite loop
2370
  */
2371
  my_decimal tmp_dec, *dec;
2372
  double nr;
2373
  if (hybrid_type == REAL_RESULT)
2374
    return val_decimal_from_real(dec_buf);
2375
2376
  dec= Item_variance_field::val_decimal(dec_buf);
2377
  if (!dec)
2378
    return 0;
2379
  my_decimal2double(E_DEC_FATAL_ERROR, dec, &nr);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2380
  assert(nr >= 0.0);
1 by brian
clean slate
2381
  nr= sqrt(nr);
2382
  double2my_decimal(E_DEC_FATAL_ERROR, nr, &tmp_dec);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2383
  my_decimal_round(E_DEC_FATAL_ERROR, &tmp_dec, decimals, false, dec_buf);
1 by brian
clean slate
2384
  return dec_buf;
2385
}
2386
2387
2388
Item_variance_field::Item_variance_field(Item_sum_variance *item)
2389
{
2390
  name=item->name;
2391
  decimals=item->decimals;
2392
  max_length=item->max_length;
2393
  unsigned_flag= item->unsigned_flag;
2394
  field=item->result_field;
2395
  maybe_null=1;
2396
  sample= item->sample;
2397
  prec_increment= item->prec_increment;
2398
  if ((hybrid_type= item->hybrid_type) == DECIMAL_RESULT)
2399
  {
2400
    f_scale0= item->f_scale0;
2401
    f_precision0= item->f_precision0;
2402
    dec_bin_size0= item->dec_bin_size0;
2403
    f_scale1= item->f_scale1;
2404
    f_precision1= item->f_precision1;
2405
    dec_bin_size1= item->dec_bin_size1;
2406
  }
2407
}
2408
2409
2410
double Item_variance_field::val_real()
2411
{
2412
  // fix_fields() never calls for this Item
2413
  if (hybrid_type == DECIMAL_RESULT)
2414
    return val_real_from_decimal();
2415
2416
  double recurrence_s;
151 by Brian Aker
Ulonglong to uint64_t
2417
  uint64_t count;
1 by brian
clean slate
2418
  float8get(recurrence_s, (field->ptr + sizeof(double)));
2419
  count=sint8korr(field->ptr+sizeof(double)*2);
2420
2421
  if ((null_value= (count <= sample)))
2422
    return 0.0;
2423
2424
  return variance_fp_recurrence_result(recurrence_s, count, sample);
2425
}
2426
2427
2428
/****************************************************************************
2429
** COUNT(DISTINCT ...)
2430
****************************************************************************/
2431
2432
int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2)
2433
{
2434
  Field *f= (Field*) arg;
2435
  return f->cmp(key1, key2);
2436
}
2437
2438
/**
2439
  Did not make this one static - at least gcc gets confused when
2440
  I try to declare a static function as a friend. If you can figure
2441
  out the syntax to make a static function a friend, make this one
2442
  static
2443
*/
2444
2445
int composite_key_cmp(void* arg, uchar* key1, uchar* key2)
2446
{
2447
  Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
2448
  Field **field    = item->table->field;
2449
  Field **field_end= field + item->table->s->fields;
205 by Brian Aker
uint32 -> uin32_t
2450
  uint32_t *lengths=item->field_lengths;
1 by brian
clean slate
2451
  for (; field < field_end; ++field)
2452
  {
2453
    Field* f = *field;
2454
    int len = *lengths++;
2455
    int res = f->cmp(key1, key2);
2456
    if (res)
2457
      return res;
2458
    key1 += len;
2459
    key2 += len;
2460
  }
2461
  return 0;
2462
}
2463
2464
2465
C_MODE_START
2466
77.1.15 by Monty Taylor
Bunch of warning cleanups.
2467
static int count_distinct_walk(void *elem __attribute__((__unused__)),
2468
                               element_count count __attribute__((__unused__)),
2469
                               void *arg)
1 by brian
clean slate
2470
{
151 by Brian Aker
Ulonglong to uint64_t
2471
  (*((uint64_t*)arg))++;
1 by brian
clean slate
2472
  return 0;
2473
}
2474
2475
C_MODE_END
2476
2477
2478
void Item_sum_count_distinct::cleanup()
2479
{
2480
  Item_sum_int::cleanup();
2481
2482
  /* Free objects only if we own them. */
2483
  if (!original)
2484
  {
2485
    /*
2486
      We need to delete the table and the tree in cleanup() as
2487
      they were allocated in the runtime memroot. Using the runtime
2488
      memroot reduces memory footprint for PS/SP and simplifies setup().
2489
    */
2490
    delete tree;
2491
    tree= 0;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2492
    is_evaluated= false;
1 by brian
clean slate
2493
    if (table)
2494
    {
2495
      free_tmp_table(table->in_use, table);
2496
      table= 0;
2497
    }
2498
    delete tmp_table_param;
2499
    tmp_table_param= 0;
2500
  }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2501
  always_null= false;
2502
  return;
1 by brian
clean slate
2503
}
2504
2505
2506
/**
2507
  This is used by rollup to create a separate usable copy of
2508
  the function.
2509
*/
2510
2511
void Item_sum_count_distinct::make_unique()
2512
{
2513
  table=0;
2514
  original= 0;
2515
  force_copy_fields= 1;
2516
  tree= 0;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2517
  is_evaluated= false;
1 by brian
clean slate
2518
  tmp_table_param= 0;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2519
  always_null= false;
1 by brian
clean slate
2520
}
2521
2522
2523
Item_sum_count_distinct::~Item_sum_count_distinct()
2524
{
2525
  cleanup();
2526
}
2527
2528
2529
bool Item_sum_count_distinct::setup(THD *thd)
2530
{
2531
  List<Item> list;
2532
  SELECT_LEX *select_lex= thd->lex->current_select;
2533
2534
  /*
2535
    Setup can be called twice for ROLLUP items. This is a bug.
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2536
    Please add assert(tree == 0) here when it's fixed.
1 by brian
clean slate
2537
    It's legal to call setup() more than once when in a subquery
2538
  */
2539
  if (tree || table || tmp_table_param)
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2540
    return false;
1 by brian
clean slate
2541
2542
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2543
    return true;
1 by brian
clean slate
2544
2545
  /* Create a table with an unique key over all parameters */
2546
  for (uint i=0; i < arg_count ; i++)
2547
  {
2548
    Item *item=args[i];
2549
    if (list.push_back(item))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2550
      return true;                              // End of memory
1 by brian
clean slate
2551
    if (item->const_item() && item->is_null())
2552
      always_null= 1;
2553
  }
2554
  if (always_null)
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2555
    return false;
1 by brian
clean slate
2556
  count_field_types(select_lex, tmp_table_param, list, 0);
2557
  tmp_table_param->force_copy_fields= force_copy_fields;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2558
  assert(table == 0);
1 by brian
clean slate
2559
2560
  if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
2561
				0,
2562
				(select_lex->options | thd->options),
2563
				HA_POS_ERROR, (char*)"")))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2564
    return true;
1 by brian
clean slate
2565
  table->file->extra(HA_EXTRA_NO_ROWS);		// Don't update rows
2566
  table->no_rows=1;
2567
2568
  if (table->s->db_type() == heap_hton)
2569
  {
2570
    /*
2571
      No blobs, otherwise it would have been MyISAM: set up a compare
2572
      function and its arguments to use with Unique.
2573
    */
2574
    qsort_cmp2 compare_key;
2575
    void* cmp_arg;
2576
    Field **field= table->field;
2577
    Field **field_end= field + table->s->fields;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2578
    bool all_binary= true;
1 by brian
clean slate
2579
2580
    for (tree_key_length= 0; field < field_end; ++field)
2581
    {
2582
      Field *f= *field;
2583
      enum enum_field_types f_type= f->type();
2584
      tree_key_length+= f->pack_length();
99 by Brian Aker
Second pass at removing old varchar.
2585
      if ((f_type == MYSQL_TYPE_VARCHAR) || (!f->binary() && (f_type == MYSQL_TYPE_STRING)))
1 by brian
clean slate
2586
      {
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2587
        all_binary= false;
1 by brian
clean slate
2588
        break;
2589
      }
2590
    }
2591
    if (all_binary)
2592
    {
2593
      cmp_arg= (void*) &tree_key_length;
2594
      compare_key= (qsort_cmp2) simple_raw_key_cmp;
2595
    }
2596
    else
2597
    {
2598
      if (table->s->fields == 1)
2599
      {
2600
        /*
2601
          If we have only one field, which is the most common use of
2602
          count(distinct), it is much faster to use a simpler key
2603
          compare method that can take advantage of not having to worry
2604
          about other fields.
2605
        */
2606
        compare_key= (qsort_cmp2) simple_str_key_cmp;
2607
        cmp_arg= (void*) table->field[0];
2608
        /* tree_key_length has been set already */
2609
      }
2610
      else
2611
      {
205 by Brian Aker
uint32 -> uin32_t
2612
        uint32_t *length;
1 by brian
clean slate
2613
        compare_key= (qsort_cmp2) composite_key_cmp;
2614
        cmp_arg= (void*) this;
205 by Brian Aker
uint32 -> uin32_t
2615
        field_lengths= (uint32_t*) thd->alloc(table->s->fields * sizeof(uint32_t));
1 by brian
clean slate
2616
        for (tree_key_length= 0, length= field_lengths, field= table->field;
2617
             field < field_end; ++field, ++length)
2618
        {
2619
          *length= (*field)->pack_length();
2620
          tree_key_length+= *length;
2621
        }
2622
      }
2623
    }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2624
    assert(tree == 0);
1 by brian
clean slate
2625
    tree= new Unique(compare_key, cmp_arg, tree_key_length,
2626
                     thd->variables.max_heap_table_size);
2627
    /*
2628
      The only time tree_key_length could be 0 is if someone does
2629
      count(distinct) on a char(0) field - stupid thing to do,
2630
      but this has to be handled - otherwise someone can crash
2631
      the server with a DoS attack
2632
    */
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2633
    is_evaluated= false;
1 by brian
clean slate
2634
    if (! tree)
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2635
      return true;
1 by brian
clean slate
2636
  }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2637
  return false;
1 by brian
clean slate
2638
}
2639
2640
2641
Item *Item_sum_count_distinct::copy_or_same(THD* thd) 
2642
{
2643
  return new (thd->mem_root) Item_sum_count_distinct(thd, this);
2644
}
2645
2646
2647
void Item_sum_count_distinct::clear()
2648
{
2649
  /* tree and table can be both null only if always_null */
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2650
  is_evaluated= false;
1 by brian
clean slate
2651
  if (tree)
2652
  {
2653
    tree->reset();
2654
  }
2655
  else if (table)
2656
  {
2657
    table->file->extra(HA_EXTRA_NO_CACHE);
2658
    table->file->ha_delete_all_rows();
2659
    table->file->extra(HA_EXTRA_WRITE_CACHE);
2660
  }
2661
}
2662
2663
bool Item_sum_count_distinct::add()
2664
{
2665
  int error;
2666
  if (always_null)
2667
    return 0;
2668
  copy_fields(tmp_table_param);
2669
  copy_funcs(tmp_table_param->items_to_copy);
2670
2671
  for (Field **field=table->field ; *field ; field++)
2672
    if ((*field)->is_real_null(0))
2673
      return 0;					// Don't count NULL
2674
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2675
  is_evaluated= false;
1 by brian
clean slate
2676
  if (tree)
2677
  {
2678
    /*
2679
      The first few bytes of record (at least one) are just markers
2680
      for deleted and NULLs. We want to skip them since they will
2681
      bloat the tree without providing any valuable info. Besides,
2682
      key_length used to initialize the tree didn't include space for them.
2683
    */
2684
    return tree->unique_add(table->record[0] + table->s->null_bytes);
2685
  }
2686
  if ((error= table->file->ha_write_row(table->record[0])) &&
2687
      table->file->is_fatal_error(error, HA_CHECK_DUP))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2688
    return true;
2689
  return false;
1 by brian
clean slate
2690
}
2691
2692
152 by Brian Aker
longlong replacement
2693
int64_t Item_sum_count_distinct::val_int()
1 by brian
clean slate
2694
{
2695
  int error;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2696
  assert(fixed == 1);
1 by brian
clean slate
2697
  if (!table)					// Empty query
80.1.1 by Brian Aker
LL() cleanup
2698
    return 0LL;
1 by brian
clean slate
2699
  if (tree)
2700
  {
2701
    if (is_evaluated)
2702
      return count;
2703
2704
    if (tree->elements == 0)
152 by Brian Aker
longlong replacement
2705
      return (int64_t) tree->elements_in_tree(); // everything fits in memory
1 by brian
clean slate
2706
    count= 0;
2707
    tree->walk(count_distinct_walk, (void*) &count);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2708
    is_evaluated= true;
152 by Brian Aker
longlong replacement
2709
    return (int64_t) count;
1 by brian
clean slate
2710
  }
2711
2712
  error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2713
2714
  if(error)
2715
  {
2716
    table->file->print_error(error, MYF(0));
2717
  }
2718
2719
  return table->file->stats.records;
2720
}
2721
2722
2723
/****************************************************************************
2724
** Functions to handle dynamic loadable aggregates
2725
** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
2726
** Adapted for UDAs by: Andreas F. Bobak <bobak@relog.ch>.
2727
** Rewritten by: Monty.
2728
****************************************************************************/
2729
2730
void Item_udf_sum::clear()
2731
{
2732
  udf.clear();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2733
  return;
1 by brian
clean slate
2734
}
2735
2736
bool Item_udf_sum::add()
2737
{
2738
  udf.add(&null_value);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2739
  return(0);
1 by brian
clean slate
2740
}
2741
2742
void Item_udf_sum::cleanup()
2743
{
2744
  /*
2745
    udf_handler::cleanup() nicely handles case when we have not
2746
    original item but one created by copy_or_same() method.
2747
  */
2748
  udf.cleanup();
2749
  Item_sum::cleanup();
2750
}
2751
2752
2753
void Item_udf_sum::print(String *str, enum_query_type query_type)
2754
{
2755
  str->append(func_name());
2756
  str->append('(');
2757
  for (uint i=0 ; i < arg_count ; i++)
2758
  {
2759
    if (i)
2760
      str->append(',');
2761
    args[i]->print(str, query_type);
2762
  }
2763
  str->append(')');
2764
}
2765
2766
2767
Item *Item_sum_udf_float::copy_or_same(THD* thd)
2768
{
2769
  return new (thd->mem_root) Item_sum_udf_float(thd, this);
2770
}
2771
2772
double Item_sum_udf_float::val_real()
2773
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2774
  assert(fixed == 1);
2775
  return(udf.val(&null_value));
1 by brian
clean slate
2776
}
2777
2778
2779
String *Item_sum_udf_float::val_str(String *str)
2780
{
2781
  return val_string_from_real(str);
2782
}
2783
2784
2785
my_decimal *Item_sum_udf_float::val_decimal(my_decimal *dec)
2786
{
2787
  return val_decimal_from_real(dec);
2788
}
2789
2790
2791
String *Item_sum_udf_decimal::val_str(String *str)
2792
{
2793
  return val_string_from_decimal(str);
2794
}
2795
2796
2797
double Item_sum_udf_decimal::val_real()
2798
{
2799
  return val_real_from_decimal();
2800
}
2801
2802
152 by Brian Aker
longlong replacement
2803
int64_t Item_sum_udf_decimal::val_int()
1 by brian
clean slate
2804
{
2805
  return val_int_from_decimal();
2806
}
2807
2808
2809
my_decimal *Item_sum_udf_decimal::val_decimal(my_decimal *dec_buf)
2810
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2811
  assert(fixed == 1);
2812
  return(udf.val_decimal(&null_value, dec_buf));
1 by brian
clean slate
2813
}
2814
2815
2816
Item *Item_sum_udf_decimal::copy_or_same(THD* thd)
2817
{
2818
  return new (thd->mem_root) Item_sum_udf_decimal(thd, this);
2819
}
2820
2821
2822
Item *Item_sum_udf_int::copy_or_same(THD* thd)
2823
{
2824
  return new (thd->mem_root) Item_sum_udf_int(thd, this);
2825
}
2826
152 by Brian Aker
longlong replacement
2827
int64_t Item_sum_udf_int::val_int()
1 by brian
clean slate
2828
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2829
  assert(fixed == 1);
2830
  return(udf.val_int(&null_value));
1 by brian
clean slate
2831
}
2832
2833
2834
String *Item_sum_udf_int::val_str(String *str)
2835
{
2836
  return val_string_from_int(str);
2837
}
2838
2839
my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
2840
{
2841
  return val_decimal_from_int(dec);
2842
}
2843
2844
2845
/** Default max_length is max argument length. */
2846
2847
void Item_sum_udf_str::fix_length_and_dec()
2848
{
2849
  max_length=0;
2850
  for (uint i = 0; i < arg_count; i++)
2851
    set_if_bigger(max_length,args[i]->max_length);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2852
  return;
1 by brian
clean slate
2853
}
2854
2855
2856
Item *Item_sum_udf_str::copy_or_same(THD* thd)
2857
{
2858
  return new (thd->mem_root) Item_sum_udf_str(thd, this);
2859
}
2860
2861
2862
my_decimal *Item_sum_udf_str::val_decimal(my_decimal *dec)
2863
{
2864
  return val_decimal_from_string(dec);
2865
}
2866
2867
String *Item_sum_udf_str::val_str(String *str)
2868
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2869
  assert(fixed == 1);
1 by brian
clean slate
2870
  String *res=udf.val_str(str,&str_value);
2871
  null_value = !res;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2872
  return(res);
1 by brian
clean slate
2873
}
2874
2875
/*****************************************************************************
2876
 GROUP_CONCAT function
2877
2878
 SQL SYNTAX:
2879
  GROUP_CONCAT([DISTINCT] expr,... [ORDER BY col [ASC|DESC],...]
2880
    [SEPARATOR str_const])
2881
2882
 concat of values from "group by" operation
2883
2884
 BUGS
2885
   Blobs doesn't work with DISTINCT or ORDER BY
2886
*****************************************************************************/
2887
2888
2889
/** 
2890
  Compares the values for fields in expr list of GROUP_CONCAT.
2891
  @note
2892
       
2893
     GROUP_CONCAT([DISTINCT] expr [,expr ...]
2894
              [ORDER BY {unsigned_integer | col_name | expr}
2895
                  [ASC | DESC] [,col_name ...]]
2896
              [SEPARATOR str_val])
2897
 
2898
  @return
2899
  @retval -1 : key1 < key2 
2900
  @retval  0 : key1 = key2
2901
  @retval  1 : key1 > key2 
2902
*/
2903
2904
int group_concat_key_cmp_with_distinct(void* arg, const void* key1, 
2905
                                       const void* key2)
2906
{
2907
  Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
2908
  TABLE *table= item_func->table;
2909
2910
  for (uint i= 0; i < item_func->arg_count_field; i++)
2911
  {
2912
    Item *item= item_func->args[i];
2913
    /* 
2914
      If field_item is a const item then either get_tp_table_field returns 0
2915
      or it is an item over a const table. 
2916
    */
2917
    if (item->const_item())
2918
      continue;
2919
    /*
2920
      We have to use get_tmp_table_field() instead of
2921
      real_item()->get_tmp_table_field() because we want the field in
2922
      the temporary table, not the original field
2923
    */
2924
    Field *field= item->get_tmp_table_field();
2925
    int res;
2926
    uint offset= field->offset(field->table->record[0])-table->s->null_bytes;
2927
    if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
2928
      return res;
2929
  }
2930
  return 0;
2931
}
2932
2933
2934
/**
2935
  function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
2936
*/
2937
2938
int group_concat_key_cmp_with_order(void* arg, const void* key1, 
2939
                                    const void* key2)
2940
{
2941
  Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2942
  ORDER **order_item, **end;
2943
  TABLE *table= grp_item->table;
2944
2945
  for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
2946
       order_item < end;
2947
       order_item++)
2948
  {
2949
    Item *item= *(*order_item)->item;
2950
    /*
2951
      We have to use get_tmp_table_field() instead of
2952
      real_item()->get_tmp_table_field() because we want the field in
2953
      the temporary table, not the original field
2954
    */
2955
    Field *field= item->get_tmp_table_field();
2956
    /* 
2957
      If item is a const item then either get_tp_table_field returns 0
2958
      or it is an item over a const table. 
2959
    */
2960
    if (field && !item->const_item())
2961
    {
2962
      int res;
2963
      uint offset= (field->offset(field->table->record[0]) -
2964
                    table->s->null_bytes);
2965
      if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
2966
        return (*order_item)->asc ? res : -res;
2967
    }
2968
  }
2969
  /*
2970
    We can't return 0 because in that case the tree class would remove this
2971
    item as double value. This would cause problems for case-changes and
2972
    if the returned values are not the same we do the sort on.
2973
  */
2974
  return 1;
2975
}
2976
2977
2978
/**
2979
  Append data from current leaf to item->result.
2980
*/
2981
2982
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
2983
                  Item_func_group_concat *item)
2984
{
2985
  TABLE *table= item->table;
2986
  String tmp((char *)table->record[1], table->s->reclength,
2987
             default_charset_info);
2988
  String tmp2;
2989
  String *result= &item->result;
2990
  Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
2991
  uint old_length= result->length();
2992
2993
  if (item->no_appended)
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2994
    item->no_appended= false;
1 by brian
clean slate
2995
  else
2996
    result->append(*item->separator);
2997
2998
  tmp.length(0);
2999
3000
  for (; arg < arg_end; arg++)
3001
  {
3002
    String *res;
3003
    if (! (*arg)->const_item())
3004
    {
3005
      /*
3006
	We have to use get_tmp_table_field() instead of
3007
	real_item()->get_tmp_table_field() because we want the field in
3008
	the temporary table, not the original field
3009
        We also can't use table->field array to access the fields
3010
        because it contains both order and arg list fields.
3011
      */
3012
      Field *field= (*arg)->get_tmp_table_field();
3013
      uint offset= (field->offset(field->table->record[0]) -
3014
                    table->s->null_bytes);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3015
      assert(offset < table->s->reclength);
1 by brian
clean slate
3016
      res= field->val_str(&tmp, key + offset);
3017
    }
3018
    else
3019
      res= (*arg)->val_str(&tmp);
3020
    if (res)
3021
      result->append(*res);
3022
  }
3023
3024
  /* stop if length of result more than max_length */
3025
  if (result->length() > item->max_length)
3026
  {
3027
    int well_formed_error;
3028
    CHARSET_INFO *cs= item->collation.collation;
3029
    const char *ptr= result->ptr();
3030
    uint add_length;
3031
    /*
3032
      It's ok to use item->result.length() as the fourth argument
3033
      as this is never used to limit the length of the data.
3034
      Cut is done with the third argument.
3035
    */
3036
    add_length= cs->cset->well_formed_len(cs,
3037
                                          ptr + old_length,
3038
                                          ptr + item->max_length,
3039
                                          result->length(),
3040
                                          &well_formed_error);
3041
    result->length(old_length + add_length);
3042
    item->count_cut_values++;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3043
    item->warning_for_row= true;
1 by brian
clean slate
3044
    return 1;
3045
  }
3046
  return 0;
3047
}
3048
3049
3050
/**
3051
  Constructor of Item_func_group_concat.
3052
3053
  @param distinct_arg   distinct
3054
  @param select_list    list of expression for show values
3055
  @param order_list     list of sort columns
3056
  @param separator_arg  string value of separator.
3057
*/
3058
3059
Item_func_group_concat::
3060
Item_func_group_concat(Name_resolution_context *context_arg,
3061
                       bool distinct_arg, List<Item> *select_list,
3062
                       SQL_LIST *order_list, String *separator_arg)
3063
  :tmp_table_param(0), warning(0),
3064
   separator(separator_arg), tree(0), unique_filter(NULL), table(0),
3065
   order(0), context(context_arg),
3066
   arg_count_order(order_list ? order_list->elements : 0),
3067
   arg_count_field(select_list->elements),
3068
   count_cut_values(0),
3069
   distinct(distinct_arg),
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3070
   warning_for_row(false),
1 by brian
clean slate
3071
   force_copy_fields(0), original(0)
3072
{
3073
  Item *item_select;
3074
  Item **arg_ptr;
3075
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3076
  quick_group= false;
1 by brian
clean slate
3077
  arg_count= arg_count_field + arg_count_order;
3078
3079
  /*
3080
    We need to allocate:
3081
    args - arg_count_field+arg_count_order
3082
           (for possible order items in temporare tables)
3083
    order - arg_count_order
3084
  */
3085
  if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
3086
                                 sizeof(ORDER*)*arg_count_order)))
3087
    return;
3088
3089
  order= (ORDER**)(args + arg_count);
3090
3091
  /* fill args items of show and sort */
3092
  List_iterator_fast<Item> li(*select_list);
3093
3094
  for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
3095
    *arg_ptr= item_select;
3096
3097
  if (arg_count_order)
3098
  {
3099
    ORDER **order_ptr= order;
3100
    for (ORDER *order_item= (ORDER*) order_list->first;
3101
         order_item != NULL;
3102
         order_item= order_item->next)
3103
    {
3104
      (*order_ptr++)= order_item;
3105
      *arg_ptr= *order_item->item;
3106
      order_item->item= arg_ptr++;
3107
    }
3108
  }
3109
}
3110
3111
3112
Item_func_group_concat::Item_func_group_concat(THD *thd,
3113
                                               Item_func_group_concat *item)
3114
  :Item_sum(thd, item),
3115
  tmp_table_param(item->tmp_table_param),
3116
  warning(item->warning),
3117
  separator(item->separator),
3118
  tree(item->tree),
3119
  unique_filter(item->unique_filter),
3120
  table(item->table),
3121
  order(item->order),
3122
  context(item->context),
3123
  arg_count_order(item->arg_count_order),
3124
  arg_count_field(item->arg_count_field),
3125
  count_cut_values(item->count_cut_values),
3126
  distinct(item->distinct),
3127
  warning_for_row(item->warning_for_row),
3128
  always_null(item->always_null),
3129
  force_copy_fields(item->force_copy_fields),
3130
  original(item)
3131
{
3132
  quick_group= item->quick_group;
3133
  result.set_charset(collation.collation);
3134
}
3135
3136
3137
3138
void Item_func_group_concat::cleanup()
3139
{
3140
  Item_sum::cleanup();
3141
3142
  /* Adjust warning message to include total number of cut values */
3143
  if (warning)
3144
  {
3145
    char warn_buff[MYSQL_ERRMSG_SIZE];
3146
    sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3147
    warning->set_msg(current_thd, warn_buff);
3148
    warning= 0;
3149
  }
3150
3151
  /*
3152
    Free table and tree if they belong to this item (if item have not pointer
3153
    to original item from which was made copy => it own its objects )
3154
  */
3155
  if (!original)
3156
  {
3157
    delete tmp_table_param;
3158
    tmp_table_param= 0;
3159
    if (table)
3160
    {
3161
      THD *thd= table->in_use;
3162
      free_tmp_table(thd, table);
3163
      table= 0;
3164
      if (tree)
3165
      {
3166
        delete_tree(tree);
3167
        tree= 0;
3168
      }
3169
      if (unique_filter)
3170
      {
3171
        delete unique_filter;
3172
        unique_filter= NULL;
3173
      }
3174
      if (warning)
3175
      {
3176
        char warn_buff[MYSQL_ERRMSG_SIZE];
3177
        sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3178
        warning->set_msg(thd, warn_buff);
3179
        warning= 0;
3180
      }
3181
    }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3182
    assert(tree == 0 && warning == 0);
1 by brian
clean slate
3183
  }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3184
  return;
1 by brian
clean slate
3185
}
3186
3187
3188
Item *Item_func_group_concat::copy_or_same(THD* thd)
3189
{
3190
  return new (thd->mem_root) Item_func_group_concat(thd, this);
3191
}
3192
3193
3194
void Item_func_group_concat::clear()
3195
{
3196
  result.length(0);
3197
  result.copy();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3198
  null_value= true;
3199
  warning_for_row= false;
3200
  no_appended= true;
1 by brian
clean slate
3201
  if (tree)
3202
    reset_tree(tree);
3203
  if (distinct)
3204
    unique_filter->reset();
3205
  /* No need to reset the table as we never call write_row */
3206
}
3207
3208
3209
bool Item_func_group_concat::add()
3210
{
3211
  if (always_null)
3212
    return 0;
3213
  copy_fields(tmp_table_param);
3214
  copy_funcs(tmp_table_param->items_to_copy);
3215
3216
  for (uint i= 0; i < arg_count_field; i++)
3217
  {
3218
    Item *show_item= args[i];
3219
    if (!show_item->const_item())
3220
    {
3221
      Field *f= show_item->get_tmp_table_field();
3222
      if (f->is_null_in_record((const uchar*) table->record[0]))
3223
        return 0;                               // Skip row if it contains null
3224
    }
3225
  }
3226
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3227
  null_value= false;
3228
  bool row_eligible= true;
1 by brian
clean slate
3229
3230
  if (distinct) 
3231
  {
3232
    /* Filter out duplicate rows. */
3233
    uint count= unique_filter->elements_in_tree();
3234
    unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3235
    if (count == unique_filter->elements_in_tree())
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3236
      row_eligible= false;
1 by brian
clean slate
3237
  }
3238
3239
  TREE_ELEMENT *el= 0;                          // Only for safety
3240
  if (row_eligible && tree)
3241
    el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3242
                    tree->custom_arg);
3243
  /*
3244
    If the row is not a duplicate (el->count == 1)
3245
    we can dump the row here in case of GROUP_CONCAT(DISTINCT...)
3246
    instead of doing tree traverse later.
3247
  */
3248
  if (row_eligible && !warning_for_row &&
3249
      (!tree || (el->count == 1 && distinct && !arg_count_order)))
3250
    dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3251
3252
  return 0;
3253
}
3254
3255
3256
bool
3257
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3258
{
3259
  uint i;                       /* for loop variable */
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3260
  assert(fixed == 0);
1 by brian
clean slate
3261
3262
  if (init_sum_func_check(thd))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3263
    return true;
1 by brian
clean slate
3264
3265
  maybe_null= 1;
3266
3267
  /*
3268
    Fix fields for select list and ORDER clause
3269
  */
3270
3271
  for (i=0 ; i < arg_count ; i++)
3272
  {
3273
    if ((!args[i]->fixed &&
3274
         args[i]->fix_fields(thd, args + i)) ||
3275
        args[i]->check_cols(1))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3276
      return true;
1 by brian
clean slate
3277
  }
3278
3279
  if (agg_item_charsets(collation, func_name(),
3280
                        args,
3281
			/* skip charset aggregation for order columns */
3282
			arg_count - arg_count_order,
3283
			MY_COLL_ALLOW_CONV, 1))
3284
    return 1;
3285
3286
  result.set_charset(collation.collation);
3287
  result_field= 0;
3288
  null_value= 1;
3289
  max_length= thd->variables.group_concat_max_len;
3290
205 by Brian Aker
uint32 -> uin32_t
3291
  uint32_t offset;
1 by brian
clean slate
3292
  if (separator->needs_conversion(separator->length(), separator->charset(),
3293
                                  collation.collation, &offset))
3294
  {
205 by Brian Aker
uint32 -> uin32_t
3295
    uint32_t buflen= collation.collation->mbmaxlen * separator->length();
1 by brian
clean slate
3296
    uint errors, conv_length;
3297
    char *buf;
3298
    String *new_separator;
3299
3300
    if (!(buf= (char*) thd->stmt_arena->alloc(buflen)) ||
3301
        !(new_separator= new(thd->stmt_arena->mem_root)
3302
                           String(buf, buflen, collation.collation)))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3303
      return true;
1 by brian
clean slate
3304
    
3305
    conv_length= copy_and_convert(buf, buflen, collation.collation,
3306
                                  separator->ptr(), separator->length(),
3307
                                  separator->charset(), &errors);
3308
    new_separator->length(conv_length);
3309
    separator= new_separator;
3310
  }
3311
3312
  if (check_sum_func(thd, ref))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3313
    return true;
1 by brian
clean slate
3314
3315
  fixed= 1;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3316
  return false;
1 by brian
clean slate
3317
}
3318
3319
3320
bool Item_func_group_concat::setup(THD *thd)
3321
{
3322
  List<Item> list;
3323
  SELECT_LEX *select_lex= thd->lex->current_select;
3324
3325
  /*
3326
    Currently setup() can be called twice. Please add
3327
    assertion here when this is fixed.
3328
  */
3329
  if (table || tree)
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3330
    return(false);
1 by brian
clean slate
3331
3332
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3333
    return(true);
1 by brian
clean slate
3334
3335
  /* We'll convert all blobs to varchar fields in the temporary table */
3336
  tmp_table_param->convert_blob_length= max_length *
3337
                                        collation.collation->mbmaxlen;
3338
  /* Push all not constant fields to the list and create a temp table */
3339
  always_null= 0;
3340
  for (uint i= 0; i < arg_count_field; i++)
3341
  {
3342
    Item *item= args[i];
3343
    if (list.push_back(item))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3344
      return(true);
1 by brian
clean slate
3345
    if (item->const_item())
3346
    {
3347
      if (item->is_null())
3348
      {
3349
        always_null= 1;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3350
        return(false);
1 by brian
clean slate
3351
      }
3352
    }
3353
  }
3354
3355
  List<Item> all_fields(list);
3356
  /*
3357
    Try to find every ORDER expression in the list of GROUP_CONCAT
3358
    arguments. If an expression is not found, prepend it to
3359
    "all_fields". The resulting field list is used as input to create
3360
    tmp table columns.
3361
  */
3362
  if (arg_count_order &&
3363
      setup_order(thd, args, context->table_list, list, all_fields, *order))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3364
    return(true);
1 by brian
clean slate
3365
3366
  count_field_types(select_lex, tmp_table_param, all_fields, 0);
3367
  tmp_table_param->force_copy_fields= force_copy_fields;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3368
  assert(table == 0);
1 by brian
clean slate
3369
  if (arg_count_order > 0 || distinct)
3370
  {
3371
    /*
3372
      Currently we have to force conversion of BLOB values to VARCHAR's
3373
      if we are to store them in TREE objects used for ORDER BY and
3374
      DISTINCT. This leads to truncation if the BLOB's size exceeds
3375
      Field_varstring::MAX_SIZE.
3376
    */
3377
    set_if_smaller(tmp_table_param->convert_blob_length, 
3378
                   Field_varstring::MAX_SIZE);
3379
  }
3380
3381
  /*
3382
    We have to create a temporary table to get descriptions of fields
3383
    (types, sizes and so on).
3384
3385
    Note that in the table, we first have the ORDER BY fields, then the
3386
    field list.
3387
  */
3388
  if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3389
                                (ORDER*) 0, 0, true,
1 by brian
clean slate
3390
                                (select_lex->options | thd->options),
3391
                                HA_POS_ERROR, (char*) "")))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3392
    return(true);
1 by brian
clean slate
3393
  table->file->extra(HA_EXTRA_NO_ROWS);
3394
  table->no_rows= 1;
3395
3396
  /*
3397
     Need sorting or uniqueness: init tree and choose a function to sort.
3398
     Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3399
     the row is not added to the result.
3400
  */
3401
  uint tree_key_length= table->s->reclength - table->s->null_bytes;
3402
3403
  if (arg_count_order)
3404
  {
3405
    tree= &tree_base;
3406
    /*
3407
      Create a tree for sorting. The tree is used to sort (according to the
3408
      syntax of this function). If there is no ORDER BY clause, we don't
3409
      create this tree.
3410
    */
3411
    init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
3412
                               thd->variables.sortbuff_size/16), 0,
3413
              tree_key_length, 
3414
              group_concat_key_cmp_with_order , 0, NULL, (void*) this);
3415
  }
3416
3417
  if (distinct)
3418
    unique_filter= new Unique(group_concat_key_cmp_with_distinct,
3419
                              (void*)this,
3420
                              tree_key_length,
3421
                              thd->variables.max_heap_table_size);
3422
  
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3423
  return(false);
1 by brian
clean slate
3424
}
3425
3426
3427
/* This is used by rollup to create a separate usable copy of the function */
3428
3429
void Item_func_group_concat::make_unique()
3430
{
3431
  tmp_table_param= 0;
3432
  table=0;
3433
  original= 0;
3434
  force_copy_fields= 1;
3435
  tree= 0;
3436
}
3437
3438
77.1.15 by Monty Taylor
Bunch of warning cleanups.
3439
String* Item_func_group_concat::val_str(String* str __attribute__((__unused__)))
1 by brian
clean slate
3440
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3441
  assert(fixed == 1);
1 by brian
clean slate
3442
  if (null_value)
3443
    return 0;
3444
  if (no_appended && tree)
3445
    /* Tree is used for sorting as in ORDER BY */
3446
    tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
3447
              left_root_right);
3448
  if (count_cut_values && !warning)
3449
  {
3450
    /*
3451
      ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in
3452
      Item_func_group_concat::cleanup().
3453
    */
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3454
    assert(table);
1 by brian
clean slate
3455
    warning= push_warning(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
3456
                          ER_CUT_VALUE_GROUP_CONCAT,
3457
                          ER(ER_CUT_VALUE_GROUP_CONCAT));
3458
  }
3459
  return &result;
3460
}
3461
3462
3463
void Item_func_group_concat::print(String *str, enum_query_type query_type)
3464
{
3465
  str->append(STRING_WITH_LEN("group_concat("));
3466
  if (distinct)
3467
    str->append(STRING_WITH_LEN("distinct "));
3468
  for (uint i= 0; i < arg_count_field; i++)
3469
  {
3470
    if (i)
3471
      str->append(',');
3472
    args[i]->print(str, query_type);
3473
  }
3474
  if (arg_count_order)
3475
  {
3476
    str->append(STRING_WITH_LEN(" order by "));
3477
    for (uint i= 0 ; i < arg_count_order ; i++)
3478
    {
3479
      if (i)
3480
        str->append(',');
3481
      (*order[i]->item)->print(str, query_type);
3482
      if (order[i]->asc)
3483
        str->append(STRING_WITH_LEN(" ASC"));
3484
      else
3485
        str->append(STRING_WITH_LEN(" DESC"));
3486
    }
3487
  }
3488
  str->append(STRING_WITH_LEN(" separator \'"));
3489
  str->append(*separator);
3490
  str->append(STRING_WITH_LEN("\')"));
3491
}
3492
3493
3494
Item_func_group_concat::~Item_func_group_concat()
3495
{
3496
  if (!original && unique_filter)
3497
    delete unique_filter;    
3498
}