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