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