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