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