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