~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_sum.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 09:12:23 UTC
  • mto: (511.1.6 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016091223-17ngih0qu9vssjs3
We pass -Wunused-macros now!

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>
 
23
#include <drizzled/server_includes.h>
26
24
#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;
 
25
#include <drizzled/drizzled_error_messages.h>
51
26
 
52
27
/**
53
28
  Prepare an aggregate function item for checking context conditions.
58
33
    If the set function is not allowed in any subquery where it occurs
59
34
    an error is reported immediately.
60
35
 
61
 
  @param session      reference to the thread context info
 
36
  @param thd      reference to the thread context info
62
37
 
63
38
  @note
64
39
    This function is to be called for any item created for a set function
70
45
  @retval
71
46
    FALSE  otherwise
72
47
*/
73
 
 
74
 
bool Item_sum::init_sum_func_check(Session *session)
 
48
 
 
49
bool Item_sum::init_sum_func_check(THD *thd)
75
50
{
76
 
  if (!session->lex->allow_sum_func)
 
51
  if (!thd->lex->allow_sum_func)
77
52
  {
78
53
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
79
54
               MYF(0));
80
55
    return true;
81
56
  }
82
57
  /* Set a reference to the nesting set function if there is  any */
83
 
  in_sum_func= session->lex->in_sum_func;
 
58
  in_sum_func= thd->lex->in_sum_func;
84
59
  /* 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;
 
60
  thd->lex->in_sum_func= this;
 
61
  nest_level= thd->lex->current_select->nest_level;
87
62
  ref_by= 0;
88
63
  aggr_level= -1;
89
64
  aggr_sel= NULL;
105
80
    If the context conditions are not met the method reports an error.
106
81
    If the set function is aggregated in some outer subquery the method
107
82
    adds it to the chain of items for such set functions that is attached
108
 
    to the the Select_Lex structure for this subquery.
 
83
    to the the st_select_lex structure for this subquery.
109
84
 
110
85
    A number of designated members of the object are used to check the
111
86
    conditions. They are specified in the comment before the Item_sum
112
87
    class declaration.
113
88
    Additionally a bitmap variable called allow_sum_func is employed.
114
 
    It is included into the session->lex structure.
 
89
    It is included into the thd->lex structure.
115
90
    The bitmap contains 1 at n-th position if the set function happens
116
91
    to occur under a construct of the n-th level subquery where usage
117
92
    of set functions are allowed (i.e either in the SELECT list or
122
97
         HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
123
98
                t1.a > (SELECT MIN(t2.d) FROM t2);
124
99
    @endcode
125
 
    allow_sum_func will contain:
126
 
    - for SUM(t1.b) - 1 at the first position
 
100
    allow_sum_func will contain: 
 
101
    - for SUM(t1.b) - 1 at the first position 
127
102
    - for AVG(t1.b) - 1 at the first position, 0 at the second position
128
103
    - for MIN(t2.d) - 1 at the first position, 1 at the second position.
129
104
 
130
 
  @param session  reference to the thread context info
 
105
  @param thd  reference to the thread context info
131
106
  @param ref  location of the pointer to this item in the embedding expression
132
107
 
133
108
  @note
141
116
  @retval
142
117
    FALSE  otherwise
143
118
*/
144
 
 
145
 
bool Item_sum::check_sum_func(Session *session, Item **ref)
 
119
 
 
120
bool Item_sum::check_sum_func(THD *thd, Item **ref)
146
121
{
147
122
  bool invalid= false;
148
 
  nesting_map allow_sum_func= session->lex->allow_sum_func;
149
 
  /*
 
123
  nesting_map allow_sum_func= thd->lex->allow_sum_func;
 
124
  /*  
150
125
    The value of max_arg_level is updated if an argument of the set function
151
126
    contains a column reference resolved  against a subquery whose level is
152
127
    greater than the current value of max_arg_level.
153
128
    max_arg_level cannot be greater than nest level.
154
 
    nest level is always >= 0
155
 
  */
 
129
    nest level is always >= 0  
 
130
  */ 
156
131
  if (nest_level == max_arg_level)
157
132
  {
158
133
    /*
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
 
    */
 
134
      The function must be aggregated in the current subquery, 
 
135
      If it is there under a construct where it is not allowed 
 
136
      we report an error. 
 
137
    */ 
163
138
    invalid= !(allow_sum_func & (1 << max_arg_level));
164
139
  }
165
140
  else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
169
144
      Try to find a subquery where it can be aggregated;
170
145
      If we fail to find such a subquery report an error.
171
146
    */
172
 
    if (register_sum_func(session, ref))
 
147
    if (register_sum_func(thd, ref))
173
148
      return true;
174
149
    invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
175
150
    if (!invalid && false)
178
153
  if (!invalid && aggr_level < 0)
179
154
  {
180
155
    aggr_level= nest_level;
181
 
    aggr_sel= session->lex->current_select;
 
156
    aggr_sel= thd->lex->current_select;
182
157
  }
183
158
  /*
184
159
    By this moment we either found a subquery where the set function is
185
160
    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.
 
161
    or set the value of 'invalid' to TRUE to report later an error. 
187
162
  */
188
 
  /*
 
163
  /* 
189
164
    Additionally we have to check whether possible nested set functions
190
165
    are acceptable here: they are not, if the level of aggregation of
191
166
    some of them is less than aggr_level.
192
167
  */
193
 
  if (!invalid)
 
168
  if (!invalid) 
194
169
    invalid= aggr_level <= max_sum_func_level;
195
 
  if (invalid)
 
170
  if (invalid)  
196
171
  {
197
172
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
198
173
               MYF(0));
204
179
    /*
205
180
      If the set function is nested adjust the value of
206
181
      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
 
182
      We take into account only enclosed set functions that are to be 
 
183
      aggregated on the same level or above of the nest level of 
209
184
      the enclosing set function.
210
185
      But we must always pass up the max_sum_func_level because it is
211
186
      the maximum nested level of all directly and indirectly enclosed
256
231
    List_iterator<Item_field> of(outer_fields);
257
232
    while ((field= of++))
258
233
    {
259
 
      Select_Lex *sel= field->cached_table->select_lex;
 
234
      SELECT_LEX *sel= field->cached_table->select_lex;
260
235
      if (sel->nest_level < aggr_level)
261
236
      {
262
237
        if (in_sum_func)
268
243
          in_sum_func->outer_fields.push_back(field);
269
244
        }
270
245
        else
271
 
        {
272
 
          sel->full_group_by_flag.set(NON_AGG_FIELD_USED);
273
 
        }
 
246
          sel->full_group_by_flag|= NON_AGG_FIELD_USED;
274
247
      }
275
248
      if (sel->nest_level > aggr_level &&
276
 
          (sel->full_group_by_flag.test(SUM_FUNC_USED)) &&
277
 
          ! sel->group_list.elements)
 
249
          (sel->full_group_by_flag & SUM_FUNC_USED) &&
 
250
          !sel->group_list.elements)
278
251
      {
279
252
        my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
280
253
                   ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
282
255
      }
283
256
    }
284
257
  }
285
 
  aggr_sel->full_group_by_flag.set(SUM_FUNC_USED);
 
258
  aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
286
259
  update_used_tables();
287
 
  session->lex->in_sum_func= in_sum_func;
 
260
  thd->lex->in_sum_func= in_sum_func;
288
261
  return false;
289
262
}
290
263
 
295
268
    aggregated. If it finds such a subquery then aggr_level is set to
296
269
    the nest level of this subquery and the item for the set function
297
270
    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
 
271
    inner_sum_func_list defined for each subquery. When the item is placed 
299
272
    there the field 'ref_by' is set to ref.
300
273
 
301
274
  @note
304
277
    a subquery in one chain. It would simplify the process of 'splitting'
305
278
    for set functions.
306
279
 
307
 
  @param session  reference to the thread context info
 
280
  @param thd  reference to the thread context info
308
281
  @param ref  location of the pointer to this item in the embedding expression
309
282
 
310
283
  @retval
311
284
    FALSE  if the executes without failures (currently always)
312
285
  @retval
313
286
    TRUE   otherwise
314
 
*/
 
287
*/  
315
288
 
316
 
bool Item_sum::register_sum_func(Session *session, Item **ref)
 
289
bool Item_sum::register_sum_func(THD *thd, Item **ref)
317
290
{
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() ;
 
291
  SELECT_LEX *sl;
 
292
  nesting_map allow_sum_func= thd->lex->allow_sum_func;
 
293
  for (sl= thd->lex->current_select->master_unit()->outer_select() ;
321
294
       sl && sl->nest_level > max_arg_level;
322
295
       sl= sl->master_unit()->outer_select() )
323
296
  {
330
303
  }
331
304
  if (sl && (allow_sum_func & (1 << sl->nest_level)))
332
305
  {
333
 
    /*
 
306
    /* 
334
307
      We reached the subquery of level max_arg_level and checked
335
 
      that the function can be aggregated here.
 
308
      that the function can be aggregated here. 
336
309
      The set function will be aggregated in this subquery.
337
 
    */
 
310
    */   
338
311
    aggr_level= sl->nest_level;
339
312
    aggr_sel= sl;
340
313
 
353
326
    aggr_sel->inner_sum_func_list= this;
354
327
    aggr_sel->with_sum_func= 1;
355
328
 
356
 
    /*
 
329
    /* 
357
330
      Mark Item_subselect(s) as containing aggregate function all the way up
358
331
      to aggregate function's calculation context.
359
332
      Note that we must not mark the Item of calculation context itself
360
 
      because with_sum_func on the calculation context Select_Lex is
 
333
      because with_sum_func on the calculation context st_select_lex is
361
334
      already set above.
362
335
 
363
 
      with_sum_func being set for an Item means that this Item refers
 
336
      with_sum_func being set for an Item means that this Item refers 
364
337
      (somewhere in it, e.g. one of its arguments if it's a function) directly
365
338
      or through intermediate items to an aggregate function that is calculated
366
339
      in a context "outside" of the Item (e.g. in the current or outer select).
367
340
 
368
 
      with_sum_func being set for an Select_Lex means that this Select_Lex
 
341
      with_sum_func being set for an st_select_lex means that this st_select_lex
369
342
      has aggregate functions directly referenced (i.e. not through a sub-select).
370
343
    */
371
 
    for (sl= session->lex->current_select;
 
344
    for (sl= thd->lex->current_select; 
372
345
         sl && sl != aggr_sel && sl->master_unit()->item;
373
346
         sl= sl->master_unit()->outer_select() )
374
347
      sl->master_unit()->item->with_sum_func= 1;
375
348
  }
376
 
  session->lex->current_select->mark_as_dependent(aggr_sel);
 
349
  thd->lex->current_select->mark_as_dependent(aggr_sel);
377
350
  return false;
378
351
}
379
352
 
380
353
 
381
 
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
 
354
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), 
382
355
  forced_const(false)
383
356
{
384
 
  if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
 
357
  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
385
358
  {
386
359
    uint32_t i=0;
387
360
    List_iterator_fast<Item> li(list);
401
374
  Constructor used in processing select with temporary tebles.
402
375
*/
403
376
 
404
 
Item_sum::Item_sum(Session *session, Item_sum *item):
405
 
  Item_result_field(session, item), arg_count(item->arg_count),
 
377
Item_sum::Item_sum(THD *thd, Item_sum *item):
 
378
  Item_result_field(thd, item), arg_count(item->arg_count),
406
379
  aggr_sel(item->aggr_sel),
407
380
  nest_level(item->nest_level), aggr_level(item->aggr_level),
408
381
  quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
409
 
  forced_const(item->forced_const)
 
382
  forced_const(item->forced_const) 
410
383
{
411
384
  if (arg_count <= 2)
412
385
    args=tmp_args;
413
386
  else
414
 
    if (!(args= (Item**) session->alloc(sizeof(Item*)*arg_count)))
 
387
    if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
415
388
      return;
416
389
  memcpy(args, item->args, sizeof(Item*)*arg_count);
417
390
}
419
392
 
420
393
void Item_sum::mark_as_sum_func()
421
394
{
422
 
  Select_Lex *cur_select= current_session->lex->current_select;
 
395
  SELECT_LEX *cur_select= current_thd->lex->current_select;
423
396
  cur_select->n_sum_items++;
424
397
  cur_select->with_sum_func= 1;
425
398
  with_sum_func= 1;
426
399
}
427
400
 
428
401
 
429
 
void Item_sum::make_field(SendField *tmp_field)
 
402
void Item_sum::make_field(Send_field *tmp_field)
430
403
{
431
404
  if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
432
405
  {
466
439
  max_length=float_length(decimals);
467
440
}
468
441
 
469
 
Item *Item_sum::get_tmp_table_item(Session *session)
 
442
Item *Item_sum::get_tmp_table_item(THD *thd)
470
443
{
471
 
  Item_sum* sum_item= (Item_sum *) copy_or_same(session);
 
444
  Item_sum* sum_item= (Item_sum *) copy_or_same(thd);
472
445
  if (sum_item && sum_item->result_field)          // If not a const sum func
473
446
  {
474
447
    Field *result_field_tmp= sum_item->result_field;
504
477
}
505
478
 
506
479
 
507
 
Field *Item_sum::create_tmp_field(bool ,
 
480
Field *Item_sum::create_tmp_field(bool group __attribute__((unused)),
508
481
                                  Table *table,
509
482
                                  uint32_t convert_blob_length)
510
483
{
522
495
        !convert_blob_length)
523
496
      return make_string_field(table);
524
497
    field= new Field_varstring(convert_blob_length, maybe_null,
525
 
                               name, table->getMutableShare(), collation.collation);
 
498
                               name, table->s, collation.collation);
526
499
    break;
527
500
  case DECIMAL_RESULT:
528
 
    field= new Field_decimal(max_length, maybe_null, name,
 
501
    field= new Field_new_decimal(max_length, maybe_null, name,
529
502
                                 decimals, unsigned_flag);
530
503
    break;
531
504
  case ROW_RESULT:
566
539
}
567
540
 
568
541
 
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
542
my_decimal *Item_sum_num::val_decimal(my_decimal *decimal_value)
577
543
{
578
544
  return val_decimal_from_real(decimal_value);
593
559
 
594
560
 
595
561
bool
596
 
Item_sum_num::fix_fields(Session *session, Item **ref)
 
562
Item_sum_num::fix_fields(THD *thd, Item **ref)
597
563
{
598
564
  assert(fixed == 0);
599
565
 
600
 
  if (init_sum_func_check(session))
 
566
  if (init_sum_func_check(thd))
601
567
    return true;
602
568
 
603
569
  decimals=0;
604
570
  maybe_null=0;
605
571
  for (uint32_t i=0 ; i < arg_count ; i++)
606
572
  {
607
 
    if (args[i]->fix_fields(session, args + i) || args[i]->check_cols(1))
 
573
    if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
608
574
      return true;
609
575
    set_if_bigger(decimals, args[i]->decimals);
610
576
    maybe_null |= args[i]->maybe_null;
614
580
  null_value=1;
615
581
  fix_length_and_dec();
616
582
 
617
 
  if (check_sum_func(session, ref))
 
583
  if (check_sum_func(thd, ref))
618
584
    return true;
619
585
 
620
586
  fixed= 1;
622
588
}
623
589
 
624
590
 
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),
 
591
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
 
592
  :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
627
593
  hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
628
594
  was_values(item->was_values)
629
595
{
652
618
}
653
619
 
654
620
bool
655
 
Item_sum_hybrid::fix_fields(Session *session, Item **ref)
 
621
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
656
622
{
657
623
  assert(fixed == 0);
658
624
 
659
625
  Item *item= args[0];
660
626
 
661
 
  if (init_sum_func_check(session))
 
627
  if (init_sum_func_check(thd))
662
628
    return true;
663
629
 
664
630
  // 'item' can be changed during fix_fields
665
 
  if ((!item->fixed && item->fix_fields(session, args)) ||
 
631
  if ((!item->fixed && item->fix_fields(thd, args)) ||
666
632
      (item= args[0])->check_cols(1))
667
633
    return true;
668
634
  decimals=item->decimals;
700
666
  else
701
667
    hybrid_field_type= Item::field_type();
702
668
 
703
 
  if (check_sum_func(session, ref))
 
669
  if (check_sum_func(thd, ref))
704
670
    return true;
705
671
 
706
672
  fixed= 1;
714
680
  if (args[0]->type() == Item::FIELD_ITEM)
715
681
  {
716
682
    field= ((Item_field*) args[0])->field;
717
 
 
718
 
    if ((field= create_tmp_field_from_field(current_session, field, name, table,
 
683
    
 
684
    if ((field= create_tmp_field_from_field(current_thd, field, name, table,
719
685
                                            NULL, convert_blob_length)))
720
686
      field->flags&= ~NOT_NULL_FLAG;
721
687
    return field;
726
692
    fields creations separately.
727
693
  */
728
694
  switch (args[0]->field_type()) {
729
 
  case DRIZZLE_TYPE_DATE:
730
 
    field= new Field_date(maybe_null, name, collation.collation);
 
695
  case DRIZZLE_TYPE_NEWDATE:
 
696
    field= new Field_newdate(maybe_null, name, collation.collation);
 
697
    break;
 
698
  case DRIZZLE_TYPE_TIME:
 
699
    field= new Field_time(maybe_null, name, collation.collation);
731
700
    break;
732
701
  case DRIZZLE_TYPE_TIMESTAMP:
733
702
  case DRIZZLE_TYPE_DATETIME:
750
719
  @todo
751
720
  check if the following assignments are really needed
752
721
*/
753
 
Item_sum_sum::Item_sum_sum(Session *session, Item_sum_sum *item)
754
 
  :Item_sum_num(session, item), hybrid_type(item->hybrid_type),
 
722
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item) 
 
723
  :Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
755
724
   curr_dec_buff(item->curr_dec_buff)
756
725
{
757
726
  /* TODO: check if the following assignments are really needed */
764
733
    sum= item->sum;
765
734
}
766
735
 
767
 
Item *Item_sum_sum::copy_or_same(Session* session)
 
736
Item *Item_sum_sum::copy_or_same(THD* thd)
768
737
{
769
 
  return new (session->mem_root) Item_sum_sum(session, this);
 
738
  return new (thd->mem_root) Item_sum_sum(thd, this);
770
739
}
771
740
 
772
741
 
877
846
 
878
847
/***************************************************************************/
879
848
 
 
849
#ifdef __cplusplus
 
850
extern "C" {
 
851
#endif
 
852
 
880
853
/* Declarations for auxilary C-callbacks */
881
854
 
882
855
static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
886
859
 
887
860
 
888
861
static int item_sum_distinct_walk(void *element,
889
 
                                  uint32_t ,
 
862
                                  element_count num_of_dups __attribute__((unused)),
890
863
                                  void *item)
891
864
{
892
865
  return ((Item_sum_distinct*) (item))->unique_walk_function(element);
893
866
}
894
867
 
 
868
#ifdef __cplusplus
 
869
}
 
870
#endif
 
871
 
895
872
/* Item_sum_distinct */
896
873
 
897
874
Item_sum_distinct::Item_sum_distinct(Item *item_arg)
907
884
}
908
885
 
909
886
 
910
 
Item_sum_distinct::Item_sum_distinct(Session *session, Item_sum_distinct *original)
911
 
  :Item_sum_num(session, original), val(original->val), tree(0),
 
887
Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
 
888
  :Item_sum_num(thd, original), val(original->val), tree(0),
912
889
  table_field_type(original->table_field_type)
913
890
{
914
891
  quick_group= 0;
948
925
  return &fast_decimal_traits_instance;
949
926
}
950
927
 
951
 
 
952
928
void Item_sum_distinct::fix_length_and_dec()
953
929
{
954
930
  assert(args[0]->fixed);
955
931
 
956
 
  null_value= maybe_null= true;
957
932
  table_field_type= args[0]->field_type();
958
933
 
959
934
  /* Adjust tmp table type according to the chosen aggregation type */
981
956
  case DECIMAL_RESULT:
982
957
    val.traits= Hybrid_type_traits_decimal::instance();
983
958
    if (table_field_type != DRIZZLE_TYPE_LONGLONG)
984
 
      table_field_type= DRIZZLE_TYPE_DECIMAL;
 
959
      table_field_type= DRIZZLE_TYPE_NEWDECIMAL;
985
960
    break;
986
961
  case ROW_RESULT:
987
962
  default:
991
966
}
992
967
 
993
968
 
994
 
enum Item_result Item_sum_distinct::result_type () const
995
 
{
996
 
  return val.traits->type();
997
 
}
998
 
 
999
 
 
1000
969
/**
1001
970
  @todo
1002
971
  check that the case of CHAR(0) works OK
1003
972
*/
1004
 
bool Item_sum_distinct::setup(Session *session)
 
973
bool Item_sum_distinct::setup(THD *thd)
1005
974
{
1006
 
  List<CreateField> field_list;
1007
 
  CreateField field_def;                              /* field definition */
 
975
  List<Create_field> field_list;
 
976
  Create_field field_def;                              /* field definition */
1008
977
  /* It's legal to call setup() more than once when in a subquery */
1009
978
  if (tree)
1010
979
    return(false);
1023
992
  assert(args[0]->fixed);
1024
993
 
1025
994
  field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
1026
 
                               args[0]->decimals, args[0]->maybe_null);
 
995
                               args[0]->decimals, args[0]->maybe_null,
 
996
                               args[0]->unsigned_flag);
1027
997
 
1028
 
  if (! (table= session->create_virtual_tmp_table(field_list)))
 
998
  if (! (table= create_virtual_tmp_table(thd, field_list)))
1029
999
    return(true);
1030
1000
 
1031
1001
  /* XXX: check that the case of CHAR(0) works OK */
1032
 
  tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
 
1002
  tree_key_length= table->s->reclength - table->s->null_bytes;
1033
1003
 
1034
1004
  /*
1035
1005
    Unique handles all unique elements in a tree until they can't fit
1037
1007
    simple_raw_key_cmp because the table contains numbers only; decimals
1038
1008
    are converted to binary representation as well.
1039
1009
  */
1040
 
  tree= new Unique(simple_raw_key_cmp, &tree_key_length,
1041
 
                   tree_key_length,
1042
 
                   (size_t)session->variables.max_heap_table_size);
 
1010
  tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
 
1011
                   thd->variables.max_heap_table_size);
1043
1012
 
1044
1013
  is_evaluated= false;
1045
1014
  return(tree == 0);
1048
1017
 
1049
1018
bool Item_sum_distinct::add()
1050
1019
{
1051
 
  args[0]->save_in_field(table->getField(0), false);
 
1020
  args[0]->save_in_field(table->field[0], false);
1052
1021
  is_evaluated= false;
1053
 
  if (!table->getField(0)->is_null())
 
1022
  if (!table->field[0]->is_null())
1054
1023
  {
1055
1024
    assert(tree);
1056
1025
    null_value= 0;
1058
1027
      '0' values are also stored in the tree. This doesn't matter
1059
1028
      for SUM(DISTINCT), but is important for AVG(DISTINCT)
1060
1029
    */
1061
 
    return tree->unique_add(table->getField(0)->ptr);
 
1030
    return tree->unique_add(table->field[0]->ptr);
1062
1031
  }
1063
1032
  return 0;
1064
1033
}
1066
1035
 
1067
1036
bool Item_sum_distinct::unique_walk_function(void *element)
1068
1037
{
1069
 
  memcpy(table->getField(0)->ptr, element, tree_key_length);
 
1038
  memcpy(table->field[0]->ptr, element, tree_key_length);
1070
1039
  ++count;
1071
 
  val.traits->add(&val, table->getField(0));
 
1040
  val.traits->add(&val, table->field[0]);
1072
1041
  return 0;
1073
1042
}
1074
1043
 
1110
1079
     */
1111
1080
    if (tree)
1112
1081
    {
1113
 
      table->getField(0)->set_notnull();
 
1082
      table->field[0]->set_notnull();
1114
1083
      tree->walk(item_sum_distinct_walk, (void*) this);
1115
1084
    }
1116
1085
    is_evaluated= true;
1157
1126
Item_sum_avg_distinct::fix_length_and_dec()
1158
1127
{
1159
1128
  Item_sum_distinct::fix_length_and_dec();
1160
 
  prec_increment= current_session->variables.div_precincrement;
 
1129
  prec_increment= current_thd->variables.div_precincrement;
1161
1130
  /*
1162
1131
    AVG() will divide val by count. We need to reserve digits
1163
1132
    after decimal point as the result can be fractional.
1164
1133
  */
1165
 
  decimals= min(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
 
1134
  decimals= cmin(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
1166
1135
}
1167
1136
 
1168
1137
 
1179
1148
}
1180
1149
 
1181
1150
 
1182
 
Item *Item_sum_count::copy_or_same(Session* session)
 
1151
Item *Item_sum_count::copy_or_same(THD* thd)
1183
1152
{
1184
 
  return new (session->mem_root) Item_sum_count(session, this);
 
1153
  return new (thd->mem_root) Item_sum_count(thd, this);
1185
1154
}
1186
1155
 
1187
1156
 
1220
1189
{
1221
1190
  Item_sum_sum::fix_length_and_dec();
1222
1191
  maybe_null=null_value=1;
1223
 
  prec_increment= current_session->variables.div_precincrement;
 
1192
  prec_increment= current_thd->variables.div_precincrement;
1224
1193
  if (hybrid_type == DECIMAL_RESULT)
1225
1194
  {
1226
1195
    int precision= args[0]->decimal_precision() + prec_increment;
1227
 
    decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
 
1196
    decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1228
1197
    max_length= my_decimal_precision_to_length(precision, decimals,
1229
1198
                                               unsigned_flag);
1230
 
    f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
 
1199
    f_precision= cmin(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1231
1200
    f_scale=  args[0]->decimals;
1232
1201
    dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
1233
1202
  }
1234
1203
  else {
1235
 
    decimals= min(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
 
1204
    decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
1236
1205
    max_length= args[0]->max_length + prec_increment;
1237
1206
  }
1238
1207
}
1239
1208
 
1240
1209
 
1241
 
Item *Item_sum_avg::copy_or_same(Session* session)
 
1210
Item *Item_sum_avg::copy_or_same(THD* thd)
1242
1211
{
1243
 
  return new (session->mem_root) Item_sum_avg(session, this);
 
1212
  return new (thd->mem_root) Item_sum_avg(thd, this);
1244
1213
}
1245
1214
 
1246
1215
 
1247
1216
Field *Item_sum_avg::create_tmp_field(bool group, Table *table,
1248
 
                                      uint32_t )
 
1217
                                      uint32_t convert_blob_len __attribute__((unused)))
1249
1218
{
1250
1219
  Field *field;
1251
1220
  if (group)
1257
1226
    */
1258
1227
    field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
1259
1228
                                dec_bin_size : sizeof(double)) + sizeof(int64_t),
1260
 
                               0, name, table->getMutableShare(), &my_charset_bin);
 
1229
                               0, name, table->s, &my_charset_bin);
1261
1230
  }
1262
1231
  else if (hybrid_type == DECIMAL_RESULT)
1263
 
    field= new Field_decimal(max_length, maybe_null, name,
1264
 
                             decimals, unsigned_flag);
 
1232
    field= new Field_new_decimal(max_length, maybe_null, name,
 
1233
                                 decimals, unsigned_flag);
1265
1234
  else
1266
1235
    field= new Field_double(max_length, maybe_null, name, decimals, true);
1267
1236
  if (field)
1298
1267
}
1299
1268
 
1300
1269
 
1301
 
int64_t Item_sum_avg::val_int()
1302
 
{
1303
 
  return (int64_t) rint(val_real());
1304
 
}
1305
 
 
1306
 
 
1307
1270
my_decimal *Item_sum_avg::val_decimal(my_decimal *val)
1308
1271
{
1309
1272
  my_decimal sum_buff, cnt;
1349
1312
  return sqrt(nr);
1350
1313
}
1351
1314
 
1352
 
Item *Item_sum_std::copy_or_same(Session* session)
 
1315
Item *Item_sum_std::copy_or_same(THD* thd)
1353
1316
{
1354
 
  return new (session->mem_root) Item_sum_std(session, this);
 
1317
  return new (thd->mem_root) Item_sum_std(thd, this);
1355
1318
}
1356
1319
 
1357
1320
 
1376
1339
{
1377
1340
  *count += 1;
1378
1341
 
1379
 
  if (*count == 1)
 
1342
  if (*count == 1) 
1380
1343
  {
1381
1344
    *m= nr;
1382
1345
    *s= 0;
1403
1366
}
1404
1367
 
1405
1368
 
1406
 
Item_sum_variance::Item_sum_variance(Session *session, Item_sum_variance *item):
1407
 
  Item_sum_num(session, item), hybrid_type(item->hybrid_type),
 
1369
Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item):
 
1370
  Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
1408
1371
    count(item->count), sample(item->sample),
1409
1372
    prec_increment(item->prec_increment)
1410
1373
{
1416
1379
void Item_sum_variance::fix_length_and_dec()
1417
1380
{
1418
1381
  maybe_null= null_value= 1;
1419
 
  prec_increment= current_session->variables.div_precincrement;
 
1382
  prec_increment= current_thd->variables.div_precincrement;
1420
1383
 
1421
1384
  /*
1422
1385
    According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
1423
 
    aggregate function; paragraph 7h of Syntax Rules), "the declared
 
1386
    aggregate function; paragraph 7h of Syntax Rules), "the declared 
1424
1387
    type of the result is an implementation-defined aproximate numeric
1425
1388
    type.
1426
1389
  */
1429
1392
  switch (args[0]->result_type()) {
1430
1393
  case REAL_RESULT:
1431
1394
  case STRING_RESULT:
1432
 
    decimals= min(args[0]->decimals + 4, (int)NOT_FIXED_DEC);
 
1395
    decimals= cmin(args[0]->decimals + 4, NOT_FIXED_DEC);
1433
1396
    break;
1434
1397
  case INT_RESULT:
1435
1398
  case DECIMAL_RESULT:
1436
1399
  {
1437
1400
    int precision= args[0]->decimal_precision()*2 + prec_increment;
1438
 
    decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
 
1401
    decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1439
1402
    max_length= my_decimal_precision_to_length(precision, decimals,
1440
1403
                                               unsigned_flag);
1441
1404
 
1449
1412
}
1450
1413
 
1451
1414
 
1452
 
Item *Item_sum_variance::copy_or_same(Session* session)
 
1415
Item *Item_sum_variance::copy_or_same(THD* thd)
1453
1416
{
1454
 
  return new (session->mem_root) Item_sum_variance(session, this);
 
1417
  return new (thd->mem_root) Item_sum_variance(thd, this);
1455
1418
}
1456
1419
 
1457
1420
 
1461
1424
  pass around.
1462
1425
*/
1463
1426
Field *Item_sum_variance::create_tmp_field(bool group, Table *table,
1464
 
                                           uint32_t )
 
1427
                                           uint32_t convert_blob_len __attribute__((unused)))
1465
1428
{
1466
1429
  Field *field;
1467
1430
  if (group)
1471
1434
      The easiest way is to do this is to store both value in a string
1472
1435
      and unpack on access.
1473
1436
    */
1474
 
    field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->getMutableShare(), &my_charset_bin);
 
1437
    field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->s, &my_charset_bin);
1475
1438
  }
1476
1439
  else
1477
1440
    field= new Field_double(max_length, maybe_null, name, decimals, true);
1485
1448
 
1486
1449
void Item_sum_variance::clear()
1487
1450
{
1488
 
  count= 0;
 
1451
  count= 0; 
1489
1452
}
1490
1453
 
1491
1454
bool Item_sum_variance::add()
1492
1455
{
1493
 
  /*
 
1456
  /* 
1494
1457
    Why use a temporary variable?  We don't know if it is null until we
1495
1458
    evaluate it, which has the side-effect of setting null_value .
1496
1459
  */
1497
1460
  double nr= args[0]->val_real();
1498
 
 
 
1461
  
1499
1462
  if (!args[0]->null_value)
1500
1463
    variance_fp_recurrence_next(&recurrence_m, &recurrence_s, &count, nr);
1501
1464
  return 0;
1526
1489
}
1527
1490
 
1528
1491
 
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
1492
my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf)
1537
1493
{
1538
1494
  assert(fixed == 1);
1736
1692
}
1737
1693
 
1738
1694
 
1739
 
Item *Item_sum_min::copy_or_same(Session* session)
 
1695
Item *Item_sum_min::copy_or_same(THD* thd)
1740
1696
{
1741
 
  return new (session->mem_root) Item_sum_min(session, this);
 
1697
  return new (thd->mem_root) Item_sum_min(thd, this);
1742
1698
}
1743
1699
 
1744
1700
 
1760
1716
  {
1761
1717
    int64_t nr=args[0]->val_int();
1762
1718
    if (!args[0]->null_value && (null_value ||
1763
 
                                 (unsigned_flag &&
 
1719
                                 (unsigned_flag && 
1764
1720
                                  (uint64_t) nr < (uint64_t) sum_int) ||
1765
1721
                                 (!unsigned_flag && nr < sum_int)))
1766
1722
    {
1800
1756
}
1801
1757
 
1802
1758
 
1803
 
Item *Item_sum_max::copy_or_same(Session* session)
 
1759
Item *Item_sum_max::copy_or_same(THD* thd)
1804
1760
{
1805
 
  return new (session->mem_root) Item_sum_max(session, this);
 
1761
  return new (thd->mem_root) Item_sum_max(thd, this);
1806
1762
}
1807
1763
 
1808
1764
 
1824
1780
  {
1825
1781
    int64_t nr=args[0]->val_int();
1826
1782
    if (!args[0]->null_value && (null_value ||
1827
 
                                 (unsigned_flag &&
 
1783
                                 (unsigned_flag && 
1828
1784
                                  (uint64_t) nr > (uint64_t) sum_int) ||
1829
1785
                                 (!unsigned_flag && nr > sum_int)))
1830
1786
    {
1878
1834
  bits= reset_bits;
1879
1835
}
1880
1836
 
1881
 
Item *Item_sum_or::copy_or_same(Session* session)
 
1837
Item *Item_sum_or::copy_or_same(THD* thd)
1882
1838
{
1883
 
  return new (session->mem_root) Item_sum_or(session, this);
 
1839
  return new (thd->mem_root) Item_sum_or(thd, this);
1884
1840
}
1885
1841
 
1886
1842
 
1892
1848
  return 0;
1893
1849
}
1894
1850
 
1895
 
Item *Item_sum_xor::copy_or_same(Session* session)
 
1851
Item *Item_sum_xor::copy_or_same(THD* thd)
1896
1852
{
1897
 
  return new (session->mem_root) Item_sum_xor(session, this);
 
1853
  return new (thd->mem_root) Item_sum_xor(thd, this);
1898
1854
}
1899
1855
 
1900
1856
 
1906
1862
  return 0;
1907
1863
}
1908
1864
 
1909
 
Item *Item_sum_and::copy_or_same(Session* session)
 
1865
Item *Item_sum_and::copy_or_same(THD* thd)
1910
1866
{
1911
 
  return new (session->mem_root) Item_sum_and(session, this);
 
1867
  return new (thd->mem_root) Item_sum_and(thd, this);
1912
1868
}
1913
1869
 
1914
1870
 
2449
2405
}
2450
2406
 
2451
2407
 
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
2408
double Item_variance_field::val_real()
2460
2409
{
2461
2410
  // fix_fields() never calls for this Item
2494
2443
int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
2495
2444
{
2496
2445
  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();
 
2446
  Field **field    = item->table->field;
 
2447
  Field **field_end= field + item->table->s->fields;
2499
2448
  uint32_t *lengths=item->field_lengths;
2500
2449
  for (; field < field_end; ++field)
2501
2450
  {
2510
2459
  return 0;
2511
2460
}
2512
2461
 
2513
 
static int count_distinct_walk(void *,
2514
 
                               uint32_t ,
 
2462
#ifdef __cplusplus
 
2463
extern "C" {
 
2464
#endif
 
2465
 
 
2466
static int count_distinct_walk(void *elem __attribute__((unused)),
 
2467
                               element_count count __attribute__((unused)),
2515
2468
                               void *arg)
2516
2469
{
2517
2470
  (*((uint64_t*)arg))++;
2518
2471
  return 0;
2519
2472
}
2520
2473
 
 
2474
#ifdef __cplusplus
 
2475
}
 
2476
#endif
 
2477
 
 
2478
 
 
2479
 
2521
2480
void Item_sum_count_distinct::cleanup()
2522
2481
{
2523
2482
  Item_sum_int::cleanup();
2535
2494
    is_evaluated= false;
2536
2495
    if (table)
2537
2496
    {
 
2497
      table->free_tmp_table(table->in_use);
2538
2498
      table= 0;
2539
2499
    }
2540
2500
    delete tmp_table_param;
2568
2528
}
2569
2529
 
2570
2530
 
2571
 
bool Item_sum_count_distinct::setup(Session *session)
 
2531
bool Item_sum_count_distinct::setup(THD *thd)
2572
2532
{
2573
2533
  List<Item> list;
2574
 
  Select_Lex *select_lex= session->lex->current_select;
 
2534
  SELECT_LEX *select_lex= thd->lex->current_select;
2575
2535
 
2576
2536
  /*
2577
2537
    Setup can be called twice for ROLLUP items. This is a bug.
2581
2541
  if (tree || table || tmp_table_param)
2582
2542
    return false;
2583
2543
 
2584
 
  if (!(tmp_table_param= new Tmp_Table_Param))
 
2544
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
2585
2545
    return true;
2586
2546
 
2587
2547
  /* Create a table with an unique key over all parameters */
2599
2559
  tmp_table_param->force_copy_fields= force_copy_fields;
2600
2560
  assert(table == 0);
2601
2561
 
2602
 
  if (!(table= create_tmp_table(session, tmp_table_param, list, (order_st*) 0, 1,
 
2562
  if (!(table= create_tmp_table(thd, tmp_table_param, list, (order_st*) 0, 1,
2603
2563
                                0,
2604
 
                                (select_lex->options | session->options),
 
2564
                                (select_lex->options | thd->options),
2605
2565
                                HA_POS_ERROR, (char*)"")))
2606
 
  {
2607
2566
    return true;
2608
 
  }
2609
 
  table->cursor->extra(HA_EXTRA_NO_ROWS);               // Don't update rows
 
2567
  table->file->extra(HA_EXTRA_NO_ROWS);         // Don't update rows
2610
2568
  table->no_rows=1;
2611
2569
 
2612
 
  if (table->getShare()->db_type() == heap_engine)
 
2570
  if (table->s->db_type() == heap_hton)
2613
2571
  {
2614
2572
    /*
2615
2573
      No blobs, otherwise it would have been MyISAM: set up a compare
2617
2575
    */
2618
2576
    qsort_cmp2 compare_key;
2619
2577
    void* cmp_arg;
2620
 
    Field **field= table->getFields();
2621
 
    Field **field_end= field + table->getShare()->sizeFields();
 
2578
    Field **field= table->field;
 
2579
    Field **field_end= field + table->s->fields;
2622
2580
    bool all_binary= true;
2623
2581
 
2624
2582
    for (tree_key_length= 0; field < field_end; ++field)
2639
2597
    }
2640
2598
    else
2641
2599
    {
2642
 
      if (table->getShare()->sizeFields() == 1)
 
2600
      if (table->s->fields == 1)
2643
2601
      {
2644
2602
        /*
2645
2603
          If we have only one field, which is the most common use of
2648
2606
          about other fields.
2649
2607
        */
2650
2608
        compare_key= (qsort_cmp2) simple_str_key_cmp;
2651
 
        cmp_arg= (void*) table->getField(0);
 
2609
        cmp_arg= (void*) table->field[0];
2652
2610
        /* tree_key_length has been set already */
2653
2611
      }
2654
2612
      else
2656
2614
        uint32_t *length;
2657
2615
        compare_key= (qsort_cmp2) composite_key_cmp;
2658
2616
        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();
 
2617
        field_lengths= (uint32_t*) thd->alloc(table->s->fields * sizeof(uint32_t));
 
2618
        for (tree_key_length= 0, length= field_lengths, field= table->field;
2661
2619
             field < field_end; ++field, ++length)
2662
2620
        {
2663
2621
          *length= (*field)->pack_length();
2667
2625
    }
2668
2626
    assert(tree == 0);
2669
2627
    tree= new Unique(compare_key, cmp_arg, tree_key_length,
2670
 
                     (size_t)session->variables.max_heap_table_size);
 
2628
                     thd->variables.max_heap_table_size);
2671
2629
    /*
2672
2630
      The only time tree_key_length could be 0 is if someone does
2673
2631
      count(distinct) on a char(0) field - stupid thing to do,
2682
2640
}
2683
2641
 
2684
2642
 
2685
 
Item *Item_sum_count_distinct::copy_or_same(Session* session)
 
2643
Item *Item_sum_count_distinct::copy_or_same(THD* thd) 
2686
2644
{
2687
 
  return new (session->mem_root) Item_sum_count_distinct(session, this);
 
2645
  return new (thd->mem_root) Item_sum_count_distinct(thd, this);
2688
2646
}
2689
2647
 
2690
2648
 
2698
2656
  }
2699
2657
  else if (table)
2700
2658
  {
2701
 
    table->cursor->extra(HA_EXTRA_NO_CACHE);
2702
 
    table->cursor->ha_delete_all_rows();
2703
 
    table->cursor->extra(HA_EXTRA_WRITE_CACHE);
 
2659
    table->file->extra(HA_EXTRA_NO_CACHE);
 
2660
    table->file->ha_delete_all_rows();
 
2661
    table->file->extra(HA_EXTRA_WRITE_CACHE);
2704
2662
  }
2705
2663
}
2706
2664
 
2712
2670
  copy_fields(tmp_table_param);
2713
2671
  copy_funcs(tmp_table_param->items_to_copy);
2714
2672
 
2715
 
  for (Field **field= table->getFields() ; *field ; field++)
2716
 
  {
 
2673
  for (Field **field=table->field ; *field ; field++)
2717
2674
    if ((*field)->is_real_null(0))
2718
 
    {
2719
2675
      return 0;                                 // Don't count NULL
2720
 
    }
2721
 
  }
2722
2676
 
2723
2677
  is_evaluated= false;
2724
2678
  if (tree)
2729
2683
      bloat the tree without providing any valuable info. Besides,
2730
2684
      key_length used to initialize the tree didn't include space for them.
2731
2685
    */
2732
 
    return tree->unique_add(table->record[0] + table->getShare()->null_bytes);
 
2686
    return tree->unique_add(table->record[0] + table->s->null_bytes);
2733
2687
  }
2734
 
  if ((error= table->cursor->insertRecord(table->record[0])) &&
2735
 
      table->cursor->is_fatal_error(error, HA_CHECK_DUP))
 
2688
  if ((error= table->file->ha_write_row(table->record[0])) &&
 
2689
      table->file->is_fatal_error(error, HA_CHECK_DUP))
2736
2690
    return true;
2737
2691
  return false;
2738
2692
}
2757
2711
    return (int64_t) count;
2758
2712
  }
2759
2713
 
2760
 
  error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
2714
  error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2761
2715
 
2762
2716
  if(error)
2763
2717
  {
2764
 
    table->print_error(error, MYF(0));
 
2718
    table->file->print_error(error, MYF(0));
2765
2719
  }
2766
2720
 
2767
 
  return table->cursor->stats.records;
 
2721
  return table->file->stats.records;
2768
2722
}
2769
2723
 
2770
2724
/*****************************************************************************
2781
2735
*****************************************************************************/
2782
2736
 
2783
2737
 
2784
 
/**
 
2738
/** 
2785
2739
  Compares the values for fields in expr list of GROUP_CONCAT.
2786
2740
  @note
2787
 
 
 
2741
       
2788
2742
     GROUP_CONCAT([DISTINCT] expr [,expr ...]
2789
2743
              [order_st BY {unsigned_integer | col_name | expr}
2790
2744
                  [ASC | DESC] [,col_name ...]]
2791
2745
              [SEPARATOR str_val])
2792
 
 
 
2746
 
2793
2747
  @return
2794
 
  @retval -1 : key1 < key2
 
2748
  @retval -1 : key1 < key2 
2795
2749
  @retval  0 : key1 = key2
2796
 
  @retval  1 : key1 > key2
 
2750
  @retval  1 : key1 > key2 
2797
2751
*/
2798
2752
 
2799
 
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
 
2753
int group_concat_key_cmp_with_distinct(void* arg, const void* key1, 
2800
2754
                                       const void* key2)
2801
2755
{
2802
2756
  Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
2805
2759
  for (uint32_t i= 0; i < item_func->arg_count_field; i++)
2806
2760
  {
2807
2761
    Item *item= item_func->args[i];
2808
 
    /*
 
2762
    /* 
2809
2763
      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.
 
2764
      or it is an item over a const table. 
2811
2765
    */
2812
2766
    if (item->const_item())
2813
2767
      continue;
2818
2772
    */
2819
2773
    Field *field= item->get_tmp_table_field();
2820
2774
    int res;
2821
 
    uint32_t offset= field->offset(field->getTable()->record[0])-table->getShare()->null_bytes;
 
2775
    uint32_t offset= field->offset(field->table->record[0])-table->s->null_bytes;
2822
2776
    if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2823
2777
      return res;
2824
2778
  }
2827
2781
 
2828
2782
 
2829
2783
/**
2830
 
  function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
 
2784
  function of sort for syntax: GROUP_CONCAT(expr,... order_st BY col,... )
2831
2785
*/
2832
2786
 
2833
 
int group_concat_key_cmp_with_order(void* arg, const void* key1,
 
2787
int group_concat_key_cmp_with_order(void* arg, const void* key1, 
2834
2788
                                    const void* key2)
2835
2789
{
2836
2790
  Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2848
2802
      the temporary table, not the original field
2849
2803
    */
2850
2804
    Field *field= item->get_tmp_table_field();
2851
 
    /*
 
2805
    /* 
2852
2806
      If item is a const item then either get_tp_table_field returns 0
2853
 
      or it is an item over a const table.
 
2807
      or it is an item over a const table. 
2854
2808
    */
2855
2809
    if (field && !item->const_item())
2856
2810
    {
2857
2811
      int res;
2858
 
      uint32_t offset= (field->offset(field->getTable()->record[0]) -
2859
 
                    table->getShare()->null_bytes);
 
2812
      uint32_t offset= (field->offset(field->table->record[0]) -
 
2813
                    table->s->null_bytes);
2860
2814
      if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2861
2815
        return (*order_item)->asc ? res : -res;
2862
2816
    }
2874
2828
  Append data from current leaf to item->result.
2875
2829
*/
2876
2830
 
2877
 
int dump_leaf_key(unsigned char* key, uint32_t ,
 
2831
int dump_leaf_key(unsigned char* key, element_count count __attribute__((unused)),
2878
2832
                  Item_func_group_concat *item)
2879
2833
{
2880
2834
  Table *table= item->table;
2881
 
  String tmp((char *)table->getUpdateRecord(), table->getShare()->getRecordLength(),
 
2835
  String tmp((char *)table->record[1], table->s->reclength,
2882
2836
             default_charset_info);
2883
2837
  String tmp2;
2884
2838
  String *result= &item->result;
2905
2859
        because it contains both order and arg list fields.
2906
2860
      */
2907
2861
      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());
 
2862
      uint32_t offset= (field->offset(field->table->record[0]) -
 
2863
                    table->s->null_bytes);
 
2864
      assert(offset < table->s->reclength);
2911
2865
      res= field->val_str(&tmp, key + offset);
2912
2866
    }
2913
2867
    else
2956
2910
                       bool distinct_arg, List<Item> *select_list,
2957
2911
                       SQL_LIST *order_list, String *separator_arg)
2958
2912
  :tmp_table_param(0), warning(0),
2959
 
   separator(separator_arg), tree(NULL), unique_filter(NULL), table(0),
 
2913
   separator(separator_arg), tree(0), unique_filter(NULL), table(0),
2960
2914
   order(0), context(context_arg),
2961
2915
   arg_count_order(order_list ? order_list->elements : 0),
2962
2916
   arg_count_field(select_list->elements),
2977
2931
           (for possible order items in temporare tables)
2978
2932
    order - arg_count_order
2979
2933
  */
2980
 
  if (!(args= (Item**) memory::sql_alloc(sizeof(Item*) * arg_count +
 
2934
  if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
2981
2935
                                 sizeof(order_st*)*arg_count_order)))
2982
2936
    return;
2983
2937
 
3004
2958
}
3005
2959
 
3006
2960
 
3007
 
Item_func_group_concat::Item_func_group_concat(Session *session,
 
2961
Item_func_group_concat::Item_func_group_concat(THD *thd,
3008
2962
                                               Item_func_group_concat *item)
3009
 
  :Item_sum(session, item),
 
2963
  :Item_sum(thd, item),
3010
2964
  tmp_table_param(item->tmp_table_param),
3011
2965
  warning(item->warning),
3012
2966
  separator(item->separator),
3038
2992
  if (warning)
3039
2993
  {
3040
2994
    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);
 
2995
    sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
 
2996
    warning->set_msg(current_thd, warn_buff);
3043
2997
    warning= 0;
3044
2998
  }
3045
2999
 
3053
3007
    tmp_table_param= 0;
3054
3008
    if (table)
3055
3009
    {
3056
 
      Session *session= table->in_use;
 
3010
      THD *thd= table->in_use;
 
3011
      table->free_tmp_table(thd);
3057
3012
      table= 0;
3058
3013
      if (tree)
3059
3014
      {
3068
3023
      if (warning)
3069
3024
      {
3070
3025
        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);
 
3026
        sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
 
3027
        warning->set_msg(thd, warn_buff);
3073
3028
        warning= 0;
3074
3029
      }
3075
3030
    }
3079
3034
}
3080
3035
 
3081
3036
 
3082
 
Item *Item_func_group_concat::copy_or_same(Session* session)
 
3037
Item *Item_func_group_concat::copy_or_same(THD* thd)
3083
3038
{
3084
 
  return new (session->mem_root) Item_func_group_concat(session, this);
 
3039
  return new (thd->mem_root) Item_func_group_concat(thd, this);
3085
3040
}
3086
3041
 
3087
3042
 
3121
3076
  null_value= false;
3122
3077
  bool row_eligible= true;
3123
3078
 
3124
 
  if (distinct)
 
3079
  if (distinct) 
3125
3080
  {
3126
3081
    /* Filter out duplicate rows. */
3127
3082
    uint32_t count= unique_filter->elements_in_tree();
3128
 
    unique_filter->unique_add(table->record[0] + table->getShare()->null_bytes);
 
3083
    unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3129
3084
    if (count == unique_filter->elements_in_tree())
3130
3085
      row_eligible= false;
3131
3086
  }
3132
3087
 
3133
3088
  TREE_ELEMENT *el= 0;                          // Only for safety
3134
3089
  if (row_eligible && tree)
3135
 
    el= tree_insert(tree, table->record[0] + table->getShare()->null_bytes, 0,
 
3090
    el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3136
3091
                    tree->custom_arg);
3137
3092
  /*
3138
3093
    If the row is not a duplicate (el->count == 1)
3141
3096
  */
3142
3097
  if (row_eligible && !warning_for_row &&
3143
3098
      (!tree || (el->count == 1 && distinct && !arg_count_order)))
3144
 
    dump_leaf_key(table->record[0] + table->getShare()->null_bytes, 1, this);
 
3099
    dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3145
3100
 
3146
3101
  return 0;
3147
3102
}
3148
3103
 
3149
3104
 
3150
3105
bool
3151
 
Item_func_group_concat::fix_fields(Session *session, Item **ref)
 
3106
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3152
3107
{
3153
3108
  uint32_t i;                       /* for loop variable */
3154
3109
  assert(fixed == 0);
3155
3110
 
3156
 
  if (init_sum_func_check(session))
 
3111
  if (init_sum_func_check(thd))
3157
3112
    return true;
3158
3113
 
3159
3114
  maybe_null= 1;
3165
3120
  for (i=0 ; i < arg_count ; i++)
3166
3121
  {
3167
3122
    if ((!args[i]->fixed &&
3168
 
         args[i]->fix_fields(session, args + i)) ||
 
3123
         args[i]->fix_fields(thd, args + i)) ||
3169
3124
        args[i]->check_cols(1))
3170
3125
      return true;
3171
3126
  }
3180
3135
  result.set_charset(collation.collation);
3181
3136
  result_field= 0;
3182
3137
  null_value= 1;
3183
 
  max_length= (size_t)session->variables.group_concat_max_len;
3184
 
 
3185
 
  if (check_sum_func(session, ref))
 
3138
  max_length= thd->variables.group_concat_max_len;
 
3139
 
 
3140
  uint32_t offset;
 
3141
  if (separator->needs_conversion(separator->length(), separator->charset(),
 
3142
                                  collation.collation, &offset))
 
3143
  {
 
3144
    uint32_t buflen= collation.collation->mbmaxlen * separator->length();
 
3145
    uint32_t errors, conv_length;
 
3146
    char *buf;
 
3147
    String *new_separator;
 
3148
 
 
3149
    if (!(buf= (char*) thd->alloc(buflen)) ||
 
3150
        !(new_separator= new(thd->mem_root)
 
3151
                           String(buf, buflen, collation.collation)))
 
3152
      return true;
 
3153
    
 
3154
    conv_length= copy_and_convert(buf, buflen, collation.collation,
 
3155
                                  separator->ptr(), separator->length(),
 
3156
                                  separator->charset(), &errors);
 
3157
    new_separator->length(conv_length);
 
3158
    separator= new_separator;
 
3159
  }
 
3160
 
 
3161
  if (check_sum_func(thd, ref))
3186
3162
    return true;
3187
3163
 
3188
3164
  fixed= 1;
3190
3166
}
3191
3167
 
3192
3168
 
3193
 
bool Item_func_group_concat::setup(Session *session)
 
3169
bool Item_func_group_concat::setup(THD *thd)
3194
3170
{
3195
3171
  List<Item> list;
3196
 
  Select_Lex *select_lex= session->lex->current_select;
 
3172
  SELECT_LEX *select_lex= thd->lex->current_select;
3197
3173
 
3198
3174
  /*
3199
3175
    Currently setup() can be called twice. Please add
3202
3178
  if (table || tree)
3203
3179
    return(false);
3204
3180
 
3205
 
  if (!(tmp_table_param= new Tmp_Table_Param))
 
3181
  if (!(tmp_table_param= new TMP_TABLE_PARAM))
3206
3182
    return(true);
3207
3183
 
3208
3184
  /* We'll convert all blobs to varchar fields in the temporary table */
3233
3209
    tmp table columns.
3234
3210
  */
3235
3211
  if (arg_count_order &&
3236
 
      setup_order(session, args, context->table_list, list, all_fields, *order))
 
3212
      setup_order(thd, args, context->table_list, list, all_fields, *order))
3237
3213
    return(true);
3238
3214
 
3239
3215
  count_field_types(select_lex, tmp_table_param, all_fields, 0);
3243
3219
  {
3244
3220
    /*
3245
3221
      Currently we have to force conversion of BLOB values to VARCHAR's
3246
 
      if we are to store them in TREE objects used for ORDER BY and
 
3222
      if we are to store them in TREE objects used for order_st BY and
3247
3223
      DISTINCT. This leads to truncation if the BLOB's size exceeds
3248
3224
      Field_varstring::MAX_SIZE.
3249
3225
    */
3250
 
    set_if_smaller(tmp_table_param->convert_blob_length,
 
3226
    set_if_smaller(tmp_table_param->convert_blob_length, 
3251
3227
                   Field_varstring::MAX_SIZE);
3252
3228
  }
3253
3229
 
3255
3231
    We have to create a temporary table to get descriptions of fields
3256
3232
    (types, sizes and so on).
3257
3233
 
3258
 
    Note that in the table, we first have the ORDER BY fields, then the
 
3234
    Note that in the table, we first have the order_st BY fields, then the
3259
3235
    field list.
3260
3236
  */
3261
 
  if (!(table= create_tmp_table(session, tmp_table_param, all_fields,
 
3237
  if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
3262
3238
                                (order_st*) 0, 0, true,
3263
 
                                (select_lex->options | session->options),
 
3239
                                (select_lex->options | thd->options),
3264
3240
                                HA_POS_ERROR, (char*) "")))
3265
 
  {
3266
3241
    return(true);
3267
 
  }
3268
 
 
3269
 
  table->cursor->extra(HA_EXTRA_NO_ROWS);
 
3242
  table->file->extra(HA_EXTRA_NO_ROWS);
3270
3243
  table->no_rows= 1;
3271
3244
 
3272
3245
  /*
3274
3247
     Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3275
3248
     the row is not added to the result.
3276
3249
  */
3277
 
  uint32_t tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
 
3250
  uint32_t tree_key_length= table->s->reclength - table->s->null_bytes;
3278
3251
 
3279
3252
  if (arg_count_order)
3280
3253
  {
3281
3254
    tree= &tree_base;
3282
3255
    /*
3283
3256
      Create a tree for sorting. The tree is used to sort (according to the
3284
 
      syntax of this function). If there is no ORDER BY clause, we don't
 
3257
      syntax of this function). If there is no order_st BY clause, we don't
3285
3258
      create this tree.
3286
3259
    */
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);
 
3260
    init_tree(tree, (uint) cmin(thd->variables.max_heap_table_size,
 
3261
                               thd->variables.sortbuff_size/16), 0,
 
3262
              tree_key_length, 
 
3263
              group_concat_key_cmp_with_order , 0, NULL, (void*) this);
3292
3264
  }
3293
3265
 
3294
3266
  if (distinct)
3295
3267
    unique_filter= new Unique(group_concat_key_cmp_with_distinct,
3296
3268
                              (void*)this,
3297
3269
                              tree_key_length,
3298
 
                              (size_t)session->variables.max_heap_table_size);
3299
 
 
 
3270
                              thd->variables.max_heap_table_size);
 
3271
  
3300
3272
  return(false);
3301
3273
}
3302
3274
 
3312
3284
  tree= 0;
3313
3285
}
3314
3286
 
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* )
 
3287
 
 
3288
String* Item_func_group_concat::val_str(String* str __attribute__((unused)))
3333
3289
{
3334
3290
  assert(fixed == 1);
3335
3291
  if (null_value)
3387
3343
Item_func_group_concat::~Item_func_group_concat()
3388
3344
{
3389
3345
  if (!original && unique_filter)
3390
 
    delete unique_filter;
 
3346
    delete unique_filter;    
3391
3347
}
3392
 
 
3393
 
} /* namespace drizzled */