~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/sum.cc

new date/time additions

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>
 
23
#include "config.h"
24
24
#include <cstdio>
25
25
#include <math.h>
26
26
#include <drizzled/sql_select.h>
29
29
#include <drizzled/hybrid_type_traits_integer.h>
30
30
#include <drizzled/hybrid_type_traits_decimal.h>
31
31
#include <drizzled/sql_base.h>
32
 
#include <drizzled/session.h>
33
32
 
34
33
#include <drizzled/item/sum.h>
35
34
#include <drizzled/field/decimal.h>
37
36
#include <drizzled/field/int64.h>
38
37
#include <drizzled/field/date.h>
39
38
#include <drizzled/field/datetime.h>
40
 
#include <drizzled/unique.h>
41
 
 
42
 
#include <drizzled/type/decimal.h>
43
 
 
44
 
#include <drizzled/internal/m_string.h>
 
39
 
 
40
#include "drizzled/internal/m_string.h"
45
41
 
46
42
#include <algorithm>
47
43
 
50
46
namespace drizzled
51
47
{
52
48
 
 
49
extern type::Decimal decimal_zero;
53
50
extern plugin::StorageEngine *heap_engine;
54
51
 
55
52
/**
76
73
 
77
74
bool Item_sum::init_sum_func_check(Session *session)
78
75
{
79
 
  if (!session->getLex()->allow_sum_func)
 
76
  if (!session->lex->allow_sum_func)
80
77
  {
81
78
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
82
79
               MYF(0));
83
80
    return true;
84
81
  }
85
82
  /* Set a reference to the nesting set function if there is  any */
86
 
  in_sum_func= session->getLex()->in_sum_func;
 
83
  in_sum_func= session->lex->in_sum_func;
87
84
  /* Save a pointer to object to be used in items for nested set functions */
88
 
  session->getLex()->in_sum_func= this;
89
 
  nest_level= session->getLex()->current_select->nest_level;
 
85
  session->lex->in_sum_func= this;
 
86
  nest_level= session->lex->current_select->nest_level;
90
87
  ref_by= 0;
91
88
  aggr_level= -1;
92
89
  aggr_sel= NULL;
93
90
  max_arg_level= -1;
94
91
  max_sum_func_level= -1;
95
 
  outer_fields.clear();
 
92
  outer_fields.empty();
96
93
  return false;
97
94
}
98
95
 
148
145
bool Item_sum::check_sum_func(Session *session, Item **ref)
149
146
{
150
147
  bool invalid= false;
151
 
  nesting_map allow_sum_func= session->getLex()->allow_sum_func;
 
148
  nesting_map allow_sum_func= session->lex->allow_sum_func;
152
149
  /*
153
150
    The value of max_arg_level is updated if an argument of the set function
154
151
    contains a column reference resolved  against a subquery whose level is
181
178
  if (!invalid && aggr_level < 0)
182
179
  {
183
180
    aggr_level= nest_level;
184
 
    aggr_sel= session->getLex()->current_select;
 
181
    aggr_sel= session->lex->current_select;
185
182
  }
186
183
  /*
187
184
    By this moment we either found a subquery where the set function is
256
253
        select the field belongs to. If there are some then an error is
257
254
        raised.
258
255
    */
259
 
    List<Item_field>::iterator of(outer_fields.begin());
 
256
    List_iterator<Item_field> of(outer_fields);
260
257
    while ((field= of++))
261
258
    {
262
259
      Select_Lex *sel= field->cached_table->select_lex;
287
284
  }
288
285
  aggr_sel->full_group_by_flag.set(SUM_FUNC_USED);
289
286
  update_used_tables();
290
 
  session->getLex()->in_sum_func= in_sum_func;
 
287
  session->lex->in_sum_func= in_sum_func;
291
288
  return false;
292
289
}
293
290
 
319
316
bool Item_sum::register_sum_func(Session *session, Item **ref)
320
317
{
321
318
  Select_Lex *sl;
322
 
  nesting_map allow_sum_func= session->getLex()->allow_sum_func;
323
 
  for (sl= session->getLex()->current_select->master_unit()->outer_select() ;
 
319
  nesting_map allow_sum_func= session->lex->allow_sum_func;
 
320
  for (sl= session->lex->current_select->master_unit()->outer_select() ;
324
321
       sl && sl->nest_level > max_arg_level;
325
322
       sl= sl->master_unit()->outer_select() )
326
323
  {
371
368
      with_sum_func being set for an Select_Lex means that this Select_Lex
372
369
      has aggregate functions directly referenced (i.e. not through a sub-select).
373
370
    */
374
 
    for (sl= session->getLex()->current_select;
 
371
    for (sl= session->lex->current_select;
375
372
         sl && sl != aggr_sel && sl->master_unit()->item;
376
373
         sl= sl->master_unit()->outer_select() )
377
374
      sl->master_unit()->item->with_sum_func= 1;
378
375
  }
379
 
  session->getLex()->current_select->mark_as_dependent(aggr_sel);
 
376
  session->lex->current_select->mark_as_dependent(aggr_sel);
380
377
  return false;
381
378
}
382
379
 
387
384
  if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
388
385
  {
389
386
    uint32_t i=0;
390
 
    List<Item>::iterator li(list.begin());
 
387
    List_iterator_fast<Item> li(list);
391
388
    Item *item;
392
389
 
393
390
    while ((item=li++))
396
393
    }
397
394
  }
398
395
  mark_as_sum_func();
399
 
  list.clear();                                 // Fields are used
 
396
  list.empty();                                 // Fields are used
400
397
}
401
398
 
402
399
 
414
411
  if (arg_count <= 2)
415
412
    args=tmp_args;
416
413
  else
417
 
    if (!(args= (Item**) session->getMemRoot()->allocate(sizeof(Item*)*arg_count)))
 
414
    if (!(args= (Item**) session->alloc(sizeof(Item*)*arg_count)))
418
415
      return;
419
416
  memcpy(args, item->args, sizeof(Item*)*arg_count);
420
417
}
422
419
 
423
420
void Item_sum::mark_as_sum_func()
424
421
{
425
 
  Select_Lex *cur_select= getSession().getLex()->current_select;
 
422
  Select_Lex *cur_select= current_session->lex->current_select;
426
423
  cur_select->n_sum_items++;
427
424
  cur_select->with_sum_func= 1;
428
425
  with_sum_func= 1;
726
723
  {
727
724
    field= ((Item_field*) args[0])->field;
728
725
 
729
 
    if ((field= create_tmp_field_from_field(&getSession(), field, name, table,
 
726
    if ((field= create_tmp_field_from_field(current_session, field, name, table,
730
727
                                            NULL, convert_blob_length)))
731
728
      field->flags&= ~NOT_NULL_FLAG;
732
729
    return field;
738
735
  */
739
736
  switch (args[0]->field_type()) {
740
737
  case DRIZZLE_TYPE_DATE:
741
 
    field= new Field_date(maybe_null, name);
 
738
    field= new Field_date(maybe_null, name, collation.collation);
742
739
    break;
743
740
  case DRIZZLE_TYPE_TIMESTAMP:
744
741
  case DRIZZLE_TYPE_DATETIME:
745
 
    field= new Field_datetime(maybe_null, name);
 
742
    field= new Field_datetime(maybe_null, name, collation.collation);
746
743
    break;
747
744
  default:
748
745
    return Item_sum::create_tmp_field(group, table, convert_blob_length);
749
746
  }
750
 
 
751
747
  if (field)
752
748
    field->init(table);
753
 
 
754
749
  return field;
755
750
}
756
751
 
1167
1162
Item_sum_avg_distinct::fix_length_and_dec()
1168
1163
{
1169
1164
  Item_sum_distinct::fix_length_and_dec();
1170
 
  prec_increment= getSession().variables.div_precincrement;
 
1165
  prec_increment= current_session->variables.div_precincrement;
1171
1166
  /*
1172
1167
    AVG() will divide val by count. We need to reserve digits
1173
1168
    after decimal point as the result can be fractional.
1230
1225
{
1231
1226
  Item_sum_sum::fix_length_and_dec();
1232
1227
  maybe_null=null_value=1;
1233
 
  prec_increment= getSession().variables.div_precincrement;
1234
 
 
 
1228
  prec_increment= current_session->variables.div_precincrement;
1235
1229
  if (hybrid_type == DECIMAL_RESULT)
1236
1230
  {
1237
1231
    int precision= args[0]->decimal_precision() + prec_increment;
1428
1422
void Item_sum_variance::fix_length_and_dec()
1429
1423
{
1430
1424
  maybe_null= null_value= 1;
1431
 
  prec_increment= getSession().variables.div_precincrement;
 
1425
  prec_increment= current_session->variables.div_precincrement;
1432
1426
 
1433
1427
  /*
1434
1428
    According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
1713
1707
    str->set_real(sum,decimals, &my_charset_bin);
1714
1708
    break;
1715
1709
  case DECIMAL_RESULT:
1716
 
    class_decimal2string(&sum_dec, 0, str);
 
1710
    class_decimal2string(E_DEC_FATAL_ERROR, &sum_dec, 0, 0, 0, str);
1717
1711
    return str;
1718
1712
  case INT_RESULT:
1719
1713
    str->set_int(sum_int, unsigned_flag, &my_charset_bin);
2584
2578
bool Item_sum_count_distinct::setup(Session *session)
2585
2579
{
2586
2580
  List<Item> list;
2587
 
  Select_Lex *select_lex= session->getLex()->current_select;
 
2581
  Select_Lex *select_lex= session->lex->current_select;
2588
2582
 
2589
2583
  /*
2590
2584
    Setup can be called twice for ROLLUP items. This is a bug.
2669
2663
        uint32_t *length;
2670
2664
        compare_key= (qsort_cmp2) composite_key_cmp;
2671
2665
        cmp_arg= (void*) this;
2672
 
        field_lengths= (uint32_t*) session->getMemRoot()->allocate(table->getShare()->sizeFields() * sizeof(uint32_t));
 
2666
        field_lengths= (uint32_t*) session->alloc(table->getShare()->sizeFields() * sizeof(uint32_t));
2673
2667
        for (tree_key_length= 0, length= field_lengths, field= table->getFields();
2674
2668
             field < field_end; ++field, ++length)
2675
2669
        {
2998
2992
  order= (Order**)(args + arg_count);
2999
2993
 
3000
2994
  /* fill args items of show and sort */
3001
 
  List<Item>::iterator li(select_list->begin());
 
2995
  List_iterator_fast<Item> li(*select_list);
3002
2996
 
3003
2997
  for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
3004
2998
    *arg_ptr= item_select;
3053
3047
  {
3054
3048
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
3055
3049
    snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3056
 
    warning->set_msg(&getSession(), warn_buff);
 
3050
    warning->set_msg(current_session, warn_buff);
3057
3051
    warning= 0;
3058
3052
  }
3059
3053
 
3208
3202
bool Item_func_group_concat::setup(Session *session)
3209
3203
{
3210
3204
  List<Item> list;
3211
 
  Select_Lex *select_lex= session->getLex()->current_select;
 
3205
  Select_Lex *select_lex= session->lex->current_select;
3212
3206
 
3213
3207
  /*
3214
3208
    Currently setup() can be called twice. Please add