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