~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/item_sum.cc

  • Committer: Brian Aker
  • Date: 2008-06-28 01:01:34 UTC
  • Revision ID: brian@tangent.org-20080628010134-n44ixrdgb6yexhkb
Remove my_pthread_getspecific_ptr()

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
  @brief
21
21
  Sum functions (COUNT, MIN...)
22
22
*/
23
 
#include "config.h"
24
 
#include <cstdio>
25
 
#include <math.h>
26
 
#include <drizzled/sql_select.h>
27
 
#include <drizzled/error.h>
28
 
#include <drizzled/hybrid_type_traits.h>
29
 
#include <drizzled/hybrid_type_traits_integer.h>
30
 
#include <drizzled/hybrid_type_traits_decimal.h>
31
 
#include <drizzled/sql_base.h>
32
 
 
33
 
#include <drizzled/item/sum.h>
34
 
#include <drizzled/field/decimal.h>
35
 
#include <drizzled/field/double.h>
36
 
#include <drizzled/field/int64_t.h>
37
 
#include <drizzled/field/date.h>
38
 
#include <drizzled/field/datetime.h>
39
 
 
40
 
#include "drizzled/internal/m_string.h"
41
 
 
42
 
#include <algorithm>
43
 
 
44
 
using namespace std;
45
 
 
46
 
namespace drizzled
47
 
{
48
 
 
49
 
extern my_decimal decimal_zero;
50
 
extern plugin::StorageEngine *heap_engine;
 
23
 
 
24
#ifdef USE_PRAGMA_IMPLEMENTATION
 
25
#pragma implementation                          // gcc: Class implementation
 
26
#endif
 
27
 
 
28
#include "mysql_priv.h"
 
29
#include "sql_select.h"
51
30
 
52
31
/**
53
32
  Prepare an aggregate function item for checking context conditions.
58
37
    If the set function is not allowed in any subquery where it occurs
59
38
    an error is reported immediately.
60
39
 
61
 
  @param session      reference to the thread context info
 
40
  @param thd      reference to the thread context info
62
41
 
63
42
  @note
64
43
    This function is to be called for any item created for a set function
70
49
  @retval
71
50
    FALSE  otherwise
72
51
*/
73
 
 
74
 
bool Item_sum::init_sum_func_check(Session *session)
 
52
 
 
53
bool Item_sum::init_sum_func_check(THD *thd)
75
54
{
76
 
  if (!session->lex->allow_sum_func)
 
55
  if (!thd->lex->allow_sum_func)
77
56
  {
78
57
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
79
58
               MYF(0));
80
 
    return true;
 
59
    return TRUE;
81
60
  }
82
61
  /* Set a reference to the nesting set function if there is  any */
83
 
  in_sum_func= session->lex->in_sum_func;
 
62
  in_sum_func= thd->lex->in_sum_func;
84
63
  /* Save a pointer to object to be used in items for nested set functions */
85
 
  session->lex->in_sum_func= this;
86
 
  nest_level= session->lex->current_select->nest_level;
 
64
  thd->lex->in_sum_func= this;
 
65
  nest_level= thd->lex->current_select->nest_level;
87
66
  ref_by= 0;
88
67
  aggr_level= -1;
89
68
  aggr_sel= NULL;
90
69
  max_arg_level= -1;
91
70
  max_sum_func_level= -1;
92
71
  outer_fields.empty();
93
 
  return false;
 
72
  return FALSE;
94
73
}
95
74
 
96
75
/**
105
84
    If the context conditions are not met the method reports an error.
106
85
    If the set function is aggregated in some outer subquery the method
107
86
    adds it to the chain of items for such set functions that is attached
108
 
    to the the Select_Lex structure for this subquery.
 
87
    to the the st_select_lex structure for this subquery.
109
88
 
110
89
    A number of designated members of the object are used to check the
111
90
    conditions. They are specified in the comment before the Item_sum
112
91
    class declaration.
113
92
    Additionally a bitmap variable called allow_sum_func is employed.
114
 
    It is included into the session->lex structure.
 
93
    It is included into the thd->lex structure.
115
94
    The bitmap contains 1 at n-th position if the set function happens
116
95
    to occur under a construct of the n-th level subquery where usage
117
96
    of set functions are allowed (i.e either in the SELECT list or
122
101
         HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
123
102
                t1.a > (SELECT MIN(t2.d) FROM t2);
124
103
    @endcode
125
 
    allow_sum_func will contain:
126
 
    - for SUM(t1.b) - 1 at the first position
 
104
    allow_sum_func will contain: 
 
105
    - for SUM(t1.b) - 1 at the first position 
127
106
    - for AVG(t1.b) - 1 at the first position, 0 at the second position
128
107
    - for MIN(t2.d) - 1 at the first position, 1 at the second position.
129
108
 
130
 
  @param session  reference to the thread context info
 
109
  @param thd  reference to the thread context info
131
110
  @param ref  location of the pointer to this item in the embedding expression
132
111
 
133
112
  @note
141
120
  @retval
142
121
    FALSE  otherwise
143
122
*/
144
 
 
145
 
bool Item_sum::check_sum_func(Session *session, Item **ref)
 
123
 
 
124
bool Item_sum::check_sum_func(THD *thd, Item **ref)
146
125
{
147
 
  bool invalid= false;
148
 
  nesting_map allow_sum_func= session->lex->allow_sum_func;
149
 
  /*
 
126
  bool invalid= FALSE;
 
127
  nesting_map allow_sum_func= thd->lex->allow_sum_func;
 
128
  /*  
150
129
    The value of max_arg_level is updated if an argument of the set function
151
130
    contains a column reference resolved  against a subquery whose level is
152
131
    greater than the current value of max_arg_level.
153
132
    max_arg_level cannot be greater than nest level.
154
 
    nest level is always >= 0
155
 
  */
 
133
    nest level is always >= 0  
 
134
  */ 
156
135
  if (nest_level == max_arg_level)
157
136
  {
158
137
    /*
159
 
      The function must be aggregated in the current subquery,
160
 
      If it is there under a construct where it is not allowed
161
 
      we report an error.
162
 
    */
 
138
      The function must be aggregated in the current subquery, 
 
139
      If it is there under a construct where it is not allowed 
 
140
      we report an error. 
 
141
    */ 
163
142
    invalid= !(allow_sum_func & (1 << max_arg_level));
164
143
  }
165
144
  else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
169
148
      Try to find a subquery where it can be aggregated;
170
149
      If we fail to find such a subquery report an error.
171
150
    */
172
 
    if (register_sum_func(session, ref))
173
 
      return true;
 
151
    if (register_sum_func(thd, ref))
 
152
      return TRUE;
174
153
    invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
175
 
    if (!invalid && false)
 
154
    if (!invalid && thd->variables.sql_mode & MODE_ANSI)
176
155
      invalid= aggr_level < 0 && max_arg_level < nest_level;
177
156
  }
178
157
  if (!invalid && aggr_level < 0)
179
158
  {
180
159
    aggr_level= nest_level;
181
 
    aggr_sel= session->lex->current_select;
 
160
    aggr_sel= thd->lex->current_select;
182
161
  }
183
162
  /*
184
163
    By this moment we either found a subquery where the set function is
185
164
    to be aggregated  and assigned a value that is  >= 0 to aggr_level,
186
 
    or set the value of 'invalid' to TRUE to report later an error.
 
165
    or set the value of 'invalid' to TRUE to report later an error. 
187
166
  */
188
 
  /*
 
167
  /* 
189
168
    Additionally we have to check whether possible nested set functions
190
169
    are acceptable here: they are not, if the level of aggregation of
191
170
    some of them is less than aggr_level.
192
171
  */
193
 
  if (!invalid)
 
172
  if (!invalid) 
194
173
    invalid= aggr_level <= max_sum_func_level;
195
 
  if (invalid)
 
174
  if (invalid)  
196
175
  {
197
176
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
198
177
               MYF(0));
199
 
    return true;
 
178
    return TRUE;
200
179
  }
201
180
 
202
181
  if (in_sum_func)
204
183
    /*
205
184
      If the set function is nested adjust the value of
206
185
      max_sum_func_level for the nesting set function.
207
 
      We take into account only enclosed set functions that are to be
208
 
      aggregated on the same level or above of the nest level of
 
186
      We take into account only enclosed set functions that are to be 
 
187
      aggregated on the same level or above of the nest level of 
209
188
      the enclosing set function.
210
189
      But we must always pass up the max_sum_func_level because it is
211
190
      the maximum nested level of all directly and indirectly enclosed
256
235
    List_iterator<Item_field> of(outer_fields);
257
236
    while ((field= of++))
258
237
    {
259
 
      Select_Lex *sel= field->cached_table->select_lex;
 
238
      SELECT_LEX *sel= field->cached_table->select_lex;
260
239
      if (sel->nest_level < aggr_level)
261
240
      {
262
241
        if (in_sum_func)
268
247
          in_sum_func->outer_fields.push_back(field);
269
248
        }
270
249
        else
271
 
        {
272
 
          sel->full_group_by_flag.set(NON_AGG_FIELD_USED);
273
 
        }
 
250
          sel->full_group_by_flag|= NON_AGG_FIELD_USED;
274
251
      }
275
252
      if (sel->nest_level > aggr_level &&
276
 
          (sel->full_group_by_flag.test(SUM_FUNC_USED)) &&
277
 
          ! sel->group_list.elements)
 
253
          (sel->full_group_by_flag & SUM_FUNC_USED) &&
 
254
          !sel->group_list.elements)
278
255
      {
279
256
        my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
280
257
                   ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
281
 
        return true;
 
258
        return TRUE;
282
259
      }
283
260
    }
284
261
  }
285
 
  aggr_sel->full_group_by_flag.set(SUM_FUNC_USED);
 
262
  aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
286
263
  update_used_tables();
287
 
  session->lex->in_sum_func= in_sum_func;
288
 
  return false;
 
264
  thd->lex->in_sum_func= in_sum_func;
 
265
  return FALSE;
289
266
}
290
267
 
291
268
/**
295
272
    aggregated. If it finds such a subquery then aggr_level is set to
296
273
    the nest level of this subquery and the item for the set function
297
274
    is added to the list of set functions used in nested subqueries
298
 
    inner_sum_func_list defined for each subquery. When the item is placed
 
275
    inner_sum_func_list defined for each subquery. When the item is placed 
299
276
    there the field 'ref_by' is set to ref.
300
277
 
301
278
  @note
304
281
    a subquery in one chain. It would simplify the process of 'splitting'
305
282
    for set functions.
306
283
 
307
 
  @param session  reference to the thread context info
 
284
  @param thd  reference to the thread context info
308
285
  @param ref  location of the pointer to this item in the embedding expression
309
286
 
310
287
  @retval
311
288
    FALSE  if the executes without failures (currently always)
312
289
  @retval
313
290
    TRUE   otherwise
314
 
*/
 
291
*/  
315
292
 
316
 
bool Item_sum::register_sum_func(Session *session, Item **ref)
 
293
bool Item_sum::register_sum_func(THD *thd, Item **ref)
317
294
{
318
 
  Select_Lex *sl;
319
 
  nesting_map allow_sum_func= session->lex->allow_sum_func;
320
 
  for (sl= session->lex->current_select->master_unit()->outer_select() ;
 
295
  SELECT_LEX *sl;
 
296
  nesting_map allow_sum_func= thd->lex->allow_sum_func;
 
297
  for (sl= thd->lex->current_select->master_unit()->outer_select() ;
321
298
       sl && sl->nest_level > max_arg_level;
322
299
       sl= sl->master_unit()->outer_select() )
323
300
  {
330
307
  }
331
308
  if (sl && (allow_sum_func & (1 << sl->nest_level)))
332
309
  {
333
 
    /*
 
310
    /* 
334
311
      We reached the subquery of level max_arg_level and checked
335
 
      that the function can be aggregated here.
 
312
      that the function can be aggregated here. 
336
313
      The set function will be aggregated in this subquery.
337
 
    */
 
314
    */   
338
315
    aggr_level= sl->nest_level;
339
316
    aggr_sel= sl;
340
317
 
353
330
    aggr_sel->inner_sum_func_list= this;
354
331
    aggr_sel->with_sum_func= 1;
355
332
 
356
 
    /*
 
333
    /* 
357
334
      Mark Item_subselect(s) as containing aggregate function all the way up
358
335
      to aggregate function's calculation context.
359
336
      Note that we must not mark the Item of calculation context itself
360
 
      because with_sum_func on the calculation context Select_Lex is
 
337
      because with_sum_func on the calculation context st_select_lex is
361
338
      already set above.
362
339
 
363
 
      with_sum_func being set for an Item means that this Item refers
 
340
      with_sum_func being set for an Item means that this Item refers 
364
341
      (somewhere in it, e.g. one of its arguments if it's a function) directly
365
342
      or through intermediate items to an aggregate function that is calculated
366
343
      in a context "outside" of the Item (e.g. in the current or outer select).
367
344
 
368
 
      with_sum_func being set for an Select_Lex means that this Select_Lex
 
345
      with_sum_func being set for an st_select_lex means that this st_select_lex
369
346
      has aggregate functions directly referenced (i.e. not through a sub-select).
370
347
    */
371
 
    for (sl= session->lex->current_select;
 
348
    for (sl= thd->lex->current_select; 
372
349
         sl && sl != aggr_sel && sl->master_unit()->item;
373
350
         sl= sl->master_unit()->outer_select() )
374
351
      sl->master_unit()->item->with_sum_func= 1;
375
352
  }
376
 
  session->lex->current_select->mark_as_dependent(aggr_sel);
377
 
  return false;
 
353
  thd->lex->current_select->mark_as_dependent(aggr_sel);
 
354
  return FALSE;
378
355
}
379
356
 
380
357
 
381
 
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
382
 
  forced_const(false)
 
358
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), 
 
359
  forced_const(FALSE)
383
360
{
384
 
  if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
 
361
  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
385
362
  {
386
 
    uint32_t i=0;
 
363
    uint i=0;
387
364
    List_iterator_fast<Item> li(list);
388
365
    Item *item;
389
366
 
401
378
  Constructor used in processing select with temporary tebles.
402
379
*/
403
380
 
404
 
Item_sum::Item_sum(Session *session, Item_sum *item):
405
 
  Item_result_field(session, item), arg_count(item->arg_count),
 
381
Item_sum::Item_sum(THD *thd, Item_sum *item):
 
382
  Item_result_field(thd, item), arg_count(item->arg_count),
406
383
  aggr_sel(item->aggr_sel),
407
384
  nest_level(item->nest_level), aggr_level(item->aggr_level),
408
385
  quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
409
 
  forced_const(item->forced_const)
 
386
  forced_const(item->forced_const) 
410
387
{
411
388
  if (arg_count <= 2)
412
389
    args=tmp_args;
413
390
  else
414
 
    if (!(args= (Item**) session->alloc(sizeof(Item*)*arg_count)))
 
391
    if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
415
392
      return;
416
393
  memcpy(args, item->args, sizeof(Item*)*arg_count);
417
394
}
419
396
 
420
397
void Item_sum::mark_as_sum_func()
421
398
{
422
 
  Select_Lex *cur_select= current_session->lex->current_select;
 
399
  SELECT_LEX *cur_select= current_thd->lex->current_select;
423
400
  cur_select->n_sum_items++;
424
401
  cur_select->with_sum_func= 1;
425
402
  with_sum_func= 1;
426
403
}
427
404
 
428
405
 
429
 
void Item_sum::make_field(SendField *tmp_field)
 
406
void Item_sum::make_field(Send_field *tmp_field)
430
407
{
431
408
  if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
432
409
  {
449
426
void Item_sum::print(String *str, enum_query_type query_type)
450
427
{
451
428
  str->append(func_name());
452
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
429
  for (uint i=0 ; i < arg_count ; i++)
453
430
  {
454
431
    if (i)
455
432
      str->append(',');
461
438
void Item_sum::fix_num_length_and_dec()
462
439
{
463
440
  decimals=0;
464
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
441
  for (uint i=0 ; i < arg_count ; i++)
465
442
    set_if_bigger(decimals,args[i]->decimals);
466
443
  max_length=float_length(decimals);
467
444
}
468
445
 
469
 
Item *Item_sum::get_tmp_table_item(Session *session)
 
446
Item *Item_sum::get_tmp_table_item(THD *thd)
470
447
{
471
 
  Item_sum* sum_item= (Item_sum *) copy_or_same(session);
 
448
  Item_sum* sum_item= (Item_sum *) copy_or_same(thd);
472
449
  if (sum_item && sum_item->result_field)          // If not a const sum func
473
450
  {
474
451
    Field *result_field_tmp= sum_item->result_field;
475
 
    for (uint32_t i=0 ; i < sum_item->arg_count ; i++)
 
452
    for (uint i=0 ; i < sum_item->arg_count ; i++)
476
453
    {
477
454
      Item *arg= sum_item->args[i];
478
455
      if (!arg->const_item())
489
466
 
490
467
 
491
468
bool Item_sum::walk (Item_processor processor, bool walk_subquery,
492
 
                     unsigned char *argument)
 
469
                     uchar *argument)
493
470
{
494
471
  if (arg_count)
495
472
  {
504
481
}
505
482
 
506
483
 
507
 
Field *Item_sum::create_tmp_field(bool ,
508
 
                                  Table *table,
509
 
                                  uint32_t convert_blob_length)
 
484
Field *Item_sum::create_tmp_field(bool group, TABLE *table,
 
485
                                  uint convert_blob_length)
510
486
{
511
487
  Field *field;
512
488
  switch (result_type()) {
513
489
  case REAL_RESULT:
514
 
    field= new Field_double(max_length, maybe_null, name, decimals, true);
 
490
    field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
515
491
    break;
516
492
  case INT_RESULT:
517
 
    field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
 
493
    field= new Field_longlong(max_length, maybe_null, name, unsigned_flag);
518
494
    break;
519
495
  case STRING_RESULT:
520
496
    if (max_length/collation.collation->mbmaxlen <= 255 ||
522
498
        !convert_blob_length)
523
499
      return make_string_field(table);
524
500
    field= new Field_varstring(convert_blob_length, maybe_null,
525
 
                               name, table->getMutableShare(), collation.collation);
 
501
                               name, table->s, collation.collation);
526
502
    break;
527
503
  case DECIMAL_RESULT:
528
 
    field= new Field_decimal(max_length, maybe_null, name,
 
504
    field= new Field_new_decimal(max_length, maybe_null, name,
529
505
                                 decimals, unsigned_flag);
530
506
    break;
531
507
  case ROW_RESULT:
532
508
  default:
533
509
    // This case should never be choosen
534
 
    assert(0);
 
510
    DBUG_ASSERT(0);
535
511
    return 0;
536
512
  }
537
513
  if (field)
545
521
  if (!forced_const)
546
522
  {
547
523
    used_tables_cache= 0;
548
 
    for (uint32_t i=0 ; i < arg_count ; i++)
 
524
    for (uint i=0 ; i < arg_count ; i++)
549
525
    {
550
526
      args[i]->update_used_tables();
551
527
      used_tables_cache|= args[i]->used_tables();
566
542
}
567
543
 
568
544
 
569
 
int64_t Item_sum_num::val_int()
570
 
{
571
 
  assert(fixed == 1);
572
 
  return (int64_t) rint(val_real());             /* Real as default */
573
 
}
574
 
 
575
 
 
576
545
my_decimal *Item_sum_num::val_decimal(my_decimal *decimal_value)
577
546
{
578
547
  return val_decimal_from_real(decimal_value);
593
562
 
594
563
 
595
564
bool
596
 
Item_sum_num::fix_fields(Session *session, Item **ref)
 
565
Item_sum_num::fix_fields(THD *thd, Item **ref)
597
566
{
598
 
  assert(fixed == 0);
 
567
  DBUG_ASSERT(fixed == 0);
599
568
 
600
 
  if (init_sum_func_check(session))
601
 
    return true;
 
569
  if (init_sum_func_check(thd))
 
570
    return TRUE;
602
571
 
603
572
  decimals=0;
604
573
  maybe_null=0;
605
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
574
  for (uint i=0 ; i < arg_count ; i++)
606
575
  {
607
 
    if (args[i]->fix_fields(session, args + i) || args[i]->check_cols(1))
608
 
      return true;
 
576
    if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
 
577
      return TRUE;
609
578
    set_if_bigger(decimals, args[i]->decimals);
610
579
    maybe_null |= args[i]->maybe_null;
611
580
  }
614
583
  null_value=1;
615
584
  fix_length_and_dec();
616
585
 
617
 
  if (check_sum_func(session, ref))
618
 
    return true;
 
586
  if (check_sum_func(thd, ref))
 
587
    return TRUE;
619
588
 
620
589
  fixed= 1;
621
 
  return false;
 
590
  return FALSE;
622
591
}
623
592
 
624
593
 
625
 
Item_sum_hybrid::Item_sum_hybrid(Session *session, Item_sum_hybrid *item)
626
 
  :Item_sum(session, item), value(item->value), hybrid_type(item->hybrid_type),
 
594
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
 
595
  :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
627
596
  hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
628
597
  was_values(item->was_values)
629
598
{
646
615
    break;
647
616
  case ROW_RESULT:
648
617
  default:
649
 
    assert(0);
 
618
    DBUG_ASSERT(0);
650
619
  }
651
620
  collation.set(item->collation);
652
621
}
653
622
 
654
623
bool
655
 
Item_sum_hybrid::fix_fields(Session *session, Item **ref)
 
624
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
656
625
{
657
 
  assert(fixed == 0);
 
626
  DBUG_ASSERT(fixed == 0);
658
627
 
659
628
  Item *item= args[0];
660
629
 
661
 
  if (init_sum_func_check(session))
662
 
    return true;
 
630
  if (init_sum_func_check(thd))
 
631
    return TRUE;
663
632
 
664
633
  // 'item' can be changed during fix_fields
665
 
  if ((!item->fixed && item->fix_fields(session, args)) ||
 
634
  if ((!item->fixed && item->fix_fields(thd, args)) ||
666
635
      (item= args[0])->check_cols(1))
667
 
    return true;
 
636
    return TRUE;
668
637
  decimals=item->decimals;
669
638
 
670
639
  switch (hybrid_type= item->result_type()) {
685
654
    break;
686
655
  case ROW_RESULT:
687
656
  default:
688
 
    assert(0);
 
657
    DBUG_ASSERT(0);
689
658
  };
690
659
  /* MIN/MAX can return NULL for empty set indepedent of the used column */
691
660
  maybe_null= 1;
700
669
  else
701
670
    hybrid_field_type= Item::field_type();
702
671
 
703
 
  if (check_sum_func(session, ref))
704
 
    return true;
 
672
  if (check_sum_func(thd, ref))
 
673
    return TRUE;
705
674
 
706
675
  fixed= 1;
707
 
  return false;
 
676
  return FALSE;
708
677
}
709
678
 
710
 
Field *Item_sum_hybrid::create_tmp_field(bool group, Table *table,
711
 
                                         uint32_t convert_blob_length)
 
679
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
 
680
                                         uint convert_blob_length)
712
681
{
713
682
  Field *field;
714
683
  if (args[0]->type() == Item::FIELD_ITEM)
715
684
  {
716
685
    field= ((Item_field*) args[0])->field;
717
 
 
718
 
    if ((field= create_tmp_field_from_field(current_session, field, name, table,
 
686
    
 
687
    if ((field= create_tmp_field_from_field(current_thd, field, name, table,
719
688
                                            NULL, convert_blob_length)))
720
689
      field->flags&= ~NOT_NULL_FLAG;
721
690
    return field;
726
695
    fields creations separately.
727
696
  */
728
697
  switch (args[0]->field_type()) {
729
 
  case DRIZZLE_TYPE_DATE:
730
 
    field= new Field_date(maybe_null, name, collation.collation);
731
 
    break;
732
 
  case DRIZZLE_TYPE_TIMESTAMP:
733
 
  case DRIZZLE_TYPE_DATETIME:
 
698
  case MYSQL_TYPE_DATE:
 
699
    field= new Field_newdate(maybe_null, name, collation.collation);
 
700
    break;
 
701
  case MYSQL_TYPE_TIME:
 
702
    field= new Field_time(maybe_null, name, collation.collation);
 
703
    break;
 
704
  case MYSQL_TYPE_TIMESTAMP:
 
705
  case MYSQL_TYPE_DATETIME:
734
706
    field= new Field_datetime(maybe_null, name, collation.collation);
735
707
    break;
736
708
  default:
750
722
  @todo
751
723
  check if the following assignments are really needed
752
724
*/
753
 
Item_sum_sum::Item_sum_sum(Session *session, Item_sum_sum *item)
754
 
  :Item_sum_num(session, item), hybrid_type(item->hybrid_type),
 
725
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item) 
 
726
  :Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
755
727
   curr_dec_buff(item->curr_dec_buff)
756
728
{
757
729
  /* TODO: check if the following assignments are really needed */
764
736
    sum= item->sum;
765
737
}
766
738
 
767
 
Item *Item_sum_sum::copy_or_same(Session* session)
 
739
Item *Item_sum_sum::copy_or_same(THD* thd)
768
740
{
769
 
  return new (session->mem_root) Item_sum_sum(session, this);
 
741
  return new (thd->mem_root) Item_sum_sum(thd, this);
770
742
}
771
743
 
772
744
 
773
745
void Item_sum_sum::clear()
774
746
{
 
747
  DBUG_ENTER("Item_sum_sum::clear");
775
748
  null_value=1;
776
749
  if (hybrid_type == DECIMAL_RESULT)
777
750
  {
780
753
  }
781
754
  else
782
755
    sum= 0.0;
783
 
  return;
 
756
  DBUG_VOID_RETURN;
784
757
}
785
758
 
786
759
 
787
760
void Item_sum_sum::fix_length_and_dec()
788
761
{
 
762
  DBUG_ENTER("Item_sum_sum::fix_length_and_dec");
789
763
  maybe_null=null_value=1;
790
764
  decimals= args[0]->decimals;
791
765
  switch (args[0]->result_type()) {
808
782
  }
809
783
  case ROW_RESULT:
810
784
  default:
811
 
    assert(0);
 
785
    DBUG_ASSERT(0);
812
786
  }
813
 
  return;
 
787
  DBUG_PRINT("info", ("Type: %s (%d, %d)",
 
788
                      (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
 
789
                       hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
 
790
                       hybrid_type == INT_RESULT ? "INT_RESULT" :
 
791
                       "--ILLEGAL!!!--"),
 
792
                      max_length,
 
793
                      (int)decimals));
 
794
  DBUG_VOID_RETURN;
814
795
}
815
796
 
816
797
 
817
798
bool Item_sum_sum::add()
818
799
{
 
800
  DBUG_ENTER("Item_sum_sum::add");
819
801
  if (hybrid_type == DECIMAL_RESULT)
820
802
  {
821
803
    my_decimal value, *val= args[0]->val_decimal(&value);
833
815
    if (!args[0]->null_value)
834
816
      null_value= 0;
835
817
  }
836
 
  return(0);
 
818
  DBUG_RETURN(0);
837
819
}
838
820
 
839
821
 
840
 
int64_t Item_sum_sum::val_int()
 
822
longlong Item_sum_sum::val_int()
841
823
{
842
 
  assert(fixed == 1);
 
824
  DBUG_ASSERT(fixed == 1);
843
825
  if (hybrid_type == DECIMAL_RESULT)
844
826
  {
845
 
    int64_t result;
 
827
    longlong result;
846
828
    my_decimal2int(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, unsigned_flag,
847
829
                   &result);
848
830
    return result;
849
831
  }
850
 
  return (int64_t) rint(val_real());
 
832
  return (longlong) rint(val_real());
851
833
}
852
834
 
853
835
 
854
836
double Item_sum_sum::val_real()
855
837
{
856
 
  assert(fixed == 1);
 
838
  DBUG_ASSERT(fixed == 1);
857
839
  if (hybrid_type == DECIMAL_RESULT)
858
840
    my_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum);
859
841
  return sum;
877
859
 
878
860
/***************************************************************************/
879
861
 
 
862
C_MODE_START
 
863
 
880
864
/* Declarations for auxilary C-callbacks */
881
865
 
882
866
static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
883
867
{
884
 
    return memcmp(key1, key2, *(uint32_t *) arg);
 
868
    return memcmp(key1, key2, *(uint *) arg);
885
869
}
886
870
 
887
871
 
888
 
static int item_sum_distinct_walk(void *element,
889
 
                                  uint32_t ,
 
872
static int item_sum_distinct_walk(void *element, element_count num_of_dups,
890
873
                                  void *item)
891
874
{
892
875
  return ((Item_sum_distinct*) (item))->unique_walk_function(element);
893
876
}
894
877
 
 
878
C_MODE_END
 
879
 
895
880
/* Item_sum_distinct */
896
881
 
897
882
Item_sum_distinct::Item_sum_distinct(Item *item_arg)
907
892
}
908
893
 
909
894
 
910
 
Item_sum_distinct::Item_sum_distinct(Session *session, Item_sum_distinct *original)
911
 
  :Item_sum_num(session, original), val(original->val), tree(0),
 
895
Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
 
896
  :Item_sum_num(thd, original), val(original->val), tree(0),
912
897
  table_field_type(original->table_field_type)
913
898
{
914
899
  quick_group= 0;
929
914
  virtual void fix_length_and_dec(Item *item, Item *arg) const
930
915
  { Hybrid_type_traits_decimal::instance()->fix_length_and_dec(item, arg); }
931
916
 
932
 
  virtual void div(Hybrid_type *val, uint64_t u) const
 
917
  virtual void div(Hybrid_type *val, ulonglong u) const
933
918
  {
934
919
    int2my_decimal(E_DEC_FATAL_ERROR, val->integer, 0, val->dec_buf);
935
920
    val->used_dec_buf_no= 0;
948
933
  return &fast_decimal_traits_instance;
949
934
}
950
935
 
951
 
 
952
936
void Item_sum_distinct::fix_length_and_dec()
953
937
{
954
 
  assert(args[0]->fixed);
 
938
  DBUG_ASSERT(args[0]->fixed);
955
939
 
956
 
  null_value= maybe_null= true;
957
940
  table_field_type= args[0]->field_type();
958
941
 
959
942
  /* Adjust tmp table type according to the chosen aggregation type */
961
944
  case STRING_RESULT:
962
945
  case REAL_RESULT:
963
946
    val.traits= Hybrid_type_traits::instance();
964
 
    table_field_type= DRIZZLE_TYPE_DOUBLE;
 
947
    if (table_field_type != MYSQL_TYPE_FLOAT)
 
948
      table_field_type= MYSQL_TYPE_DOUBLE;
965
949
    break;
966
950
  case INT_RESULT:
967
951
  /*
968
952
    Preserving int8, int16, int32 field types gives ~10% performance boost
969
953
    as the size of result tree becomes significantly smaller.
970
 
    Another speed up we gain by using int64_t for intermediate
 
954
    Another speed up we gain by using longlong for intermediate
971
955
    calculations. The range of int64 is enough to hold sum 2^32 distinct
972
956
    integers each <= 2^32.
973
957
  */
974
 
  if (table_field_type == DRIZZLE_TYPE_LONG)
 
958
  if (table_field_type == MYSQL_TYPE_INT24 ||
 
959
      (table_field_type >= MYSQL_TYPE_TINY && table_field_type <= MYSQL_TYPE_LONG))
975
960
  {
976
961
    val.traits= Hybrid_type_traits_fast_decimal::instance();
977
962
    break;
978
963
  }
979
 
  table_field_type= DRIZZLE_TYPE_LONGLONG;
 
964
  table_field_type= MYSQL_TYPE_LONGLONG;
980
965
  /* fallthrough */
981
966
  case DECIMAL_RESULT:
982
967
    val.traits= Hybrid_type_traits_decimal::instance();
983
 
    if (table_field_type != DRIZZLE_TYPE_LONGLONG)
984
 
      table_field_type= DRIZZLE_TYPE_DECIMAL;
 
968
    if (table_field_type != MYSQL_TYPE_LONGLONG)
 
969
      table_field_type= MYSQL_TYPE_NEWDECIMAL;
985
970
    break;
986
971
  case ROW_RESULT:
987
972
  default:
988
 
    assert(0);
 
973
    DBUG_ASSERT(0);
989
974
  }
990
975
  val.traits->fix_length_and_dec(this, args[0]);
991
976
}
992
977
 
993
978
 
994
 
enum Item_result Item_sum_distinct::result_type () const
995
 
{
996
 
  return val.traits->type();
997
 
}
998
 
 
999
 
 
1000
979
/**
1001
980
  @todo
1002
981
  check that the case of CHAR(0) works OK
1003
982
*/
1004
 
bool Item_sum_distinct::setup(Session *session)
 
983
bool Item_sum_distinct::setup(THD *thd)
1005
984
{
1006
 
  List<CreateField> field_list;
1007
 
  CreateField field_def;                              /* field definition */
 
985
  List<Create_field> field_list;
 
986
  Create_field field_def;                              /* field definition */
 
987
  DBUG_ENTER("Item_sum_distinct::setup");
1008
988
  /* It's legal to call setup() more than once when in a subquery */
1009
989
  if (tree)
1010
 
    return(false);
 
990
    DBUG_RETURN(FALSE);
1011
991
 
1012
992
  /*
1013
993
    Virtual table and the tree are created anew on each re-execution of
1015
995
    mem_root.
1016
996
  */
1017
997
  if (field_list.push_back(&field_def))
1018
 
    return(true);
 
998
    DBUG_RETURN(TRUE);
1019
999
 
1020
1000
  null_value= maybe_null= 1;
1021
1001
  quick_group= 0;
1022
1002
 
1023
 
  assert(args[0]->fixed);
 
1003
  DBUG_ASSERT(args[0]->fixed);
1024
1004
 
1025
1005
  field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
1026
 
                               args[0]->decimals, args[0]->maybe_null);
 
1006
                               args[0]->decimals, args[0]->maybe_null,
 
1007
                               args[0]->unsigned_flag);
1027
1008
 
1028
 
  if (! (table= session->create_virtual_tmp_table(field_list)))
1029
 
    return(true);
 
1009
  if (! (table= create_virtual_tmp_table(thd, field_list)))
 
1010
    DBUG_RETURN(TRUE);
1030
1011
 
1031
1012
  /* XXX: check that the case of CHAR(0) works OK */
1032
 
  tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
 
1013
  tree_key_length= table->s->reclength - table->s->null_bytes;
1033
1014
 
1034
1015
  /*
1035
1016
    Unique handles all unique elements in a tree until they can't fit
1037
1018
    simple_raw_key_cmp because the table contains numbers only; decimals
1038
1019
    are converted to binary representation as well.
1039
1020
  */
1040
 
  tree= new Unique(simple_raw_key_cmp, &tree_key_length,
1041
 
                   tree_key_length,
1042
 
                   (size_t)session->variables.max_heap_table_size);
 
1021
  tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
 
1022
                   thd->variables.max_heap_table_size);
1043
1023
 
1044
 
  is_evaluated= false;
1045
 
  return(tree == 0);
 
1024
  is_evaluated= FALSE;
 
1025
  DBUG_RETURN(tree == 0);
1046
1026
}
1047
1027
 
1048
1028
 
1049
1029
bool Item_sum_distinct::add()
1050
1030
{
1051
 
  args[0]->save_in_field(table->getField(0), false);
1052
 
  is_evaluated= false;
1053
 
  if (!table->getField(0)->is_null())
 
1031
  args[0]->save_in_field(table->field[0], FALSE);
 
1032
  is_evaluated= FALSE;
 
1033
  if (!table->field[0]->is_null())
1054
1034
  {
1055
 
    assert(tree);
 
1035
    DBUG_ASSERT(tree);
1056
1036
    null_value= 0;
1057
1037
    /*
1058
1038
      '0' values are also stored in the tree. This doesn't matter
1059
1039
      for SUM(DISTINCT), but is important for AVG(DISTINCT)
1060
1040
    */
1061
 
    return tree->unique_add(table->getField(0)->ptr);
 
1041
    return tree->unique_add(table->field[0]->ptr);
1062
1042
  }
1063
1043
  return 0;
1064
1044
}
1066
1046
 
1067
1047
bool Item_sum_distinct::unique_walk_function(void *element)
1068
1048
{
1069
 
  memcpy(table->getField(0)->ptr, element, tree_key_length);
 
1049
  memcpy(table->field[0]->ptr, element, tree_key_length);
1070
1050
  ++count;
1071
 
  val.traits->add(&val, table->getField(0));
 
1051
  val.traits->add(&val, table->field[0]);
1072
1052
  return 0;
1073
1053
}
1074
1054
 
1075
1055
 
1076
1056
void Item_sum_distinct::clear()
1077
1057
{
1078
 
  assert(tree != 0);                        /* we always have a tree */
 
1058
  DBUG_ENTER("Item_sum_distinct::clear");
 
1059
  DBUG_ASSERT(tree != 0);                        /* we always have a tree */
1079
1060
  null_value= 1;
1080
1061
  tree->reset();
1081
 
  is_evaluated= false;
1082
 
  return;
 
1062
  is_evaluated= FALSE;
 
1063
  DBUG_VOID_RETURN;
1083
1064
}
1084
1065
 
1085
1066
void Item_sum_distinct::cleanup()
1088
1069
  delete tree;
1089
1070
  tree= 0;
1090
1071
  table= 0;
1091
 
  is_evaluated= false;
 
1072
  is_evaluated= FALSE;
1092
1073
}
1093
1074
 
1094
1075
Item_sum_distinct::~Item_sum_distinct()
1110
1091
     */
1111
1092
    if (tree)
1112
1093
    {
1113
 
      table->getField(0)->set_notnull();
 
1094
      table->field[0]->set_notnull();
1114
1095
      tree->walk(item_sum_distinct_walk, (void*) this);
1115
1096
    }
1116
 
    is_evaluated= true;
 
1097
    is_evaluated= TRUE;
1117
1098
  }
1118
1099
}
1119
1100
 
1134
1115
}
1135
1116
 
1136
1117
 
1137
 
int64_t Item_sum_distinct::val_int()
 
1118
longlong Item_sum_distinct::val_int()
1138
1119
{
1139
1120
  calculate_val_and_count();
1140
1121
  return val.traits->val_int(&val, unsigned_flag);
1157
1138
Item_sum_avg_distinct::fix_length_and_dec()
1158
1139
{
1159
1140
  Item_sum_distinct::fix_length_and_dec();
1160
 
  prec_increment= current_session->variables.div_precincrement;
 
1141
  prec_increment= current_thd->variables.div_precincrement;
1161
1142
  /*
1162
1143
    AVG() will divide val by count. We need to reserve digits
1163
1144
    after decimal point as the result can be fractional.
1164
1145
  */
1165
 
  decimals= min(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
 
1146
  decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
1166
1147
}
1167
1148
 
1168
1149
 
1174
1155
    Item_sum_distinct::calculate_val_and_count();
1175
1156
    if (count)
1176
1157
      val.traits->div(&val, count);
1177
 
    is_evaluated= true;
 
1158
    is_evaluated= TRUE;
1178
1159
  }
1179
1160
}
1180
1161
 
1181
1162
 
1182
 
Item *Item_sum_count::copy_or_same(Session* session)
 
1163
Item *Item_sum_count::copy_or_same(THD* thd)
1183
1164
{
1184
 
  return new (session->mem_root) Item_sum_count(session, this);
 
1165
  return new (thd->mem_root) Item_sum_count(thd, this);
1185
1166
}
1186
1167
 
1187
1168
 
1198
1179
  return 0;
1199
1180
}
1200
1181
 
1201
 
int64_t Item_sum_count::val_int()
 
1182
longlong Item_sum_count::val_int()
1202
1183
{
1203
 
  assert(fixed == 1);
1204
 
  return (int64_t) count;
 
1184
  DBUG_ASSERT(fixed == 1);
 
1185
  return (longlong) count;
1205
1186
}
1206
1187
 
1207
1188
 
1208
1189
void Item_sum_count::cleanup()
1209
1190
{
 
1191
  DBUG_ENTER("Item_sum_count::cleanup");
1210
1192
  count= 0;
1211
1193
  Item_sum_int::cleanup();
1212
 
  return;
 
1194
  DBUG_VOID_RETURN;
1213
1195
}
1214
1196
 
1215
1197
 
1220
1202
{
1221
1203
  Item_sum_sum::fix_length_and_dec();
1222
1204
  maybe_null=null_value=1;
1223
 
  prec_increment= current_session->variables.div_precincrement;
 
1205
  prec_increment= current_thd->variables.div_precincrement;
1224
1206
  if (hybrid_type == DECIMAL_RESULT)
1225
1207
  {
1226
1208
    int precision= args[0]->decimal_precision() + prec_increment;
1227
 
    decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
 
1209
    decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
1228
1210
    max_length= my_decimal_precision_to_length(precision, decimals,
1229
1211
                                               unsigned_flag);
1230
1212
    f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1232
1214
    dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
1233
1215
  }
1234
1216
  else {
1235
 
    decimals= min(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
 
1217
    decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
1236
1218
    max_length= args[0]->max_length + prec_increment;
1237
1219
  }
1238
1220
}
1239
1221
 
1240
1222
 
1241
 
Item *Item_sum_avg::copy_or_same(Session* session)
 
1223
Item *Item_sum_avg::copy_or_same(THD* thd)
1242
1224
{
1243
 
  return new (session->mem_root) Item_sum_avg(session, this);
 
1225
  return new (thd->mem_root) Item_sum_avg(thd, this);
1244
1226
}
1245
1227
 
1246
1228
 
1247
 
Field *Item_sum_avg::create_tmp_field(bool group, Table *table,
1248
 
                                      uint32_t )
 
1229
Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table,
 
1230
                                      uint convert_blob_len)
1249
1231
{
1250
1232
  Field *field;
1251
1233
  if (group)
1255
1237
      The easiest way is to do this is to store both value in a string
1256
1238
      and unpack on access.
1257
1239
    */
1258
 
    field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
1259
 
                                dec_bin_size : sizeof(double)) + sizeof(int64_t),
1260
 
                               0, name, table->getMutableShare(), &my_charset_bin);
 
1240
    field= new Field_string(((hybrid_type == DECIMAL_RESULT) ?
 
1241
                             dec_bin_size : sizeof(double)) + sizeof(longlong),
 
1242
                            0, name, &my_charset_bin);
1261
1243
  }
1262
1244
  else if (hybrid_type == DECIMAL_RESULT)
1263
 
    field= new Field_decimal(max_length, maybe_null, name,
1264
 
                             decimals, unsigned_flag);
 
1245
    field= new Field_new_decimal(max_length, maybe_null, name,
 
1246
                                 decimals, unsigned_flag);
1265
1247
  else
1266
 
    field= new Field_double(max_length, maybe_null, name, decimals, true);
 
1248
    field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
1267
1249
  if (field)
1268
1250
    field->init(table);
1269
1251
  return field;
1280
1262
bool Item_sum_avg::add()
1281
1263
{
1282
1264
  if (Item_sum_sum::add())
1283
 
    return true;
 
1265
    return TRUE;
1284
1266
  if (!args[0]->null_value)
1285
1267
    count++;
1286
 
  return false;
 
1268
  return FALSE;
1287
1269
}
1288
1270
 
1289
1271
double Item_sum_avg::val_real()
1290
1272
{
1291
 
  assert(fixed == 1);
 
1273
  DBUG_ASSERT(fixed == 1);
1292
1274
  if (!count)
1293
1275
  {
1294
1276
    null_value=1;
1295
1277
    return 0.0;
1296
1278
  }
1297
 
  return Item_sum_sum::val_real() / uint64_t2double(count);
1298
 
}
1299
 
 
1300
 
 
1301
 
int64_t Item_sum_avg::val_int()
1302
 
{
1303
 
  return (int64_t) rint(val_real());
 
1279
  return Item_sum_sum::val_real() / ulonglong2double(count);
1304
1280
}
1305
1281
 
1306
1282
 
1308
1284
{
1309
1285
  my_decimal sum_buff, cnt;
1310
1286
  const my_decimal *sum_dec;
1311
 
  assert(fixed == 1);
 
1287
  DBUG_ASSERT(fixed == 1);
1312
1288
  if (!count)
1313
1289
  {
1314
1290
    null_value=1;
1343
1319
 
1344
1320
double Item_sum_std::val_real()
1345
1321
{
1346
 
  assert(fixed == 1);
 
1322
  DBUG_ASSERT(fixed == 1);
1347
1323
  double nr= Item_sum_variance::val_real();
1348
 
  assert(nr >= 0.0);
 
1324
  DBUG_ASSERT(nr >= 0.0);
1349
1325
  return sqrt(nr);
1350
1326
}
1351
1327
 
1352
 
Item *Item_sum_std::copy_or_same(Session* session)
 
1328
Item *Item_sum_std::copy_or_same(THD* thd)
1353
1329
{
1354
 
  return new (session->mem_root) Item_sum_std(session, this);
 
1330
  return new (thd->mem_root) Item_sum_std(thd, this);
1355
1331
}
1356
1332
 
1357
1333
 
1372
1348
  variance.  The difference between the two classes is that the first is used
1373
1349
  for a mundane SELECT, while the latter is used in a GROUPing SELECT.
1374
1350
*/
1375
 
static void variance_fp_recurrence_next(double *m, double *s, uint64_t *count, double nr)
 
1351
static void variance_fp_recurrence_next(double *m, double *s, ulonglong *count, double nr)
1376
1352
{
1377
1353
  *count += 1;
1378
1354
 
1379
 
  if (*count == 1)
 
1355
  if (*count == 1) 
1380
1356
  {
1381
1357
    *m= nr;
1382
1358
    *s= 0;
1390
1366
}
1391
1367
 
1392
1368
 
1393
 
static double variance_fp_recurrence_result(double s, uint64_t count, bool is_sample_variance)
 
1369
static double variance_fp_recurrence_result(double s, ulonglong count, bool is_sample_variance)
1394
1370
{
1395
1371
  if (count == 1)
1396
1372
    return 0.0;
1403
1379
}
1404
1380
 
1405
1381
 
1406
 
Item_sum_variance::Item_sum_variance(Session *session, Item_sum_variance *item):
1407
 
  Item_sum_num(session, item), hybrid_type(item->hybrid_type),
 
1382
Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item):
 
1383
  Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
1408
1384
    count(item->count), sample(item->sample),
1409
1385
    prec_increment(item->prec_increment)
1410
1386
{
1415
1391
 
1416
1392
void Item_sum_variance::fix_length_and_dec()
1417
1393
{
 
1394
  DBUG_ENTER("Item_sum_variance::fix_length_and_dec");
1418
1395
  maybe_null= null_value= 1;
1419
 
  prec_increment= current_session->variables.div_precincrement;
 
1396
  prec_increment= current_thd->variables.div_precincrement;
1420
1397
 
1421
1398
  /*
1422
1399
    According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
1423
 
    aggregate function; paragraph 7h of Syntax Rules), "the declared
 
1400
    aggregate function; paragraph 7h of Syntax Rules), "the declared 
1424
1401
    type of the result is an implementation-defined aproximate numeric
1425
1402
    type.
1426
1403
  */
1429
1406
  switch (args[0]->result_type()) {
1430
1407
  case REAL_RESULT:
1431
1408
  case STRING_RESULT:
1432
 
    decimals= min(args[0]->decimals + 4, (int)NOT_FIXED_DEC);
 
1409
    decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
1433
1410
    break;
1434
1411
  case INT_RESULT:
1435
1412
  case DECIMAL_RESULT:
1436
1413
  {
1437
1414
    int precision= args[0]->decimal_precision()*2 + prec_increment;
1438
 
    decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
 
1415
    decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
1439
1416
    max_length= my_decimal_precision_to_length(precision, decimals,
1440
1417
                                               unsigned_flag);
1441
1418
 
1443
1420
  }
1444
1421
  case ROW_RESULT:
1445
1422
  default:
1446
 
    assert(0);
 
1423
    DBUG_ASSERT(0);
1447
1424
  }
1448
 
  return;
 
1425
  DBUG_PRINT("info", ("Type: REAL_RESULT (%d, %d)", max_length, (int)decimals));
 
1426
  DBUG_VOID_RETURN;
1449
1427
}
1450
1428
 
1451
1429
 
1452
 
Item *Item_sum_variance::copy_or_same(Session* session)
 
1430
Item *Item_sum_variance::copy_or_same(THD* thd)
1453
1431
{
1454
 
  return new (session->mem_root) Item_sum_variance(session, this);
 
1432
  return new (thd->mem_root) Item_sum_variance(thd, this);
1455
1433
}
1456
1434
 
1457
1435
 
1460
1438
  If we're grouping, then we need some space to serialize variables into, to
1461
1439
  pass around.
1462
1440
*/
1463
 
Field *Item_sum_variance::create_tmp_field(bool group, Table *table,
1464
 
                                           uint32_t )
 
1441
Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table,
 
1442
                                           uint convert_blob_len)
1465
1443
{
1466
1444
  Field *field;
1467
1445
  if (group)
1471
1449
      The easiest way is to do this is to store both value in a string
1472
1450
      and unpack on access.
1473
1451
    */
1474
 
    field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->getMutableShare(), &my_charset_bin);
 
1452
    field= new Field_string(sizeof(double)*2 + sizeof(longlong), 0, name, &my_charset_bin);
1475
1453
  }
1476
1454
  else
1477
 
    field= new Field_double(max_length, maybe_null, name, decimals, true);
 
1455
    field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
1478
1456
 
1479
1457
  if (field != NULL)
1480
1458
    field->init(table);
1485
1463
 
1486
1464
void Item_sum_variance::clear()
1487
1465
{
1488
 
  count= 0;
 
1466
  count= 0; 
1489
1467
}
1490
1468
 
1491
1469
bool Item_sum_variance::add()
1492
1470
{
1493
 
  /*
 
1471
  /* 
1494
1472
    Why use a temporary variable?  We don't know if it is null until we
1495
1473
    evaluate it, which has the side-effect of setting null_value .
1496
1474
  */
1497
1475
  double nr= args[0]->val_real();
1498
 
 
 
1476
  
1499
1477
  if (!args[0]->null_value)
1500
1478
    variance_fp_recurrence_next(&recurrence_m, &recurrence_s, &count, nr);
1501
1479
  return 0;
1503
1481
 
1504
1482
double Item_sum_variance::val_real()
1505
1483
{
1506
 
  assert(fixed == 1);
 
1484
  DBUG_ASSERT(fixed == 1);
1507
1485
 
1508
1486
  /*
1509
1487
    'sample' is a 1/0 boolean value.  If it is 1/true, id est this is a sample
1514
1492
    Another way to read it is that 'sample' is the numerical threshhold, at and
1515
1493
    below which a 'count' number of items is called NULL.
1516
1494
  */
1517
 
  assert((sample == 0) || (sample == 1));
 
1495
  DBUG_ASSERT((sample == 0) || (sample == 1));
1518
1496
  if (count <= sample)
1519
1497
  {
1520
1498
    null_value=1;
1526
1504
}
1527
1505
 
1528
1506
 
1529
 
int64_t Item_sum_variance::val_int()
1530
 
{
1531
 
  /* can't be fix_fields()ed */
1532
 
  return (int64_t) rint(val_real());
1533
 
}
1534
 
 
1535
 
 
1536
1507
my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf)
1537
1508
{
1538
 
  assert(fixed == 1);
 
1509
  DBUG_ASSERT(fixed == 1);
1539
1510
  return val_decimal_from_real(dec_buf);
1540
1511
}
1541
1512
 
1543
1514
void Item_sum_variance::reset_field()
1544
1515
{
1545
1516
  double nr;
1546
 
  unsigned char *res= result_field->ptr;
 
1517
  uchar *res= result_field->ptr;
1547
1518
 
1548
1519
  nr= args[0]->val_real();              /* sets null_value as side-effect */
1549
1520
 
1550
1521
  if (args[0]->null_value)
1551
 
    memset(res, 0, sizeof(double)*2+sizeof(int64_t));
 
1522
    bzero(res,sizeof(double)*2+sizeof(longlong));
1552
1523
  else
1553
1524
  {
1554
 
    /* Serialize format is (double)m, (double)s, (int64_t)count */
1555
 
    uint64_t tmp_count;
 
1525
    /* Serialize format is (double)m, (double)s, (longlong)count */
 
1526
    ulonglong tmp_count;
1556
1527
    double tmp_s;
1557
1528
    float8store(res, nr);               /* recurrence variable m */
1558
1529
    tmp_s= 0.0;
1565
1536
 
1566
1537
void Item_sum_variance::update_field()
1567
1538
{
1568
 
  uint64_t field_count;
1569
 
  unsigned char *res=result_field->ptr;
 
1539
  ulonglong field_count;
 
1540
  uchar *res=result_field->ptr;
1570
1541
 
1571
1542
  double nr= args[0]->val_real();       /* sets null_value as side-effect */
1572
1543
 
1573
1544
  if (args[0]->null_value)
1574
1545
    return;
1575
1546
 
1576
 
  /* Serialize format is (double)m, (double)s, (int64_t)count */
 
1547
  /* Serialize format is (double)m, (double)s, (longlong)count */
1577
1548
  double field_recurrence_m, field_recurrence_s;
1578
1549
  float8get(field_recurrence_m, res);
1579
1550
  float8get(field_recurrence_s, res + sizeof(double));
1610
1581
 
1611
1582
double Item_sum_hybrid::val_real()
1612
1583
{
1613
 
  assert(fixed == 1);
 
1584
  DBUG_ASSERT(fixed == 1);
1614
1585
  if (null_value)
1615
1586
    return 0.0;
1616
1587
  switch (hybrid_type) {
1623
1594
                             &end_not_used, &err_not_used) : 0.0);
1624
1595
  }
1625
1596
  case INT_RESULT:
 
1597
    if (unsigned_flag)
 
1598
      return ulonglong2double(sum_int);
1626
1599
    return (double) sum_int;
1627
1600
  case DECIMAL_RESULT:
1628
1601
    my_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
1632
1605
  case ROW_RESULT:
1633
1606
  default:
1634
1607
    // This case should never be choosen
1635
 
    assert(0);
 
1608
    DBUG_ASSERT(0);
1636
1609
    return 0;
1637
1610
  }
1638
1611
}
1639
1612
 
1640
 
int64_t Item_sum_hybrid::val_int()
 
1613
longlong Item_sum_hybrid::val_int()
1641
1614
{
1642
 
  assert(fixed == 1);
 
1615
  DBUG_ASSERT(fixed == 1);
1643
1616
  if (null_value)
1644
1617
    return 0;
1645
1618
  switch (hybrid_type) {
1647
1620
    return sum_int;
1648
1621
  case DECIMAL_RESULT:
1649
1622
  {
1650
 
    int64_t result;
 
1623
    longlong result;
1651
1624
    my_decimal2int(E_DEC_FATAL_ERROR, &sum_dec, unsigned_flag, &result);
1652
1625
    return sum_int;
1653
1626
  }
1654
1627
  default:
1655
 
    return (int64_t) rint(Item_sum_hybrid::val_real());
 
1628
    return (longlong) rint(Item_sum_hybrid::val_real());
1656
1629
  }
1657
1630
}
1658
1631
 
1659
1632
 
1660
1633
my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
1661
1634
{
1662
 
  assert(fixed == 1);
 
1635
  DBUG_ASSERT(fixed == 1);
1663
1636
  if (null_value)
1664
1637
    return 0;
1665
1638
  switch (hybrid_type) {
1678
1651
  case ROW_RESULT:
1679
1652
  default:
1680
1653
    // This case should never be choosen
1681
 
    assert(0);
 
1654
    DBUG_ASSERT(0);
1682
1655
    break;
1683
1656
  }
1684
1657
  return val;                                   // Keep compiler happy
1688
1661
String *
1689
1662
Item_sum_hybrid::val_str(String *str)
1690
1663
{
1691
 
  assert(fixed == 1);
 
1664
  DBUG_ASSERT(fixed == 1);
1692
1665
  if (null_value)
1693
1666
    return 0;
1694
1667
  switch (hybrid_type) {
1706
1679
  case ROW_RESULT:
1707
1680
  default:
1708
1681
    // This case should never be choosen
1709
 
    assert(0);
 
1682
    DBUG_ASSERT(0);
1710
1683
    break;
1711
1684
  }
1712
1685
  return str;                                   // Keep compiler happy
1715
1688
 
1716
1689
void Item_sum_hybrid::cleanup()
1717
1690
{
 
1691
  DBUG_ENTER("Item_sum_hybrid::cleanup");
1718
1692
  Item_sum::cleanup();
1719
 
  forced_const= false;
 
1693
  forced_const= FALSE;
1720
1694
 
1721
1695
  /*
1722
1696
    by default it is TRUE to avoid TRUE reporting by
1725
1699
    no_rows_in_result() set it to FALSE if was not results found.
1726
1700
    If some results found it will be left unchanged.
1727
1701
  */
1728
 
  was_values= true;
1729
 
  return;
 
1702
  was_values= TRUE;
 
1703
  DBUG_VOID_RETURN;
1730
1704
}
1731
1705
 
1732
1706
void Item_sum_hybrid::no_rows_in_result()
1733
1707
{
1734
 
  was_values= false;
 
1708
  was_values= FALSE;
1735
1709
  clear();
1736
1710
}
1737
1711
 
1738
1712
 
1739
 
Item *Item_sum_min::copy_or_same(Session* session)
 
1713
Item *Item_sum_min::copy_or_same(THD* thd)
1740
1714
{
1741
 
  return new (session->mem_root) Item_sum_min(session, this);
 
1715
  return new (thd->mem_root) Item_sum_min(thd, this);
1742
1716
}
1743
1717
 
1744
1718
 
1758
1732
  break;
1759
1733
  case INT_RESULT:
1760
1734
  {
1761
 
    int64_t nr=args[0]->val_int();
 
1735
    longlong nr=args[0]->val_int();
1762
1736
    if (!args[0]->null_value && (null_value ||
1763
 
                                 (unsigned_flag &&
1764
 
                                  (uint64_t) nr < (uint64_t) sum_int) ||
 
1737
                                 (unsigned_flag && 
 
1738
                                  (ulonglong) nr < (ulonglong) sum_int) ||
1765
1739
                                 (!unsigned_flag && nr < sum_int)))
1766
1740
    {
1767
1741
      sum_int=nr;
1793
1767
  case ROW_RESULT:
1794
1768
  default:
1795
1769
    // This case should never be choosen
1796
 
    assert(0);
 
1770
    DBUG_ASSERT(0);
1797
1771
    break;
1798
1772
  }
1799
1773
  return 0;
1800
1774
}
1801
1775
 
1802
1776
 
1803
 
Item *Item_sum_max::copy_or_same(Session* session)
 
1777
Item *Item_sum_max::copy_or_same(THD* thd)
1804
1778
{
1805
 
  return new (session->mem_root) Item_sum_max(session, this);
 
1779
  return new (thd->mem_root) Item_sum_max(thd, this);
1806
1780
}
1807
1781
 
1808
1782
 
1822
1796
  break;
1823
1797
  case INT_RESULT:
1824
1798
  {
1825
 
    int64_t nr=args[0]->val_int();
 
1799
    longlong nr=args[0]->val_int();
1826
1800
    if (!args[0]->null_value && (null_value ||
1827
 
                                 (unsigned_flag &&
1828
 
                                  (uint64_t) nr > (uint64_t) sum_int) ||
 
1801
                                 (unsigned_flag && 
 
1802
                                  (ulonglong) nr > (ulonglong) sum_int) ||
1829
1803
                                 (!unsigned_flag && nr > sum_int)))
1830
1804
    {
1831
1805
      sum_int=nr;
1857
1831
  case ROW_RESULT:
1858
1832
  default:
1859
1833
    // This case should never be choosen
1860
 
    assert(0);
 
1834
    DBUG_ASSERT(0);
1861
1835
    break;
1862
1836
  }
1863
1837
  return 0;
1866
1840
 
1867
1841
/* bit_or and bit_and */
1868
1842
 
1869
 
int64_t Item_sum_bit::val_int()
 
1843
longlong Item_sum_bit::val_int()
1870
1844
{
1871
 
  assert(fixed == 1);
1872
 
  return (int64_t) bits;
 
1845
  DBUG_ASSERT(fixed == 1);
 
1846
  return (longlong) bits;
1873
1847
}
1874
1848
 
1875
1849
 
1878
1852
  bits= reset_bits;
1879
1853
}
1880
1854
 
1881
 
Item *Item_sum_or::copy_or_same(Session* session)
 
1855
Item *Item_sum_or::copy_or_same(THD* thd)
1882
1856
{
1883
 
  return new (session->mem_root) Item_sum_or(session, this);
 
1857
  return new (thd->mem_root) Item_sum_or(thd, this);
1884
1858
}
1885
1859
 
1886
1860
 
1887
1861
bool Item_sum_or::add()
1888
1862
{
1889
 
  uint64_t value= (uint64_t) args[0]->val_int();
 
1863
  ulonglong value= (ulonglong) args[0]->val_int();
1890
1864
  if (!args[0]->null_value)
1891
1865
    bits|=value;
1892
1866
  return 0;
1893
1867
}
1894
1868
 
1895
 
Item *Item_sum_xor::copy_or_same(Session* session)
 
1869
Item *Item_sum_xor::copy_or_same(THD* thd)
1896
1870
{
1897
 
  return new (session->mem_root) Item_sum_xor(session, this);
 
1871
  return new (thd->mem_root) Item_sum_xor(thd, this);
1898
1872
}
1899
1873
 
1900
1874
 
1901
1875
bool Item_sum_xor::add()
1902
1876
{
1903
 
  uint64_t value= (uint64_t) args[0]->val_int();
 
1877
  ulonglong value= (ulonglong) args[0]->val_int();
1904
1878
  if (!args[0]->null_value)
1905
1879
    bits^=value;
1906
1880
  return 0;
1907
1881
}
1908
1882
 
1909
 
Item *Item_sum_and::copy_or_same(Session* session)
 
1883
Item *Item_sum_and::copy_or_same(THD* thd)
1910
1884
{
1911
 
  return new (session->mem_root) Item_sum_and(session, this);
 
1885
  return new (thd->mem_root) Item_sum_and(thd, this);
1912
1886
}
1913
1887
 
1914
1888
 
1915
1889
bool Item_sum_and::add()
1916
1890
{
1917
 
  uint64_t value= (uint64_t) args[0]->val_int();
 
1891
  ulonglong value= (ulonglong) args[0]->val_int();
1918
1892
  if (!args[0]->null_value)
1919
1893
    bits&=value;
1920
1894
  return 0;
1927
1901
void Item_sum_num::reset_field()
1928
1902
{
1929
1903
  double nr= args[0]->val_real();
1930
 
  unsigned char *res=result_field->ptr;
 
1904
  uchar *res=result_field->ptr;
1931
1905
 
1932
1906
  if (maybe_null)
1933
1907
  {
1966
1940
  }
1967
1941
  case INT_RESULT:
1968
1942
  {
1969
 
    int64_t nr=args[0]->val_int();
 
1943
    longlong nr=args[0]->val_int();
1970
1944
 
1971
1945
    if (maybe_null)
1972
1946
    {
2020
1994
  }
2021
1995
  case ROW_RESULT:
2022
1996
  default:
2023
 
    assert(0);
 
1997
    DBUG_ASSERT(0);
2024
1998
  }
2025
1999
}
2026
2000
 
2036
2010
  }
2037
2011
  else
2038
2012
  {
2039
 
    assert(hybrid_type == REAL_RESULT);
 
2013
    DBUG_ASSERT(hybrid_type == REAL_RESULT);
2040
2014
    double nr= args[0]->val_real();                     // Nulls also return 0
2041
2015
    float8store(result_field->ptr, nr);
2042
2016
  }
2049
2023
 
2050
2024
void Item_sum_count::reset_field()
2051
2025
{
2052
 
  unsigned char *res=result_field->ptr;
2053
 
  int64_t nr=0;
 
2026
  uchar *res=result_field->ptr;
 
2027
  longlong nr=0;
2054
2028
 
2055
2029
  if (!args[0]->maybe_null || !args[0]->is_null())
2056
2030
    nr=1;
2060
2034
 
2061
2035
void Item_sum_avg::reset_field()
2062
2036
{
2063
 
  unsigned char *res=result_field->ptr;
 
2037
  uchar *res=result_field->ptr;
2064
2038
  if (hybrid_type == DECIMAL_RESULT)
2065
2039
  {
2066
 
    int64_t tmp;
 
2040
    longlong tmp;
2067
2041
    my_decimal value, *arg_dec= args[0]->val_decimal(&value);
2068
2042
    if (args[0]->null_value)
2069
2043
    {
2081
2055
    double nr= args[0]->val_real();
2082
2056
 
2083
2057
    if (args[0]->null_value)
2084
 
      memset(res, 0, sizeof(double)+sizeof(int64_t));
 
2058
      bzero(res,sizeof(double)+sizeof(longlong));
2085
2059
    else
2086
2060
    {
2087
 
      int64_t tmp= 1;
 
2061
      longlong tmp= 1;
2088
2062
      float8store(res,nr);
2089
2063
      res+=sizeof(double);
2090
2064
      int8store(res,tmp);
2101
2075
 
2102
2076
void Item_sum_bit::update_field()
2103
2077
{
2104
 
  unsigned char *res=result_field->ptr;
 
2078
  uchar *res=result_field->ptr;
2105
2079
  bits= uint8korr(res);
2106
2080
  add();
2107
2081
  int8store(res, bits);
2136
2110
  else
2137
2111
  {
2138
2112
    double old_nr,nr;
2139
 
    unsigned char *res=result_field->ptr;
 
2113
    uchar *res=result_field->ptr;
2140
2114
 
2141
2115
    float8get(old_nr,res);
2142
2116
    nr= args[0]->val_real();
2152
2126
 
2153
2127
void Item_sum_count::update_field()
2154
2128
{
2155
 
  int64_t nr;
2156
 
  unsigned char *res=result_field->ptr;
 
2129
  longlong nr;
 
2130
  uchar *res=result_field->ptr;
2157
2131
 
2158
2132
  nr=sint8korr(res);
2159
2133
  if (!args[0]->maybe_null || !args[0]->is_null())
2164
2138
 
2165
2139
void Item_sum_avg::update_field()
2166
2140
{
2167
 
  int64_t field_count;
2168
 
  unsigned char *res=result_field->ptr;
 
2141
  longlong field_count;
 
2142
  uchar *res=result_field->ptr;
2169
2143
  if (hybrid_type == DECIMAL_RESULT)
2170
2144
  {
2171
2145
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
2260
2234
void
2261
2235
Item_sum_hybrid::min_max_update_int_field()
2262
2236
{
2263
 
  int64_t nr,old_nr;
 
2237
  longlong nr,old_nr;
2264
2238
 
2265
2239
  old_nr=result_field->val_int();
2266
2240
  nr=args[0]->val_int();
2271
2245
    else
2272
2246
    {
2273
2247
      bool res=(unsigned_flag ?
2274
 
                (uint64_t) old_nr > (uint64_t) nr :
 
2248
                (ulonglong) old_nr > (ulonglong) nr :
2275
2249
                old_nr > nr);
2276
2250
      /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
2277
2251
      if ((cmp_sign > 0) ^ (!res))
2337
2311
{
2338
2312
  // fix_fields() never calls for this Item
2339
2313
  double nr;
2340
 
  int64_t count;
2341
 
  unsigned char *res;
 
2314
  longlong count;
 
2315
  uchar *res;
2342
2316
 
2343
2317
  if (hybrid_type == DECIMAL_RESULT)
2344
2318
    return val_real_from_decimal();
2353
2327
}
2354
2328
 
2355
2329
 
2356
 
int64_t Item_avg_field::val_int()
 
2330
longlong Item_avg_field::val_int()
2357
2331
{
2358
 
  return (int64_t) rint(val_real());
 
2332
  return (longlong) rint(val_real());
2359
2333
}
2360
2334
 
2361
2335
 
2365
2339
  if (hybrid_type == REAL_RESULT)
2366
2340
    return val_decimal_from_real(dec_buf);
2367
2341
 
2368
 
  int64_t count= sint8korr(field->ptr + dec_bin_size);
 
2342
  longlong count= sint8korr(field->ptr + dec_bin_size);
2369
2343
  if ((null_value= !count))
2370
2344
    return 0;
2371
2345
 
2399
2373
  double nr;
2400
2374
  // fix_fields() never calls for this Item
2401
2375
  nr= Item_variance_field::val_real();
2402
 
  assert(nr >= 0.0);
 
2376
  DBUG_ASSERT(nr >= 0.0);
2403
2377
  return sqrt(nr);
2404
2378
}
2405
2379
 
2419
2393
  if (!dec)
2420
2394
    return 0;
2421
2395
  my_decimal2double(E_DEC_FATAL_ERROR, dec, &nr);
2422
 
  assert(nr >= 0.0);
 
2396
  DBUG_ASSERT(nr >= 0.0);
2423
2397
  nr= sqrt(nr);
2424
2398
  double2my_decimal(E_DEC_FATAL_ERROR, nr, &tmp_dec);
2425
 
  my_decimal_round(E_DEC_FATAL_ERROR, &tmp_dec, decimals, false, dec_buf);
 
2399
  my_decimal_round(E_DEC_FATAL_ERROR, &tmp_dec, decimals, FALSE, dec_buf);
2426
2400
  return dec_buf;
2427
2401
}
2428
2402
 
2449
2423
}
2450
2424
 
2451
2425
 
2452
 
int64_t Item_variance_field::val_int()
2453
 
{
2454
 
  /* can't be fix_fields()ed */
2455
 
  return (int64_t) rint(val_real());
2456
 
}
2457
 
 
2458
 
 
2459
2426
double Item_variance_field::val_real()
2460
2427
{
2461
2428
  // fix_fields() never calls for this Item
2463
2430
    return val_real_from_decimal();
2464
2431
 
2465
2432
  double recurrence_s;
2466
 
  uint64_t count;
 
2433
  ulonglong count;
2467
2434
  float8get(recurrence_s, (field->ptr + sizeof(double)));
2468
2435
  count=sint8korr(field->ptr+sizeof(double)*2);
2469
2436
 
2478
2445
** COUNT(DISTINCT ...)
2479
2446
****************************************************************************/
2480
2447
 
2481
 
int simple_str_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
 
2448
int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2)
2482
2449
{
2483
2450
  Field *f= (Field*) arg;
2484
2451
  return f->cmp(key1, key2);
2491
2458
  static
2492
2459
*/
2493
2460
 
2494
 
int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
 
2461
int composite_key_cmp(void* arg, uchar* key1, uchar* key2)
2495
2462
{
2496
2463
  Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
2497
 
  Field **field    = item->table->getFields();
2498
 
  Field **field_end= field + item->table->getShare()->sizeFields();
2499
 
  uint32_t *lengths=item->field_lengths;
 
2464
  Field **field    = item->table->field;
 
2465
  Field **field_end= field + item->table->s->fields;
 
2466
  uint32 *lengths=item->field_lengths;
2500
2467
  for (; field < field_end; ++field)
2501
2468
  {
2502
2469
    Field* f = *field;
2510
2477
  return 0;
2511
2478
}
2512
2479
 
2513
 
static int count_distinct_walk(void *,
2514
 
                               uint32_t ,
2515
 
                               void *arg)
 
2480
 
 
2481
C_MODE_START
 
2482
 
 
2483
static int count_distinct_walk(void *elem, element_count count, void *arg)
2516
2484
{
2517
 
  (*((uint64_t*)arg))++;
 
2485
  (*((ulonglong*)arg))++;
2518
2486
  return 0;
2519
2487
}
2520
2488
 
 
2489
C_MODE_END
 
2490
 
 
2491
 
2521
2492
void Item_sum_count_distinct::cleanup()
2522
2493
{
 
2494
  DBUG_ENTER("Item_sum_count_distinct::cleanup");
2523
2495
  Item_sum_int::cleanup();
2524
2496
 
2525
2497
  /* Free objects only if we own them. */
2532
2504
    */
2533
2505
    delete tree;
2534
2506
    tree= 0;
2535
 
    is_evaluated= false;
 
2507
    is_evaluated= FALSE;
2536
2508
    if (table)
2537
2509
    {
 
2510
      free_tmp_table(table->in_use, table);
2538
2511
      table= 0;
2539
2512
    }
2540
2513
    delete tmp_table_param;
2541
2514
    tmp_table_param= 0;
2542
2515
  }
2543
 
  always_null= false;
2544
 
  return;
 
2516
  always_null= FALSE;
 
2517
  DBUG_VOID_RETURN;
2545
2518
}
2546
2519
 
2547
2520
 
2556
2529
  original= 0;
2557
2530
  force_copy_fields= 1;
2558
2531
  tree= 0;
2559
 
  is_evaluated= false;
 
2532
  is_evaluated= FALSE;
2560
2533
  tmp_table_param= 0;
2561
 
  always_null= false;
 
2534
  always_null= FALSE;
2562
2535
}
2563
2536
 
2564
2537
 
2568
2541
}
2569
2542
 
2570
2543
 
2571
 
bool Item_sum_count_distinct::setup(Session *session)
 
2544
bool Item_sum_count_distinct::setup(THD *thd)
2572
2545
{
2573
2546
  List<Item> list;
2574
 
  Select_Lex *select_lex= session->lex->current_select;
 
2547
  SELECT_LEX *select_lex= thd->lex->current_select;
2575
2548
 
2576
2549
  /*
2577
2550
    Setup can be called twice for ROLLUP items. This is a bug.
2578
 
    Please add assert(tree == 0) here when it's fixed.
 
2551
    Please add DBUG_ASSERT(tree == 0) here when it's fixed.
2579
2552
    It's legal to call setup() more than once when in a subquery
2580
2553
  */
2581
2554
  if (tree || table || tmp_table_param)
2582
 
    return false;
 
2555
    return FALSE;
2583
2556
 
2584
 
  if (!(tmp_table_param= new Tmp_Table_Param))
2585
 
    return true;
 
2557
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
 
2558
    return TRUE;
2586
2559
 
2587
2560
  /* Create a table with an unique key over all parameters */
2588
 
  for (uint32_t i=0; i < arg_count ; i++)
 
2561
  for (uint i=0; i < arg_count ; i++)
2589
2562
  {
2590
2563
    Item *item=args[i];
2591
2564
    if (list.push_back(item))
2592
 
      return true;                              // End of memory
 
2565
      return TRUE;                              // End of memory
2593
2566
    if (item->const_item() && item->is_null())
2594
2567
      always_null= 1;
2595
2568
  }
2596
2569
  if (always_null)
2597
 
    return false;
 
2570
    return FALSE;
2598
2571
  count_field_types(select_lex, tmp_table_param, list, 0);
2599
2572
  tmp_table_param->force_copy_fields= force_copy_fields;
2600
 
  assert(table == 0);
 
2573
  DBUG_ASSERT(table == 0);
 
2574
  /*
 
2575
    Make create_tmp_table() convert BIT columns to BIGINT.
 
2576
    This is needed because BIT fields store parts of their data in table's
 
2577
    null bits, and we don't have methods to compare two table records, which
 
2578
    is needed by Unique which is used when HEAP table is used.
 
2579
  */
 
2580
  {
 
2581
    List_iterator_fast<Item> li(list);
 
2582
    Item *item;
 
2583
    while ((item= li++))
 
2584
    {
 
2585
      if (item->type() == Item::FIELD_ITEM &&
 
2586
          ((Item_field*)item)->field->type() == FIELD_TYPE_BIT)
 
2587
        item->marker=4;
 
2588
    }
 
2589
  }
2601
2590
 
2602
 
  if (!(table= create_tmp_table(session, tmp_table_param, list, (order_st*) 0, 1,
 
2591
  if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
2603
2592
                                0,
2604
 
                                (select_lex->options | session->options),
 
2593
                                (select_lex->options | thd->options),
2605
2594
                                HA_POS_ERROR, (char*)"")))
2606
 
  {
2607
 
    return true;
2608
 
  }
2609
 
  table->cursor->extra(HA_EXTRA_NO_ROWS);               // Don't update rows
 
2595
    return TRUE;
 
2596
  table->file->extra(HA_EXTRA_NO_ROWS);         // Don't update rows
2610
2597
  table->no_rows=1;
2611
2598
 
2612
 
  if (table->getShare()->db_type() == heap_engine)
 
2599
  if (table->s->db_type() == heap_hton)
2613
2600
  {
2614
2601
    /*
2615
2602
      No blobs, otherwise it would have been MyISAM: set up a compare
2617
2604
    */
2618
2605
    qsort_cmp2 compare_key;
2619
2606
    void* cmp_arg;
2620
 
    Field **field= table->getFields();
2621
 
    Field **field_end= field + table->getShare()->sizeFields();
2622
 
    bool all_binary= true;
 
2607
    Field **field= table->field;
 
2608
    Field **field_end= field + table->s->fields;
 
2609
    bool all_binary= TRUE;
2623
2610
 
2624
2611
    for (tree_key_length= 0; field < field_end; ++field)
2625
2612
    {
2626
2613
      Field *f= *field;
2627
2614
      enum enum_field_types f_type= f->type();
2628
2615
      tree_key_length+= f->pack_length();
2629
 
      if (f_type == DRIZZLE_TYPE_VARCHAR)
 
2616
      if ((f_type == MYSQL_TYPE_VARCHAR) || (!f->binary() && (f_type == MYSQL_TYPE_STRING || f_type == MYSQL_TYPE_VAR_STRING)))
2630
2617
      {
2631
 
        all_binary= false;
 
2618
        all_binary= FALSE;
2632
2619
        break;
2633
2620
      }
2634
2621
    }
2639
2626
    }
2640
2627
    else
2641
2628
    {
2642
 
      if (table->getShare()->sizeFields() == 1)
 
2629
      if (table->s->fields == 1)
2643
2630
      {
2644
2631
        /*
2645
2632
          If we have only one field, which is the most common use of
2648
2635
          about other fields.
2649
2636
        */
2650
2637
        compare_key= (qsort_cmp2) simple_str_key_cmp;
2651
 
        cmp_arg= (void*) table->getField(0);
 
2638
        cmp_arg= (void*) table->field[0];
2652
2639
        /* tree_key_length has been set already */
2653
2640
      }
2654
2641
      else
2655
2642
      {
2656
 
        uint32_t *length;
 
2643
        uint32 *length;
2657
2644
        compare_key= (qsort_cmp2) composite_key_cmp;
2658
2645
        cmp_arg= (void*) this;
2659
 
        field_lengths= (uint32_t*) session->alloc(table->getShare()->sizeFields() * sizeof(uint32_t));
2660
 
        for (tree_key_length= 0, length= field_lengths, field= table->getFields();
 
2646
        field_lengths= (uint32*) thd->alloc(table->s->fields * sizeof(uint32));
 
2647
        for (tree_key_length= 0, length= field_lengths, field= table->field;
2661
2648
             field < field_end; ++field, ++length)
2662
2649
        {
2663
2650
          *length= (*field)->pack_length();
2665
2652
        }
2666
2653
      }
2667
2654
    }
2668
 
    assert(tree == 0);
 
2655
    DBUG_ASSERT(tree == 0);
2669
2656
    tree= new Unique(compare_key, cmp_arg, tree_key_length,
2670
 
                     (size_t)session->variables.max_heap_table_size);
 
2657
                     thd->variables.max_heap_table_size);
2671
2658
    /*
2672
2659
      The only time tree_key_length could be 0 is if someone does
2673
2660
      count(distinct) on a char(0) field - stupid thing to do,
2674
2661
      but this has to be handled - otherwise someone can crash
2675
2662
      the server with a DoS attack
2676
2663
    */
2677
 
    is_evaluated= false;
 
2664
    is_evaluated= FALSE;
2678
2665
    if (! tree)
2679
 
      return true;
 
2666
      return TRUE;
2680
2667
  }
2681
 
  return false;
 
2668
  return FALSE;
2682
2669
}
2683
2670
 
2684
2671
 
2685
 
Item *Item_sum_count_distinct::copy_or_same(Session* session)
 
2672
Item *Item_sum_count_distinct::copy_or_same(THD* thd) 
2686
2673
{
2687
 
  return new (session->mem_root) Item_sum_count_distinct(session, this);
 
2674
  return new (thd->mem_root) Item_sum_count_distinct(thd, this);
2688
2675
}
2689
2676
 
2690
2677
 
2691
2678
void Item_sum_count_distinct::clear()
2692
2679
{
2693
2680
  /* tree and table can be both null only if always_null */
2694
 
  is_evaluated= false;
 
2681
  is_evaluated= FALSE;
2695
2682
  if (tree)
2696
2683
  {
2697
2684
    tree->reset();
2698
2685
  }
2699
2686
  else if (table)
2700
2687
  {
2701
 
    table->cursor->extra(HA_EXTRA_NO_CACHE);
2702
 
    table->cursor->ha_delete_all_rows();
2703
 
    table->cursor->extra(HA_EXTRA_WRITE_CACHE);
 
2688
    table->file->extra(HA_EXTRA_NO_CACHE);
 
2689
    table->file->ha_delete_all_rows();
 
2690
    table->file->extra(HA_EXTRA_WRITE_CACHE);
2704
2691
  }
2705
2692
}
2706
2693
 
2712
2699
  copy_fields(tmp_table_param);
2713
2700
  copy_funcs(tmp_table_param->items_to_copy);
2714
2701
 
2715
 
  for (Field **field= table->getFields() ; *field ; field++)
2716
 
  {
 
2702
  for (Field **field=table->field ; *field ; field++)
2717
2703
    if ((*field)->is_real_null(0))
2718
 
    {
2719
2704
      return 0;                                 // Don't count NULL
2720
 
    }
2721
 
  }
2722
2705
 
2723
 
  is_evaluated= false;
 
2706
  is_evaluated= FALSE;
2724
2707
  if (tree)
2725
2708
  {
2726
2709
    /*
2729
2712
      bloat the tree without providing any valuable info. Besides,
2730
2713
      key_length used to initialize the tree didn't include space for them.
2731
2714
    */
2732
 
    return tree->unique_add(table->record[0] + table->getShare()->null_bytes);
 
2715
    return tree->unique_add(table->record[0] + table->s->null_bytes);
2733
2716
  }
2734
 
  if ((error= table->cursor->insertRecord(table->record[0])) &&
2735
 
      table->cursor->is_fatal_error(error, HA_CHECK_DUP))
2736
 
    return true;
2737
 
  return false;
 
2717
  if ((error= table->file->ha_write_row(table->record[0])) &&
 
2718
      table->file->is_fatal_error(error, HA_CHECK_DUP))
 
2719
    return TRUE;
 
2720
  return FALSE;
2738
2721
}
2739
2722
 
2740
2723
 
2741
 
int64_t Item_sum_count_distinct::val_int()
 
2724
longlong Item_sum_count_distinct::val_int()
2742
2725
{
2743
2726
  int error;
2744
 
  assert(fixed == 1);
 
2727
  DBUG_ASSERT(fixed == 1);
2745
2728
  if (!table)                                   // Empty query
2746
 
    return 0L;
 
2729
    return LL(0);
2747
2730
  if (tree)
2748
2731
  {
2749
2732
    if (is_evaluated)
2750
2733
      return count;
2751
2734
 
2752
2735
    if (tree->elements == 0)
2753
 
      return (int64_t) tree->elements_in_tree(); // everything fits in memory
 
2736
      return (longlong) tree->elements_in_tree(); // everything fits in memory
2754
2737
    count= 0;
2755
2738
    tree->walk(count_distinct_walk, (void*) &count);
2756
 
    is_evaluated= true;
2757
 
    return (int64_t) count;
 
2739
    is_evaluated= TRUE;
 
2740
    return (longlong) count;
2758
2741
  }
2759
2742
 
2760
 
  error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
2743
  error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2761
2744
 
2762
2745
  if(error)
2763
2746
  {
2764
 
    table->print_error(error, MYF(0));
2765
 
  }
2766
 
 
2767
 
  return table->cursor->stats.records;
2768
 
}
 
2747
    table->file->print_error(error, MYF(0));
 
2748
  }
 
2749
 
 
2750
  return table->file->stats.records;
 
2751
}
 
2752
 
 
2753
 
 
2754
/****************************************************************************
 
2755
** Functions to handle dynamic loadable aggregates
 
2756
** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
 
2757
** Adapted for UDAs by: Andreas F. Bobak <bobak@relog.ch>.
 
2758
** Rewritten by: Monty.
 
2759
****************************************************************************/
 
2760
 
 
2761
#ifdef HAVE_DLOPEN
 
2762
 
 
2763
void Item_udf_sum::clear()
 
2764
{
 
2765
  DBUG_ENTER("Item_udf_sum::clear");
 
2766
  udf.clear();
 
2767
  DBUG_VOID_RETURN;
 
2768
}
 
2769
 
 
2770
bool Item_udf_sum::add()
 
2771
{
 
2772
  DBUG_ENTER("Item_udf_sum::add");
 
2773
  udf.add(&null_value);
 
2774
  DBUG_RETURN(0);
 
2775
}
 
2776
 
 
2777
void Item_udf_sum::cleanup()
 
2778
{
 
2779
  /*
 
2780
    udf_handler::cleanup() nicely handles case when we have not
 
2781
    original item but one created by copy_or_same() method.
 
2782
  */
 
2783
  udf.cleanup();
 
2784
  Item_sum::cleanup();
 
2785
}
 
2786
 
 
2787
 
 
2788
void Item_udf_sum::print(String *str, enum_query_type query_type)
 
2789
{
 
2790
  str->append(func_name());
 
2791
  str->append('(');
 
2792
  for (uint i=0 ; i < arg_count ; i++)
 
2793
  {
 
2794
    if (i)
 
2795
      str->append(',');
 
2796
    args[i]->print(str, query_type);
 
2797
  }
 
2798
  str->append(')');
 
2799
}
 
2800
 
 
2801
 
 
2802
Item *Item_sum_udf_float::copy_or_same(THD* thd)
 
2803
{
 
2804
  return new (thd->mem_root) Item_sum_udf_float(thd, this);
 
2805
}
 
2806
 
 
2807
double Item_sum_udf_float::val_real()
 
2808
{
 
2809
  DBUG_ASSERT(fixed == 1);
 
2810
  DBUG_ENTER("Item_sum_udf_float::val");
 
2811
  DBUG_PRINT("info",("result_type: %d  arg_count: %d",
 
2812
                     args[0]->result_type(), arg_count));
 
2813
  DBUG_RETURN(udf.val(&null_value));
 
2814
}
 
2815
 
 
2816
 
 
2817
String *Item_sum_udf_float::val_str(String *str)
 
2818
{
 
2819
  return val_string_from_real(str);
 
2820
}
 
2821
 
 
2822
 
 
2823
my_decimal *Item_sum_udf_float::val_decimal(my_decimal *dec)
 
2824
{
 
2825
  return val_decimal_from_real(dec);
 
2826
}
 
2827
 
 
2828
 
 
2829
String *Item_sum_udf_decimal::val_str(String *str)
 
2830
{
 
2831
  return val_string_from_decimal(str);
 
2832
}
 
2833
 
 
2834
 
 
2835
double Item_sum_udf_decimal::val_real()
 
2836
{
 
2837
  return val_real_from_decimal();
 
2838
}
 
2839
 
 
2840
 
 
2841
longlong Item_sum_udf_decimal::val_int()
 
2842
{
 
2843
  return val_int_from_decimal();
 
2844
}
 
2845
 
 
2846
 
 
2847
my_decimal *Item_sum_udf_decimal::val_decimal(my_decimal *dec_buf)
 
2848
{
 
2849
  DBUG_ASSERT(fixed == 1);
 
2850
  DBUG_ENTER("Item_func_udf_decimal::val_decimal");
 
2851
  DBUG_PRINT("info",("result_type: %d  arg_count: %d",
 
2852
                     args[0]->result_type(), arg_count));
 
2853
 
 
2854
  DBUG_RETURN(udf.val_decimal(&null_value, dec_buf));
 
2855
}
 
2856
 
 
2857
 
 
2858
Item *Item_sum_udf_decimal::copy_or_same(THD* thd)
 
2859
{
 
2860
  return new (thd->mem_root) Item_sum_udf_decimal(thd, this);
 
2861
}
 
2862
 
 
2863
 
 
2864
Item *Item_sum_udf_int::copy_or_same(THD* thd)
 
2865
{
 
2866
  return new (thd->mem_root) Item_sum_udf_int(thd, this);
 
2867
}
 
2868
 
 
2869
longlong Item_sum_udf_int::val_int()
 
2870
{
 
2871
  DBUG_ASSERT(fixed == 1);
 
2872
  DBUG_ENTER("Item_sum_udf_int::val_int");
 
2873
  DBUG_PRINT("info",("result_type: %d  arg_count: %d",
 
2874
                     args[0]->result_type(), arg_count));
 
2875
  DBUG_RETURN(udf.val_int(&null_value));
 
2876
}
 
2877
 
 
2878
 
 
2879
String *Item_sum_udf_int::val_str(String *str)
 
2880
{
 
2881
  return val_string_from_int(str);
 
2882
}
 
2883
 
 
2884
my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
 
2885
{
 
2886
  return val_decimal_from_int(dec);
 
2887
}
 
2888
 
 
2889
 
 
2890
/** Default max_length is max argument length. */
 
2891
 
 
2892
void Item_sum_udf_str::fix_length_and_dec()
 
2893
{
 
2894
  DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec");
 
2895
  max_length=0;
 
2896
  for (uint i = 0; i < arg_count; i++)
 
2897
    set_if_bigger(max_length,args[i]->max_length);
 
2898
  DBUG_VOID_RETURN;
 
2899
}
 
2900
 
 
2901
 
 
2902
Item *Item_sum_udf_str::copy_or_same(THD* thd)
 
2903
{
 
2904
  return new (thd->mem_root) Item_sum_udf_str(thd, this);
 
2905
}
 
2906
 
 
2907
 
 
2908
my_decimal *Item_sum_udf_str::val_decimal(my_decimal *dec)
 
2909
{
 
2910
  return val_decimal_from_string(dec);
 
2911
}
 
2912
 
 
2913
String *Item_sum_udf_str::val_str(String *str)
 
2914
{
 
2915
  DBUG_ASSERT(fixed == 1);
 
2916
  DBUG_ENTER("Item_sum_udf_str::str");
 
2917
  String *res=udf.val_str(str,&str_value);
 
2918
  null_value = !res;
 
2919
  DBUG_RETURN(res);
 
2920
}
 
2921
 
 
2922
#endif /* HAVE_DLOPEN */
 
2923
 
2769
2924
 
2770
2925
/*****************************************************************************
2771
2926
 GROUP_CONCAT function
2772
2927
 
2773
2928
 SQL SYNTAX:
2774
 
  GROUP_CONCAT([DISTINCT] expr,... [order_st BY col [ASC|DESC],...]
 
2929
  GROUP_CONCAT([DISTINCT] expr,... [ORDER BY col [ASC|DESC],...]
2775
2930
    [SEPARATOR str_const])
2776
2931
 
2777
2932
 concat of values from "group by" operation
2778
2933
 
2779
2934
 BUGS
2780
 
   Blobs doesn't work with DISTINCT or order_st BY
 
2935
   Blobs doesn't work with DISTINCT or ORDER BY
2781
2936
*****************************************************************************/
2782
2937
 
2783
2938
 
2784
 
/**
 
2939
/** 
2785
2940
  Compares the values for fields in expr list of GROUP_CONCAT.
2786
2941
  @note
2787
 
 
 
2942
       
2788
2943
     GROUP_CONCAT([DISTINCT] expr [,expr ...]
2789
 
              [order_st BY {unsigned_integer | col_name | expr}
 
2944
              [ORDER BY {unsigned_integer | col_name | expr}
2790
2945
                  [ASC | DESC] [,col_name ...]]
2791
2946
              [SEPARATOR str_val])
2792
 
 
 
2947
 
2793
2948
  @return
2794
 
  @retval -1 : key1 < key2
 
2949
  @retval -1 : key1 < key2 
2795
2950
  @retval  0 : key1 = key2
2796
 
  @retval  1 : key1 > key2
 
2951
  @retval  1 : key1 > key2 
2797
2952
*/
2798
2953
 
2799
 
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
 
2954
int group_concat_key_cmp_with_distinct(void* arg, const void* key1, 
2800
2955
                                       const void* key2)
2801
2956
{
2802
2957
  Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
2803
 
  Table *table= item_func->table;
 
2958
  TABLE *table= item_func->table;
2804
2959
 
2805
 
  for (uint32_t i= 0; i < item_func->arg_count_field; i++)
 
2960
  for (uint i= 0; i < item_func->arg_count_field; i++)
2806
2961
  {
2807
2962
    Item *item= item_func->args[i];
2808
 
    /*
 
2963
    /* 
2809
2964
      If field_item is a const item then either get_tp_table_field returns 0
2810
 
      or it is an item over a const table.
 
2965
      or it is an item over a const table. 
2811
2966
    */
2812
2967
    if (item->const_item())
2813
2968
      continue;
2818
2973
    */
2819
2974
    Field *field= item->get_tmp_table_field();
2820
2975
    int res;
2821
 
    uint32_t offset= field->offset(field->getTable()->record[0])-table->getShare()->null_bytes;
2822
 
    if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
 
2976
    uint offset= field->offset(field->table->record[0])-table->s->null_bytes;
 
2977
    if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
2823
2978
      return res;
2824
2979
  }
2825
2980
  return 0;
2830
2985
  function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
2831
2986
*/
2832
2987
 
2833
 
int group_concat_key_cmp_with_order(void* arg, const void* key1,
 
2988
int group_concat_key_cmp_with_order(void* arg, const void* key1, 
2834
2989
                                    const void* key2)
2835
2990
{
2836
2991
  Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2837
 
  order_st **order_item, **end;
2838
 
  Table *table= grp_item->table;
 
2992
  ORDER **order_item, **end;
 
2993
  TABLE *table= grp_item->table;
2839
2994
 
2840
2995
  for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
2841
2996
       order_item < end;
2848
3003
      the temporary table, not the original field
2849
3004
    */
2850
3005
    Field *field= item->get_tmp_table_field();
2851
 
    /*
 
3006
    /* 
2852
3007
      If item is a const item then either get_tp_table_field returns 0
2853
 
      or it is an item over a const table.
 
3008
      or it is an item over a const table. 
2854
3009
    */
2855
3010
    if (field && !item->const_item())
2856
3011
    {
2857
3012
      int res;
2858
 
      uint32_t offset= (field->offset(field->getTable()->record[0]) -
2859
 
                    table->getShare()->null_bytes);
2860
 
      if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
 
3013
      uint offset= (field->offset(field->table->record[0]) -
 
3014
                    table->s->null_bytes);
 
3015
      if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
2861
3016
        return (*order_item)->asc ? res : -res;
2862
3017
    }
2863
3018
  }
2874
3029
  Append data from current leaf to item->result.
2875
3030
*/
2876
3031
 
2877
 
int dump_leaf_key(unsigned char* key, uint32_t ,
 
3032
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
2878
3033
                  Item_func_group_concat *item)
2879
3034
{
2880
 
  Table *table= item->table;
2881
 
  String tmp((char *)table->getUpdateRecord(), table->getShare()->getRecordLength(),
 
3035
  TABLE *table= item->table;
 
3036
  String tmp((char *)table->record[1], table->s->reclength,
2882
3037
             default_charset_info);
2883
3038
  String tmp2;
2884
3039
  String *result= &item->result;
2885
3040
  Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
2886
 
  uint32_t old_length= result->length();
 
3041
  uint old_length= result->length();
2887
3042
 
2888
3043
  if (item->no_appended)
2889
 
    item->no_appended= false;
 
3044
    item->no_appended= FALSE;
2890
3045
  else
2891
3046
    result->append(*item->separator);
2892
3047
 
2905
3060
        because it contains both order and arg list fields.
2906
3061
      */
2907
3062
      Field *field= (*arg)->get_tmp_table_field();
2908
 
      uint32_t offset= (field->offset(field->getTable()->record[0]) -
2909
 
                    table->getShare()->null_bytes);
2910
 
      assert(offset < table->getShare()->getRecordLength());
 
3063
      uint offset= (field->offset(field->table->record[0]) -
 
3064
                    table->s->null_bytes);
 
3065
      DBUG_ASSERT(offset < table->s->reclength);
2911
3066
      res= field->val_str(&tmp, key + offset);
2912
3067
    }
2913
3068
    else
2920
3075
  if (result->length() > item->max_length)
2921
3076
  {
2922
3077
    int well_formed_error;
2923
 
    const CHARSET_INFO * const cs= item->collation.collation;
 
3078
    CHARSET_INFO *cs= item->collation.collation;
2924
3079
    const char *ptr= result->ptr();
2925
 
    uint32_t add_length;
 
3080
    uint add_length;
2926
3081
    /*
2927
3082
      It's ok to use item->result.length() as the fourth argument
2928
3083
      as this is never used to limit the length of the data.
2935
3090
                                          &well_formed_error);
2936
3091
    result->length(old_length + add_length);
2937
3092
    item->count_cut_values++;
2938
 
    item->warning_for_row= true;
 
3093
    item->warning_for_row= TRUE;
2939
3094
    return 1;
2940
3095
  }
2941
3096
  return 0;
2956
3111
                       bool distinct_arg, List<Item> *select_list,
2957
3112
                       SQL_LIST *order_list, String *separator_arg)
2958
3113
  :tmp_table_param(0), warning(0),
2959
 
   separator(separator_arg), tree(NULL), unique_filter(NULL), table(0),
 
3114
   separator(separator_arg), tree(0), unique_filter(NULL), table(0),
2960
3115
   order(0), context(context_arg),
2961
3116
   arg_count_order(order_list ? order_list->elements : 0),
2962
3117
   arg_count_field(select_list->elements),
2963
3118
   count_cut_values(0),
2964
3119
   distinct(distinct_arg),
2965
 
   warning_for_row(false),
 
3120
   warning_for_row(FALSE),
2966
3121
   force_copy_fields(0), original(0)
2967
3122
{
2968
3123
  Item *item_select;
2969
3124
  Item **arg_ptr;
2970
3125
 
2971
 
  quick_group= false;
 
3126
  quick_group= FALSE;
2972
3127
  arg_count= arg_count_field + arg_count_order;
2973
3128
 
2974
3129
  /*
2977
3132
           (for possible order items in temporare tables)
2978
3133
    order - arg_count_order
2979
3134
  */
2980
 
  if (!(args= (Item**) memory::sql_alloc(sizeof(Item*) * arg_count +
2981
 
                                 sizeof(order_st*)*arg_count_order)))
 
3135
  if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
 
3136
                                 sizeof(ORDER*)*arg_count_order)))
2982
3137
    return;
2983
3138
 
2984
 
  order= (order_st**)(args + arg_count);
 
3139
  order= (ORDER**)(args + arg_count);
2985
3140
 
2986
3141
  /* fill args items of show and sort */
2987
3142
  List_iterator_fast<Item> li(*select_list);
2991
3146
 
2992
3147
  if (arg_count_order)
2993
3148
  {
2994
 
    order_st **order_ptr= order;
2995
 
    for (order_st *order_item= (order_st*) order_list->first;
 
3149
    ORDER **order_ptr= order;
 
3150
    for (ORDER *order_item= (ORDER*) order_list->first;
2996
3151
         order_item != NULL;
2997
3152
         order_item= order_item->next)
2998
3153
    {
3004
3159
}
3005
3160
 
3006
3161
 
3007
 
Item_func_group_concat::Item_func_group_concat(Session *session,
 
3162
Item_func_group_concat::Item_func_group_concat(THD *thd,
3008
3163
                                               Item_func_group_concat *item)
3009
 
  :Item_sum(session, item),
 
3164
  :Item_sum(thd, item),
3010
3165
  tmp_table_param(item->tmp_table_param),
3011
3166
  warning(item->warning),
3012
3167
  separator(item->separator),
3032
3187
 
3033
3188
void Item_func_group_concat::cleanup()
3034
3189
{
 
3190
  DBUG_ENTER("Item_func_group_concat::cleanup");
3035
3191
  Item_sum::cleanup();
3036
3192
 
3037
3193
  /* Adjust warning message to include total number of cut values */
3038
3194
  if (warning)
3039
3195
  {
3040
 
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
3041
 
    snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3042
 
    warning->set_msg(current_session, warn_buff);
 
3196
    char warn_buff[MYSQL_ERRMSG_SIZE];
 
3197
    sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
 
3198
    warning->set_msg(current_thd, warn_buff);
3043
3199
    warning= 0;
3044
3200
  }
3045
3201
 
3053
3209
    tmp_table_param= 0;
3054
3210
    if (table)
3055
3211
    {
3056
 
      Session *session= table->in_use;
 
3212
      THD *thd= table->in_use;
 
3213
      free_tmp_table(thd, table);
3057
3214
      table= 0;
3058
3215
      if (tree)
3059
3216
      {
3067
3224
      }
3068
3225
      if (warning)
3069
3226
      {
3070
 
        char warn_buff[DRIZZLE_ERRMSG_SIZE];
3071
 
        snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3072
 
        warning->set_msg(session, warn_buff);
 
3227
        char warn_buff[MYSQL_ERRMSG_SIZE];
 
3228
        sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
 
3229
        warning->set_msg(thd, warn_buff);
3073
3230
        warning= 0;
3074
3231
      }
3075
3232
    }
3076
 
    assert(tree == 0 && warning == 0);
 
3233
    DBUG_ASSERT(tree == 0 && warning == 0);
3077
3234
  }
3078
 
  return;
 
3235
  DBUG_VOID_RETURN;
3079
3236
}
3080
3237
 
3081
3238
 
3082
 
Item *Item_func_group_concat::copy_or_same(Session* session)
 
3239
Item *Item_func_group_concat::copy_or_same(THD* thd)
3083
3240
{
3084
 
  return new (session->mem_root) Item_func_group_concat(session, this);
 
3241
  return new (thd->mem_root) Item_func_group_concat(thd, this);
3085
3242
}
3086
3243
 
3087
3244
 
3089
3246
{
3090
3247
  result.length(0);
3091
3248
  result.copy();
3092
 
  null_value= true;
3093
 
  warning_for_row= false;
3094
 
  no_appended= true;
 
3249
  null_value= TRUE;
 
3250
  warning_for_row= FALSE;
 
3251
  no_appended= TRUE;
3095
3252
  if (tree)
3096
3253
    reset_tree(tree);
3097
3254
  if (distinct)
3107
3264
  copy_fields(tmp_table_param);
3108
3265
  copy_funcs(tmp_table_param->items_to_copy);
3109
3266
 
3110
 
  for (uint32_t i= 0; i < arg_count_field; i++)
 
3267
  for (uint i= 0; i < arg_count_field; i++)
3111
3268
  {
3112
3269
    Item *show_item= args[i];
3113
3270
    if (!show_item->const_item())
3114
3271
    {
3115
3272
      Field *f= show_item->get_tmp_table_field();
3116
 
      if (f->is_null_in_record((const unsigned char*) table->record[0]))
 
3273
      if (f->is_null_in_record((const uchar*) table->record[0]))
3117
3274
        return 0;                               // Skip row if it contains null
3118
3275
    }
3119
3276
  }
3120
3277
 
3121
 
  null_value= false;
3122
 
  bool row_eligible= true;
 
3278
  null_value= FALSE;
 
3279
  bool row_eligible= TRUE;
3123
3280
 
3124
 
  if (distinct)
 
3281
  if (distinct) 
3125
3282
  {
3126
3283
    /* Filter out duplicate rows. */
3127
 
    uint32_t count= unique_filter->elements_in_tree();
3128
 
    unique_filter->unique_add(table->record[0] + table->getShare()->null_bytes);
 
3284
    uint count= unique_filter->elements_in_tree();
 
3285
    unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3129
3286
    if (count == unique_filter->elements_in_tree())
3130
 
      row_eligible= false;
 
3287
      row_eligible= FALSE;
3131
3288
  }
3132
3289
 
3133
3290
  TREE_ELEMENT *el= 0;                          // Only for safety
3134
3291
  if (row_eligible && tree)
3135
 
    el= tree_insert(tree, table->record[0] + table->getShare()->null_bytes, 0,
 
3292
    el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3136
3293
                    tree->custom_arg);
3137
3294
  /*
3138
3295
    If the row is not a duplicate (el->count == 1)
3141
3298
  */
3142
3299
  if (row_eligible && !warning_for_row &&
3143
3300
      (!tree || (el->count == 1 && distinct && !arg_count_order)))
3144
 
    dump_leaf_key(table->record[0] + table->getShare()->null_bytes, 1, this);
 
3301
    dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3145
3302
 
3146
3303
  return 0;
3147
3304
}
3148
3305
 
3149
3306
 
3150
3307
bool
3151
 
Item_func_group_concat::fix_fields(Session *session, Item **ref)
 
3308
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3152
3309
{
3153
 
  uint32_t i;                       /* for loop variable */
3154
 
  assert(fixed == 0);
 
3310
  uint i;                       /* for loop variable */
 
3311
  DBUG_ASSERT(fixed == 0);
3155
3312
 
3156
 
  if (init_sum_func_check(session))
3157
 
    return true;
 
3313
  if (init_sum_func_check(thd))
 
3314
    return TRUE;
3158
3315
 
3159
3316
  maybe_null= 1;
3160
3317
 
3161
3318
  /*
3162
 
    Fix fields for select list and order_st clause
 
3319
    Fix fields for select list and ORDER clause
3163
3320
  */
3164
3321
 
3165
3322
  for (i=0 ; i < arg_count ; i++)
3166
3323
  {
3167
3324
    if ((!args[i]->fixed &&
3168
 
         args[i]->fix_fields(session, args + i)) ||
 
3325
         args[i]->fix_fields(thd, args + i)) ||
3169
3326
        args[i]->check_cols(1))
3170
 
      return true;
 
3327
      return TRUE;
3171
3328
  }
3172
3329
 
3173
3330
  if (agg_item_charsets(collation, func_name(),
3180
3337
  result.set_charset(collation.collation);
3181
3338
  result_field= 0;
3182
3339
  null_value= 1;
3183
 
  max_length= (size_t)session->variables.group_concat_max_len;
3184
 
 
3185
 
  if (check_sum_func(session, ref))
3186
 
    return true;
 
3340
  max_length= thd->variables.group_concat_max_len;
 
3341
 
 
3342
  uint32 offset;
 
3343
  if (separator->needs_conversion(separator->length(), separator->charset(),
 
3344
                                  collation.collation, &offset))
 
3345
  {
 
3346
    uint32 buflen= collation.collation->mbmaxlen * separator->length();
 
3347
    uint errors, conv_length;
 
3348
    char *buf;
 
3349
    String *new_separator;
 
3350
 
 
3351
    if (!(buf= (char*) thd->stmt_arena->alloc(buflen)) ||
 
3352
        !(new_separator= new(thd->stmt_arena->mem_root)
 
3353
                           String(buf, buflen, collation.collation)))
 
3354
      return TRUE;
 
3355
    
 
3356
    conv_length= copy_and_convert(buf, buflen, collation.collation,
 
3357
                                  separator->ptr(), separator->length(),
 
3358
                                  separator->charset(), &errors);
 
3359
    new_separator->length(conv_length);
 
3360
    separator= new_separator;
 
3361
  }
 
3362
 
 
3363
  if (check_sum_func(thd, ref))
 
3364
    return TRUE;
3187
3365
 
3188
3366
  fixed= 1;
3189
 
  return false;
 
3367
  return FALSE;
3190
3368
}
3191
3369
 
3192
3370
 
3193
 
bool Item_func_group_concat::setup(Session *session)
 
3371
bool Item_func_group_concat::setup(THD *thd)
3194
3372
{
3195
3373
  List<Item> list;
3196
 
  Select_Lex *select_lex= session->lex->current_select;
 
3374
  SELECT_LEX *select_lex= thd->lex->current_select;
 
3375
  DBUG_ENTER("Item_func_group_concat::setup");
3197
3376
 
3198
3377
  /*
3199
3378
    Currently setup() can be called twice. Please add
3200
3379
    assertion here when this is fixed.
3201
3380
  */
3202
3381
  if (table || tree)
3203
 
    return(false);
 
3382
    DBUG_RETURN(FALSE);
3204
3383
 
3205
 
  if (!(tmp_table_param= new Tmp_Table_Param))
3206
 
    return(true);
 
3384
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
 
3385
    DBUG_RETURN(TRUE);
3207
3386
 
3208
3387
  /* We'll convert all blobs to varchar fields in the temporary table */
3209
3388
  tmp_table_param->convert_blob_length= max_length *
3210
3389
                                        collation.collation->mbmaxlen;
3211
3390
  /* Push all not constant fields to the list and create a temp table */
3212
3391
  always_null= 0;
3213
 
  for (uint32_t i= 0; i < arg_count_field; i++)
 
3392
  for (uint i= 0; i < arg_count_field; i++)
3214
3393
  {
3215
3394
    Item *item= args[i];
3216
3395
    if (list.push_back(item))
3217
 
      return(true);
 
3396
      DBUG_RETURN(TRUE);
3218
3397
    if (item->const_item())
3219
3398
    {
3220
3399
      if (item->is_null())
3221
3400
      {
3222
3401
        always_null= 1;
3223
 
        return(false);
 
3402
        DBUG_RETURN(FALSE);
3224
3403
      }
3225
3404
    }
3226
3405
  }
3227
3406
 
3228
3407
  List<Item> all_fields(list);
3229
3408
  /*
3230
 
    Try to find every order_st expression in the list of GROUP_CONCAT
 
3409
    Try to find every ORDER expression in the list of GROUP_CONCAT
3231
3410
    arguments. If an expression is not found, prepend it to
3232
3411
    "all_fields". The resulting field list is used as input to create
3233
3412
    tmp table columns.
3234
3413
  */
3235
3414
  if (arg_count_order &&
3236
 
      setup_order(session, args, context->table_list, list, all_fields, *order))
3237
 
    return(true);
 
3415
      setup_order(thd, args, context->table_list, list, all_fields, *order))
 
3416
    DBUG_RETURN(TRUE);
3238
3417
 
3239
3418
  count_field_types(select_lex, tmp_table_param, all_fields, 0);
3240
3419
  tmp_table_param->force_copy_fields= force_copy_fields;
3241
 
  assert(table == 0);
 
3420
  DBUG_ASSERT(table == 0);
3242
3421
  if (arg_count_order > 0 || distinct)
3243
3422
  {
3244
3423
    /*
3247
3426
      DISTINCT. This leads to truncation if the BLOB's size exceeds
3248
3427
      Field_varstring::MAX_SIZE.
3249
3428
    */
3250
 
    set_if_smaller(tmp_table_param->convert_blob_length,
 
3429
    set_if_smaller(tmp_table_param->convert_blob_length, 
3251
3430
                   Field_varstring::MAX_SIZE);
 
3431
 
 
3432
    /*
 
3433
      Force the create_tmp_table() to convert BIT columns to INT
 
3434
      as we cannot compare two table records containg BIT fields
 
3435
      stored in the the tree used for distinct/order by.
 
3436
      Moreover we don't even save in the tree record null bits 
 
3437
      where BIT fields store parts of their data.
 
3438
    */
 
3439
    List_iterator_fast<Item> li(all_fields);
 
3440
    Item *item;
 
3441
    while ((item= li++))
 
3442
    {
 
3443
      if (item->type() == Item::FIELD_ITEM && 
 
3444
          ((Item_field*) item)->field->type() == FIELD_TYPE_BIT)
 
3445
        item->marker= 4;
 
3446
    }
3252
3447
  }
3253
3448
 
3254
3449
  /*
3258
3453
    Note that in the table, we first have the ORDER BY fields, then the
3259
3454
    field list.
3260
3455
  */
3261
 
  if (!(table= create_tmp_table(session, tmp_table_param, all_fields,
3262
 
                                (order_st*) 0, 0, true,
3263
 
                                (select_lex->options | session->options),
 
3456
  if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
 
3457
                                (ORDER*) 0, 0, TRUE,
 
3458
                                (select_lex->options | thd->options),
3264
3459
                                HA_POS_ERROR, (char*) "")))
3265
 
  {
3266
 
    return(true);
3267
 
  }
3268
 
 
3269
 
  table->cursor->extra(HA_EXTRA_NO_ROWS);
 
3460
    DBUG_RETURN(TRUE);
 
3461
  table->file->extra(HA_EXTRA_NO_ROWS);
3270
3462
  table->no_rows= 1;
3271
3463
 
3272
3464
  /*
3274
3466
     Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3275
3467
     the row is not added to the result.
3276
3468
  */
3277
 
  uint32_t tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
 
3469
  uint tree_key_length= table->s->reclength - table->s->null_bytes;
3278
3470
 
3279
3471
  if (arg_count_order)
3280
3472
  {
3284
3476
      syntax of this function). If there is no ORDER BY clause, we don't
3285
3477
      create this tree.
3286
3478
    */
3287
 
    init_tree(tree, (uint32_t) min(session->variables.max_heap_table_size,
3288
 
                                   (uint64_t)(session->variables.sortbuff_size/16)), 
3289
 
              0,
3290
 
              tree_key_length,
3291
 
              group_concat_key_cmp_with_order , false, NULL, (void*) this);
 
3479
    init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
 
3480
                               thd->variables.sortbuff_size/16), 0,
 
3481
              tree_key_length, 
 
3482
              group_concat_key_cmp_with_order , 0, NULL, (void*) this);
3292
3483
  }
3293
3484
 
3294
3485
  if (distinct)
3295
3486
    unique_filter= new Unique(group_concat_key_cmp_with_distinct,
3296
3487
                              (void*)this,
3297
3488
                              tree_key_length,
3298
 
                              (size_t)session->variables.max_heap_table_size);
3299
 
 
3300
 
  return(false);
 
3489
                              thd->variables.max_heap_table_size);
 
3490
  
 
3491
  DBUG_RETURN(FALSE);
3301
3492
}
3302
3493
 
3303
3494
 
3312
3503
  tree= 0;
3313
3504
}
3314
3505
 
3315
 
double Item_func_group_concat::val_real()
3316
 
{
3317
 
  String *res;  res=val_str(&str_value);
3318
 
  return res ? internal::my_atof(res->c_ptr()) : 0.0;
3319
 
}
3320
 
 
3321
 
int64_t Item_func_group_concat::val_int()
3322
 
{
3323
 
  String *res;
3324
 
  char *end_ptr;
3325
 
  int error;
3326
 
  if (!(res= val_str(&str_value)))
3327
 
    return (int64_t) 0;
3328
 
  end_ptr= (char*) res->ptr()+ res->length();
3329
 
  return internal::my_strtoll10(res->ptr(), &end_ptr, &error);
3330
 
}
3331
 
 
3332
 
String* Item_func_group_concat::val_str(String* )
3333
 
{
3334
 
  assert(fixed == 1);
 
3506
 
 
3507
String* Item_func_group_concat::val_str(String* str)
 
3508
{
 
3509
  DBUG_ASSERT(fixed == 1);
3335
3510
  if (null_value)
3336
3511
    return 0;
3337
3512
  if (no_appended && tree)
3344
3519
      ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in
3345
3520
      Item_func_group_concat::cleanup().
3346
3521
    */
3347
 
    assert(table);
3348
 
    warning= push_warning(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
3522
    DBUG_ASSERT(table);
 
3523
    warning= push_warning(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
3349
3524
                          ER_CUT_VALUE_GROUP_CONCAT,
3350
3525
                          ER(ER_CUT_VALUE_GROUP_CONCAT));
3351
3526
  }
3358
3533
  str->append(STRING_WITH_LEN("group_concat("));
3359
3534
  if (distinct)
3360
3535
    str->append(STRING_WITH_LEN("distinct "));
3361
 
  for (uint32_t i= 0; i < arg_count_field; i++)
 
3536
  for (uint i= 0; i < arg_count_field; i++)
3362
3537
  {
3363
3538
    if (i)
3364
3539
      str->append(',');
3367
3542
  if (arg_count_order)
3368
3543
  {
3369
3544
    str->append(STRING_WITH_LEN(" order by "));
3370
 
    for (uint32_t i= 0 ; i < arg_count_order ; i++)
 
3545
    for (uint i= 0 ; i < arg_count_order ; i++)
3371
3546
    {
3372
3547
      if (i)
3373
3548
        str->append(',');
3387
3562
Item_func_group_concat::~Item_func_group_concat()
3388
3563
{
3389
3564
  if (!original && unique_filter)
3390
 
    delete unique_filter;
 
3565
    delete unique_filter;    
3391
3566
}
3392
 
 
3393
 
} /* namespace drizzled */