~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;
2450
  uint32 *lengths=item->field_lengths;
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
      {
2612
        uint32 *length;
2613
        compare_key= (qsort_cmp2) composite_key_cmp;
2614
        cmp_arg= (void*) this;
2615
        field_lengths= (uint32*) thd->alloc(table->s->fields * sizeof(uint32));
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
#ifdef HAVE_DLOPEN
2731
2732
void Item_udf_sum::clear()
2733
{
2734
  udf.clear();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2735
  return;
1 by brian
clean slate
2736
}
2737
2738
bool Item_udf_sum::add()
2739
{
2740
  udf.add(&null_value);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2741
  return(0);
1 by brian
clean slate
2742
}
2743
2744
void Item_udf_sum::cleanup()
2745
{
2746
  /*
2747
    udf_handler::cleanup() nicely handles case when we have not
2748
    original item but one created by copy_or_same() method.
2749
  */
2750
  udf.cleanup();
2751
  Item_sum::cleanup();
2752
}
2753
2754
2755
void Item_udf_sum::print(String *str, enum_query_type query_type)
2756
{
2757
  str->append(func_name());
2758
  str->append('(');
2759
  for (uint i=0 ; i < arg_count ; i++)
2760
  {
2761
    if (i)
2762
      str->append(',');
2763
    args[i]->print(str, query_type);
2764
  }
2765
  str->append(')');
2766
}
2767
2768
2769
Item *Item_sum_udf_float::copy_or_same(THD* thd)
2770
{
2771
  return new (thd->mem_root) Item_sum_udf_float(thd, this);
2772
}
2773
2774
double Item_sum_udf_float::val_real()
2775
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2776
  assert(fixed == 1);
2777
  return(udf.val(&null_value));
1 by brian
clean slate
2778
}
2779
2780
2781
String *Item_sum_udf_float::val_str(String *str)
2782
{
2783
  return val_string_from_real(str);
2784
}
2785
2786
2787
my_decimal *Item_sum_udf_float::val_decimal(my_decimal *dec)
2788
{
2789
  return val_decimal_from_real(dec);
2790
}
2791
2792
2793
String *Item_sum_udf_decimal::val_str(String *str)
2794
{
2795
  return val_string_from_decimal(str);
2796
}
2797
2798
2799
double Item_sum_udf_decimal::val_real()
2800
{
2801
  return val_real_from_decimal();
2802
}
2803
2804
152 by Brian Aker
longlong replacement
2805
int64_t Item_sum_udf_decimal::val_int()
1 by brian
clean slate
2806
{
2807
  return val_int_from_decimal();
2808
}
2809
2810
2811
my_decimal *Item_sum_udf_decimal::val_decimal(my_decimal *dec_buf)
2812
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2813
  assert(fixed == 1);
2814
  return(udf.val_decimal(&null_value, dec_buf));
1 by brian
clean slate
2815
}
2816
2817
2818
Item *Item_sum_udf_decimal::copy_or_same(THD* thd)
2819
{
2820
  return new (thd->mem_root) Item_sum_udf_decimal(thd, this);
2821
}
2822
2823
2824
Item *Item_sum_udf_int::copy_or_same(THD* thd)
2825
{
2826
  return new (thd->mem_root) Item_sum_udf_int(thd, this);
2827
}
2828
152 by Brian Aker
longlong replacement
2829
int64_t Item_sum_udf_int::val_int()
1 by brian
clean slate
2830
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2831
  assert(fixed == 1);
2832
  return(udf.val_int(&null_value));
1 by brian
clean slate
2833
}
2834
2835
2836
String *Item_sum_udf_int::val_str(String *str)
2837
{
2838
  return val_string_from_int(str);
2839
}
2840
2841
my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
2842
{
2843
  return val_decimal_from_int(dec);
2844
}
2845
2846
2847
/** Default max_length is max argument length. */
2848
2849
void Item_sum_udf_str::fix_length_and_dec()
2850
{
2851
  max_length=0;
2852
  for (uint i = 0; i < arg_count; i++)
2853
    set_if_bigger(max_length,args[i]->max_length);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2854
  return;
1 by brian
clean slate
2855
}
2856
2857
2858
Item *Item_sum_udf_str::copy_or_same(THD* thd)
2859
{
2860
  return new (thd->mem_root) Item_sum_udf_str(thd, this);
2861
}
2862
2863
2864
my_decimal *Item_sum_udf_str::val_decimal(my_decimal *dec)
2865
{
2866
  return val_decimal_from_string(dec);
2867
}
2868
2869
String *Item_sum_udf_str::val_str(String *str)
2870
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2871
  assert(fixed == 1);
1 by brian
clean slate
2872
  String *res=udf.val_str(str,&str_value);
2873
  null_value = !res;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2874
  return(res);
1 by brian
clean slate
2875
}
2876
2877
#endif /* HAVE_DLOPEN */
2878
2879
2880
/*****************************************************************************
2881
 GROUP_CONCAT function
2882
2883
 SQL SYNTAX:
2884
  GROUP_CONCAT([DISTINCT] expr,... [ORDER BY col [ASC|DESC],...]
2885
    [SEPARATOR str_const])
2886
2887
 concat of values from "group by" operation
2888
2889
 BUGS
2890
   Blobs doesn't work with DISTINCT or ORDER BY
2891
*****************************************************************************/
2892
2893
2894
/** 
2895
  Compares the values for fields in expr list of GROUP_CONCAT.
2896
  @note
2897
       
2898
     GROUP_CONCAT([DISTINCT] expr [,expr ...]
2899
              [ORDER BY {unsigned_integer | col_name | expr}
2900
                  [ASC | DESC] [,col_name ...]]
2901
              [SEPARATOR str_val])
2902
 
2903
  @return
2904
  @retval -1 : key1 < key2 
2905
  @retval  0 : key1 = key2
2906
  @retval  1 : key1 > key2 
2907
*/
2908
2909
int group_concat_key_cmp_with_distinct(void* arg, const void* key1, 
2910
                                       const void* key2)
2911
{
2912
  Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
2913
  TABLE *table= item_func->table;
2914
2915
  for (uint i= 0; i < item_func->arg_count_field; i++)
2916
  {
2917
    Item *item= item_func->args[i];
2918
    /* 
2919
      If field_item is a const item then either get_tp_table_field returns 0
2920
      or it is an item over a const table. 
2921
    */
2922
    if (item->const_item())
2923
      continue;
2924
    /*
2925
      We have to use get_tmp_table_field() instead of
2926
      real_item()->get_tmp_table_field() because we want the field in
2927
      the temporary table, not the original field
2928
    */
2929
    Field *field= item->get_tmp_table_field();
2930
    int res;
2931
    uint offset= field->offset(field->table->record[0])-table->s->null_bytes;
2932
    if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
2933
      return res;
2934
  }
2935
  return 0;
2936
}
2937
2938
2939
/**
2940
  function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
2941
*/
2942
2943
int group_concat_key_cmp_with_order(void* arg, const void* key1, 
2944
                                    const void* key2)
2945
{
2946
  Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2947
  ORDER **order_item, **end;
2948
  TABLE *table= grp_item->table;
2949
2950
  for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
2951
       order_item < end;
2952
       order_item++)
2953
  {
2954
    Item *item= *(*order_item)->item;
2955
    /*
2956
      We have to use get_tmp_table_field() instead of
2957
      real_item()->get_tmp_table_field() because we want the field in
2958
      the temporary table, not the original field
2959
    */
2960
    Field *field= item->get_tmp_table_field();
2961
    /* 
2962
      If item is a const item then either get_tp_table_field returns 0
2963
      or it is an item over a const table. 
2964
    */
2965
    if (field && !item->const_item())
2966
    {
2967
      int res;
2968
      uint offset= (field->offset(field->table->record[0]) -
2969
                    table->s->null_bytes);
2970
      if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
2971
        return (*order_item)->asc ? res : -res;
2972
    }
2973
  }
2974
  /*
2975
    We can't return 0 because in that case the tree class would remove this
2976
    item as double value. This would cause problems for case-changes and
2977
    if the returned values are not the same we do the sort on.
2978
  */
2979
  return 1;
2980
}
2981
2982
2983
/**
2984
  Append data from current leaf to item->result.
2985
*/
2986
2987
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
2988
                  Item_func_group_concat *item)
2989
{
2990
  TABLE *table= item->table;
2991
  String tmp((char *)table->record[1], table->s->reclength,
2992
             default_charset_info);
2993
  String tmp2;
2994
  String *result= &item->result;
2995
  Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
2996
  uint old_length= result->length();
2997
2998
  if (item->no_appended)
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
2999
    item->no_appended= false;
1 by brian
clean slate
3000
  else
3001
    result->append(*item->separator);
3002
3003
  tmp.length(0);
3004
3005
  for (; arg < arg_end; arg++)
3006
  {
3007
    String *res;
3008
    if (! (*arg)->const_item())
3009
    {
3010
      /*
3011
	We have to use get_tmp_table_field() instead of
3012
	real_item()->get_tmp_table_field() because we want the field in
3013
	the temporary table, not the original field
3014
        We also can't use table->field array to access the fields
3015
        because it contains both order and arg list fields.
3016
      */
3017
      Field *field= (*arg)->get_tmp_table_field();
3018
      uint offset= (field->offset(field->table->record[0]) -
3019
                    table->s->null_bytes);
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3020
      assert(offset < table->s->reclength);
1 by brian
clean slate
3021
      res= field->val_str(&tmp, key + offset);
3022
    }
3023
    else
3024
      res= (*arg)->val_str(&tmp);
3025
    if (res)
3026
      result->append(*res);
3027
  }
3028
3029
  /* stop if length of result more than max_length */
3030
  if (result->length() > item->max_length)
3031
  {
3032
    int well_formed_error;
3033
    CHARSET_INFO *cs= item->collation.collation;
3034
    const char *ptr= result->ptr();
3035
    uint add_length;
3036
    /*
3037
      It's ok to use item->result.length() as the fourth argument
3038
      as this is never used to limit the length of the data.
3039
      Cut is done with the third argument.
3040
    */
3041
    add_length= cs->cset->well_formed_len(cs,
3042
                                          ptr + old_length,
3043
                                          ptr + item->max_length,
3044
                                          result->length(),
3045
                                          &well_formed_error);
3046
    result->length(old_length + add_length);
3047
    item->count_cut_values++;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3048
    item->warning_for_row= true;
1 by brian
clean slate
3049
    return 1;
3050
  }
3051
  return 0;
3052
}
3053
3054
3055
/**
3056
  Constructor of Item_func_group_concat.
3057
3058
  @param distinct_arg   distinct
3059
  @param select_list    list of expression for show values
3060
  @param order_list     list of sort columns
3061
  @param separator_arg  string value of separator.
3062
*/
3063
3064
Item_func_group_concat::
3065
Item_func_group_concat(Name_resolution_context *context_arg,
3066
                       bool distinct_arg, List<Item> *select_list,
3067
                       SQL_LIST *order_list, String *separator_arg)
3068
  :tmp_table_param(0), warning(0),
3069
   separator(separator_arg), tree(0), unique_filter(NULL), table(0),
3070
   order(0), context(context_arg),
3071
   arg_count_order(order_list ? order_list->elements : 0),
3072
   arg_count_field(select_list->elements),
3073
   count_cut_values(0),
3074
   distinct(distinct_arg),
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3075
   warning_for_row(false),
1 by brian
clean slate
3076
   force_copy_fields(0), original(0)
3077
{
3078
  Item *item_select;
3079
  Item **arg_ptr;
3080
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3081
  quick_group= false;
1 by brian
clean slate
3082
  arg_count= arg_count_field + arg_count_order;
3083
3084
  /*
3085
    We need to allocate:
3086
    args - arg_count_field+arg_count_order
3087
           (for possible order items in temporare tables)
3088
    order - arg_count_order
3089
  */
3090
  if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
3091
                                 sizeof(ORDER*)*arg_count_order)))
3092
    return;
3093
3094
  order= (ORDER**)(args + arg_count);
3095
3096
  /* fill args items of show and sort */
3097
  List_iterator_fast<Item> li(*select_list);
3098
3099
  for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
3100
    *arg_ptr= item_select;
3101
3102
  if (arg_count_order)
3103
  {
3104
    ORDER **order_ptr= order;
3105
    for (ORDER *order_item= (ORDER*) order_list->first;
3106
         order_item != NULL;
3107
         order_item= order_item->next)
3108
    {
3109
      (*order_ptr++)= order_item;
3110
      *arg_ptr= *order_item->item;
3111
      order_item->item= arg_ptr++;
3112
    }
3113
  }
3114
}
3115
3116
3117
Item_func_group_concat::Item_func_group_concat(THD *thd,
3118
                                               Item_func_group_concat *item)
3119
  :Item_sum(thd, item),
3120
  tmp_table_param(item->tmp_table_param),
3121
  warning(item->warning),
3122
  separator(item->separator),
3123
  tree(item->tree),
3124
  unique_filter(item->unique_filter),
3125
  table(item->table),
3126
  order(item->order),
3127
  context(item->context),
3128
  arg_count_order(item->arg_count_order),
3129
  arg_count_field(item->arg_count_field),
3130
  count_cut_values(item->count_cut_values),
3131
  distinct(item->distinct),
3132
  warning_for_row(item->warning_for_row),
3133
  always_null(item->always_null),
3134
  force_copy_fields(item->force_copy_fields),
3135
  original(item)
3136
{
3137
  quick_group= item->quick_group;
3138
  result.set_charset(collation.collation);
3139
}
3140
3141
3142
3143
void Item_func_group_concat::cleanup()
3144
{
3145
  Item_sum::cleanup();
3146
3147
  /* Adjust warning message to include total number of cut values */
3148
  if (warning)
3149
  {
3150
    char warn_buff[MYSQL_ERRMSG_SIZE];
3151
    sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3152
    warning->set_msg(current_thd, warn_buff);
3153
    warning= 0;
3154
  }
3155
3156
  /*
3157
    Free table and tree if they belong to this item (if item have not pointer
3158
    to original item from which was made copy => it own its objects )
3159
  */
3160
  if (!original)
3161
  {
3162
    delete tmp_table_param;
3163
    tmp_table_param= 0;
3164
    if (table)
3165
    {
3166
      THD *thd= table->in_use;
3167
      free_tmp_table(thd, table);
3168
      table= 0;
3169
      if (tree)
3170
      {
3171
        delete_tree(tree);
3172
        tree= 0;
3173
      }
3174
      if (unique_filter)
3175
      {
3176
        delete unique_filter;
3177
        unique_filter= NULL;
3178
      }
3179
      if (warning)
3180
      {
3181
        char warn_buff[MYSQL_ERRMSG_SIZE];
3182
        sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3183
        warning->set_msg(thd, warn_buff);
3184
        warning= 0;
3185
      }
3186
    }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3187
    assert(tree == 0 && warning == 0);
1 by brian
clean slate
3188
  }
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3189
  return;
1 by brian
clean slate
3190
}
3191
3192
3193
Item *Item_func_group_concat::copy_or_same(THD* thd)
3194
{
3195
  return new (thd->mem_root) Item_func_group_concat(thd, this);
3196
}
3197
3198
3199
void Item_func_group_concat::clear()
3200
{
3201
  result.length(0);
3202
  result.copy();
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3203
  null_value= true;
3204
  warning_for_row= false;
3205
  no_appended= true;
1 by brian
clean slate
3206
  if (tree)
3207
    reset_tree(tree);
3208
  if (distinct)
3209
    unique_filter->reset();
3210
  /* No need to reset the table as we never call write_row */
3211
}
3212
3213
3214
bool Item_func_group_concat::add()
3215
{
3216
  if (always_null)
3217
    return 0;
3218
  copy_fields(tmp_table_param);
3219
  copy_funcs(tmp_table_param->items_to_copy);
3220
3221
  for (uint i= 0; i < arg_count_field; i++)
3222
  {
3223
    Item *show_item= args[i];
3224
    if (!show_item->const_item())
3225
    {
3226
      Field *f= show_item->get_tmp_table_field();
3227
      if (f->is_null_in_record((const uchar*) table->record[0]))
3228
        return 0;                               // Skip row if it contains null
3229
    }
3230
  }
3231
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3232
  null_value= false;
3233
  bool row_eligible= true;
1 by brian
clean slate
3234
3235
  if (distinct) 
3236
  {
3237
    /* Filter out duplicate rows. */
3238
    uint count= unique_filter->elements_in_tree();
3239
    unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3240
    if (count == unique_filter->elements_in_tree())
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3241
      row_eligible= false;
1 by brian
clean slate
3242
  }
3243
3244
  TREE_ELEMENT *el= 0;                          // Only for safety
3245
  if (row_eligible && tree)
3246
    el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3247
                    tree->custom_arg);
3248
  /*
3249
    If the row is not a duplicate (el->count == 1)
3250
    we can dump the row here in case of GROUP_CONCAT(DISTINCT...)
3251
    instead of doing tree traverse later.
3252
  */
3253
  if (row_eligible && !warning_for_row &&
3254
      (!tree || (el->count == 1 && distinct && !arg_count_order)))
3255
    dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3256
3257
  return 0;
3258
}
3259
3260
3261
bool
3262
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3263
{
3264
  uint i;                       /* for loop variable */
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3265
  assert(fixed == 0);
1 by brian
clean slate
3266
3267
  if (init_sum_func_check(thd))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3268
    return true;
1 by brian
clean slate
3269
3270
  maybe_null= 1;
3271
3272
  /*
3273
    Fix fields for select list and ORDER clause
3274
  */
3275
3276
  for (i=0 ; i < arg_count ; i++)
3277
  {
3278
    if ((!args[i]->fixed &&
3279
         args[i]->fix_fields(thd, args + i)) ||
3280
        args[i]->check_cols(1))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3281
      return true;
1 by brian
clean slate
3282
  }
3283
3284
  if (agg_item_charsets(collation, func_name(),
3285
                        args,
3286
			/* skip charset aggregation for order columns */
3287
			arg_count - arg_count_order,
3288
			MY_COLL_ALLOW_CONV, 1))
3289
    return 1;
3290
3291
  result.set_charset(collation.collation);
3292
  result_field= 0;
3293
  null_value= 1;
3294
  max_length= thd->variables.group_concat_max_len;
3295
3296
  uint32 offset;
3297
  if (separator->needs_conversion(separator->length(), separator->charset(),
3298
                                  collation.collation, &offset))
3299
  {
3300
    uint32 buflen= collation.collation->mbmaxlen * separator->length();
3301
    uint errors, conv_length;
3302
    char *buf;
3303
    String *new_separator;
3304
3305
    if (!(buf= (char*) thd->stmt_arena->alloc(buflen)) ||
3306
        !(new_separator= new(thd->stmt_arena->mem_root)
3307
                           String(buf, buflen, collation.collation)))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3308
      return true;
1 by brian
clean slate
3309
    
3310
    conv_length= copy_and_convert(buf, buflen, collation.collation,
3311
                                  separator->ptr(), separator->length(),
3312
                                  separator->charset(), &errors);
3313
    new_separator->length(conv_length);
3314
    separator= new_separator;
3315
  }
3316
3317
  if (check_sum_func(thd, ref))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3318
    return true;
1 by brian
clean slate
3319
3320
  fixed= 1;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3321
  return false;
1 by brian
clean slate
3322
}
3323
3324
3325
bool Item_func_group_concat::setup(THD *thd)
3326
{
3327
  List<Item> list;
3328
  SELECT_LEX *select_lex= thd->lex->current_select;
3329
3330
  /*
3331
    Currently setup() can be called twice. Please add
3332
    assertion here when this is fixed.
3333
  */
3334
  if (table || tree)
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3335
    return(false);
1 by brian
clean slate
3336
3337
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3338
    return(true);
1 by brian
clean slate
3339
3340
  /* We'll convert all blobs to varchar fields in the temporary table */
3341
  tmp_table_param->convert_blob_length= max_length *
3342
                                        collation.collation->mbmaxlen;
3343
  /* Push all not constant fields to the list and create a temp table */
3344
  always_null= 0;
3345
  for (uint i= 0; i < arg_count_field; i++)
3346
  {
3347
    Item *item= args[i];
3348
    if (list.push_back(item))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3349
      return(true);
1 by brian
clean slate
3350
    if (item->const_item())
3351
    {
3352
      if (item->is_null())
3353
      {
3354
        always_null= 1;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3355
        return(false);
1 by brian
clean slate
3356
      }
3357
    }
3358
  }
3359
3360
  List<Item> all_fields(list);
3361
  /*
3362
    Try to find every ORDER expression in the list of GROUP_CONCAT
3363
    arguments. If an expression is not found, prepend it to
3364
    "all_fields". The resulting field list is used as input to create
3365
    tmp table columns.
3366
  */
3367
  if (arg_count_order &&
3368
      setup_order(thd, args, context->table_list, list, all_fields, *order))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3369
    return(true);
1 by brian
clean slate
3370
3371
  count_field_types(select_lex, tmp_table_param, all_fields, 0);
3372
  tmp_table_param->force_copy_fields= force_copy_fields;
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3373
  assert(table == 0);
1 by brian
clean slate
3374
  if (arg_count_order > 0 || distinct)
3375
  {
3376
    /*
3377
      Currently we have to force conversion of BLOB values to VARCHAR's
3378
      if we are to store them in TREE objects used for ORDER BY and
3379
      DISTINCT. This leads to truncation if the BLOB's size exceeds
3380
      Field_varstring::MAX_SIZE.
3381
    */
3382
    set_if_smaller(tmp_table_param->convert_blob_length, 
3383
                   Field_varstring::MAX_SIZE);
3384
  }
3385
3386
  /*
3387
    We have to create a temporary table to get descriptions of fields
3388
    (types, sizes and so on).
3389
3390
    Note that in the table, we first have the ORDER BY fields, then the
3391
    field list.
3392
  */
3393
  if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3394
                                (ORDER*) 0, 0, true,
1 by brian
clean slate
3395
                                (select_lex->options | thd->options),
3396
                                HA_POS_ERROR, (char*) "")))
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3397
    return(true);
1 by brian
clean slate
3398
  table->file->extra(HA_EXTRA_NO_ROWS);
3399
  table->no_rows= 1;
3400
3401
  /*
3402
     Need sorting or uniqueness: init tree and choose a function to sort.
3403
     Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3404
     the row is not added to the result.
3405
  */
3406
  uint tree_key_length= table->s->reclength - table->s->null_bytes;
3407
3408
  if (arg_count_order)
3409
  {
3410
    tree= &tree_base;
3411
    /*
3412
      Create a tree for sorting. The tree is used to sort (according to the
3413
      syntax of this function). If there is no ORDER BY clause, we don't
3414
      create this tree.
3415
    */
3416
    init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
3417
                               thd->variables.sortbuff_size/16), 0,
3418
              tree_key_length, 
3419
              group_concat_key_cmp_with_order , 0, NULL, (void*) this);
3420
  }
3421
3422
  if (distinct)
3423
    unique_filter= new Unique(group_concat_key_cmp_with_distinct,
3424
                              (void*)this,
3425
                              tree_key_length,
3426
                              thd->variables.max_heap_table_size);
3427
  
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3428
  return(false);
1 by brian
clean slate
3429
}
3430
3431
3432
/* This is used by rollup to create a separate usable copy of the function */
3433
3434
void Item_func_group_concat::make_unique()
3435
{
3436
  tmp_table_param= 0;
3437
  table=0;
3438
  original= 0;
3439
  force_copy_fields= 1;
3440
  tree= 0;
3441
}
3442
3443
77.1.15 by Monty Taylor
Bunch of warning cleanups.
3444
String* Item_func_group_concat::val_str(String* str __attribute__((__unused__)))
1 by brian
clean slate
3445
{
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3446
  assert(fixed == 1);
1 by brian
clean slate
3447
  if (null_value)
3448
    return 0;
3449
  if (no_appended && tree)
3450
    /* Tree is used for sorting as in ORDER BY */
3451
    tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
3452
              left_root_right);
3453
  if (count_cut_values && !warning)
3454
  {
3455
    /*
3456
      ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in
3457
      Item_func_group_concat::cleanup().
3458
    */
51.1.25 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
3459
    assert(table);
1 by brian
clean slate
3460
    warning= push_warning(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
3461
                          ER_CUT_VALUE_GROUP_CONCAT,
3462
                          ER(ER_CUT_VALUE_GROUP_CONCAT));
3463
  }
3464
  return &result;
3465
}
3466
3467
3468
void Item_func_group_concat::print(String *str, enum_query_type query_type)
3469
{
3470
  str->append(STRING_WITH_LEN("group_concat("));
3471
  if (distinct)
3472
    str->append(STRING_WITH_LEN("distinct "));
3473
  for (uint i= 0; i < arg_count_field; i++)
3474
  {
3475
    if (i)
3476
      str->append(',');
3477
    args[i]->print(str, query_type);
3478
  }
3479
  if (arg_count_order)
3480
  {
3481
    str->append(STRING_WITH_LEN(" order by "));
3482
    for (uint i= 0 ; i < arg_count_order ; i++)
3483
    {
3484
      if (i)
3485
        str->append(',');
3486
      (*order[i]->item)->print(str, query_type);
3487
      if (order[i]->asc)
3488
        str->append(STRING_WITH_LEN(" ASC"));
3489
      else
3490
        str->append(STRING_WITH_LEN(" DESC"));
3491
    }
3492
  }
3493
  str->append(STRING_WITH_LEN(" separator \'"));
3494
  str->append(*separator);
3495
  str->append(STRING_WITH_LEN("\')"));
3496
}
3497
3498
3499
Item_func_group_concat::~Item_func_group_concat()
3500
{
3501
  if (!original && unique_filter)
3502
    delete unique_filter;    
3503
}