~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/sum.cc

  • Committer: Mark Atwood
  • Date: 2011-08-12 04:08:33 UTC
  • mfrom: (2385.2.17 refactor5)
  • Revision ID: me@mark.atwood.name-20110812040833-u6j85nc6ahuc0dtz
mergeĀ lp:~olafvdspek/drizzle/refactor5

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <drizzled/hybrid_type_traits_decimal.h>
31
31
#include <drizzled/sql_base.h>
32
32
#include <drizzled/session.h>
33
 
 
34
33
#include <drizzled/item/sum.h>
35
34
#include <drizzled/field/decimal.h>
36
35
#include <drizzled/field/double.h>
38
37
#include <drizzled/field/date.h>
39
38
#include <drizzled/field/datetime.h>
40
39
#include <drizzled/unique.h>
41
 
 
42
40
#include <drizzled/type/decimal.h>
43
 
 
44
41
#include <drizzled/internal/m_string.h>
 
42
#include <drizzled/item/subselect.h>
 
43
#include <drizzled/sql_lex.h>
 
44
#include <drizzled/system_variables.h>
 
45
#include <drizzled/create_field.h>
45
46
 
46
47
#include <algorithm>
47
48
 
48
49
using namespace std;
49
50
 
50
 
namespace drizzled
51
 
{
 
51
namespace drizzled {
52
52
 
53
53
extern plugin::StorageEngine *heap_engine;
54
54
 
76
76
 
77
77
bool Item_sum::init_sum_func_check(Session *session)
78
78
{
79
 
  if (!session->getLex()->allow_sum_func)
 
79
  if (!session->lex().allow_sum_func)
80
80
  {
81
81
    my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
82
82
               MYF(0));
83
83
    return true;
84
84
  }
85
85
  /* Set a reference to the nesting set function if there is  any */
86
 
  in_sum_func= session->getLex()->in_sum_func;
 
86
  in_sum_func= session->lex().in_sum_func;
87
87
  /* 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;
 
88
  session->lex().in_sum_func= this;
 
89
  nest_level= session->lex().current_select->nest_level;
90
90
  ref_by= 0;
91
91
  aggr_level= -1;
92
92
  aggr_sel= NULL;
148
148
bool Item_sum::check_sum_func(Session *session, Item **ref)
149
149
{
150
150
  bool invalid= false;
151
 
  nesting_map allow_sum_func= session->getLex()->allow_sum_func;
 
151
  nesting_map allow_sum_func= session->lex().allow_sum_func;
152
152
  /*
153
153
    The value of max_arg_level is updated if an argument of the set function
154
154
    contains a column reference resolved  against a subquery whose level is
181
181
  if (!invalid && aggr_level < 0)
182
182
  {
183
183
    aggr_level= nest_level;
184
 
    aggr_sel= session->getLex()->current_select;
 
184
    aggr_sel= session->lex().current_select;
185
185
  }
186
186
  /*
187
187
    By this moment we either found a subquery where the set function is
227
227
    Check that non-aggregated fields and sum functions aren't mixed in the
228
228
    same select in the ONLY_FULL_GROUP_BY mode.
229
229
  */
230
 
  if (outer_fields.elements)
 
230
  if (outer_fields.size())
231
231
  {
232
232
    Item_field *field;
233
233
    /*
287
287
  }
288
288
  aggr_sel->full_group_by_flag.set(SUM_FUNC_USED);
289
289
  update_used_tables();
290
 
  session->getLex()->in_sum_func= in_sum_func;
 
290
  session->lex().in_sum_func= in_sum_func;
291
291
  return false;
292
292
}
293
293
 
319
319
bool Item_sum::register_sum_func(Session *session, Item **ref)
320
320
{
321
321
  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() ;
 
322
  nesting_map allow_sum_func= session->lex().allow_sum_func;
 
323
  for (sl= session->lex().current_select->master_unit()->outer_select() ;
324
324
       sl && sl->nest_level > max_arg_level;
325
325
       sl= sl->master_unit()->outer_select() )
326
326
  {
371
371
      with_sum_func being set for an Select_Lex means that this Select_Lex
372
372
      has aggregate functions directly referenced (i.e. not through a sub-select).
373
373
    */
374
 
    for (sl= session->getLex()->current_select;
 
374
    for (sl= session->lex().current_select;
375
375
         sl && sl != aggr_sel && sl->master_unit()->item;
376
376
         sl= sl->master_unit()->outer_select() )
377
377
      sl->master_unit()->item->with_sum_func= 1;
378
378
  }
379
 
  session->getLex()->current_select->mark_as_dependent(aggr_sel);
 
379
  session->lex().current_select->mark_as_dependent(aggr_sel);
380
380
  return false;
381
381
}
382
382
 
383
383
 
384
 
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
 
384
Item_sum::Item_sum(List<Item> &list) :arg_count(list.size()),
385
385
  forced_const(false)
386
386
{
387
387
  if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
412
412
  forced_const(item->forced_const)
413
413
{
414
414
  if (arg_count <= 2)
415
 
    args=tmp_args;
 
415
    args= tmp_args;
416
416
  else
417
 
    if (!(args= (Item**) session->getMemRoot()->allocate(sizeof(Item*)*arg_count)))
418
 
      return;
 
417
    args= new (session->mem) Item*[arg_count];
419
418
  memcpy(args, item->args, sizeof(Item*)*arg_count);
420
419
}
421
420
 
422
421
 
423
422
void Item_sum::mark_as_sum_func()
424
423
{
425
 
  Select_Lex *cur_select= getSession().getLex()->current_select;
 
424
  Select_Lex *cur_select= getSession().lex().current_select;
426
425
  cur_select->n_sum_items++;
427
426
  cur_select->with_sum_func= 1;
428
427
  with_sum_func= 1;
435
434
  {
436
435
    ((Item_field*) args[0])->field->make_field(tmp_field);
437
436
    /* For expressions only col_name should be non-empty string. */
438
 
    char *empty_string= (char*)"";
439
 
    tmp_field->db_name= empty_string;
440
 
    tmp_field->org_table_name= empty_string;
441
 
    tmp_field->table_name= empty_string;
442
 
    tmp_field->org_col_name= empty_string;
 
437
    tmp_field->db_name= "";
 
438
    tmp_field->org_table_name= "";
 
439
    tmp_field->table_name= "";
 
440
    tmp_field->org_col_name= "";
443
441
    tmp_field->col_name= name;
444
442
    if (maybe_null)
445
443
      tmp_field->flags&= ~NOT_NULL_FLAG;
449
447
}
450
448
 
451
449
 
452
 
void Item_sum::print(String *str, enum_query_type query_type)
 
450
void Item_sum::print(String *str)
453
451
{
454
452
  str->append(func_name());
455
453
  for (uint32_t i=0 ; i < arg_count ; i++)
456
454
  {
457
455
    if (i)
458
456
      str->append(',');
459
 
    args[i]->print(str, query_type);
 
457
    args[i]->print(str);
460
458
  }
461
459
  str->append(')');
462
460
}
779
777
 
780
778
Item *Item_sum_sum::copy_or_same(Session* session)
781
779
{
782
 
  return new (session->mem_root) Item_sum_sum(session, this);
 
780
  return new (session->mem) Item_sum_sum(session, this);
783
781
}
784
782
 
785
783
 
844
842
    if (!args[0]->null_value)
845
843
      null_value= 0;
846
844
  }
847
 
  return(0);
 
845
  return 0;
848
846
}
849
847
 
850
848
 
1013
1011
*/
1014
1012
bool Item_sum_distinct::setup(Session *session)
1015
1013
{
1016
 
  List<CreateField> field_list;
1017
 
  CreateField field_def;                              /* field definition */
1018
1014
  /* It's legal to call setup() more than once when in a subquery */
1019
1015
  if (tree)
1020
 
    return(false);
 
1016
    return false;
1021
1017
 
1022
1018
  /*
1023
1019
    Virtual table and the tree are created anew on each re-execution of
1024
1020
    PS/SP. Hence all further allocations are performed in the runtime
1025
 
    mem_root.
 
1021
    mem.
1026
1022
  */
1027
 
  if (field_list.push_back(&field_def))
1028
 
    return(true);
1029
 
 
1030
1023
  null_value= maybe_null= 1;
1031
1024
  quick_group= 0;
1032
1025
 
1033
1026
  assert(args[0]->fixed);
1034
1027
 
1035
 
  field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
1036
 
                               args[0]->decimals, args[0]->maybe_null);
1037
 
 
1038
 
  if (! (table= session->getInstanceTable(field_list)))
1039
 
    return(true);
 
1028
  std::list<CreateField> field_list;
 
1029
  field_list.push_back(CreateField());
 
1030
  CreateField& field_def = field_list.back();
 
1031
  field_def.init_for_tmp_table(table_field_type, args[0]->max_length, args[0]->decimals, args[0]->maybe_null);
 
1032
  table= &session->getInstanceTable(field_list);
1040
1033
 
1041
1034
  /* XXX: check that the case of CHAR(0) works OK */
1042
1035
  tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
1047
1040
    simple_raw_key_cmp because the table contains numbers only; decimals
1048
1041
    are converted to binary representation as well.
1049
1042
  */
1050
 
  tree= new Unique(simple_raw_key_cmp, &tree_key_length,
1051
 
                   tree_key_length,
1052
 
                   (size_t)session->variables.max_heap_table_size);
1053
 
 
 
1043
  tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length, (size_t)session->variables.max_heap_table_size);
1054
1044
  is_evaluated= false;
1055
 
  return(tree == 0);
 
1045
  return false;
1056
1046
}
1057
1047
 
1058
 
 
1059
1048
bool Item_sum_distinct::add()
1060
1049
{
1061
1050
  args[0]->save_in_field(table->getField(0), false);
1191
1180
 
1192
1181
Item *Item_sum_count::copy_or_same(Session* session)
1193
1182
{
1194
 
  return new (session->mem_root) Item_sum_count(session, this);
 
1183
  return new (session->mem) Item_sum_count(session, this);
1195
1184
}
1196
1185
 
1197
1186
 
1251
1240
 
1252
1241
Item *Item_sum_avg::copy_or_same(Session* session)
1253
1242
{
1254
 
  return new (session->mem_root) Item_sum_avg(session, this);
 
1243
  return new (session->mem) Item_sum_avg(session, this);
1255
1244
}
1256
1245
 
1257
1246
 
1363
1352
 
1364
1353
Item *Item_sum_std::copy_or_same(Session* session)
1365
1354
{
1366
 
  return new (session->mem_root) Item_sum_std(session, this);
 
1355
  return new (session->mem) Item_sum_std(session, this);
1367
1356
}
1368
1357
 
1369
1358
 
1461
1450
 
1462
1451
Item *Item_sum_variance::copy_or_same(Session* session)
1463
1452
{
1464
 
  return new (session->mem_root) Item_sum_variance(session, this);
 
1453
  return new (session->mem) Item_sum_variance(session, this);
1465
1454
}
1466
1455
 
1467
1456
 
1753
1742
 
1754
1743
Item *Item_sum_min::copy_or_same(Session* session)
1755
1744
{
1756
 
  return new (session->mem_root) Item_sum_min(session, this);
 
1745
  return new (session->mem) Item_sum_min(session, this);
1757
1746
}
1758
1747
 
1759
1748
 
1816
1805
 
1817
1806
Item *Item_sum_max::copy_or_same(Session* session)
1818
1807
{
1819
 
  return new (session->mem_root) Item_sum_max(session, this);
 
1808
  return new (session->mem) Item_sum_max(session, this);
1820
1809
}
1821
1810
 
1822
1811
 
1894
1883
 
1895
1884
Item *Item_sum_or::copy_or_same(Session* session)
1896
1885
{
1897
 
  return new (session->mem_root) Item_sum_or(session, this);
 
1886
  return new (session->mem) Item_sum_or(session, this);
1898
1887
}
1899
1888
 
1900
1889
 
1908
1897
 
1909
1898
Item *Item_sum_xor::copy_or_same(Session* session)
1910
1899
{
1911
 
  return new (session->mem_root) Item_sum_xor(session, this);
 
1900
  return new (session->mem) Item_sum_xor(session, this);
1912
1901
}
1913
1902
 
1914
1903
 
1922
1911
 
1923
1912
Item *Item_sum_and::copy_or_same(Session* session)
1924
1913
{
1925
 
  return new (session->mem_root) Item_sum_and(session, this);
 
1914
  return new (session->mem) Item_sum_and(session, this);
1926
1915
}
1927
1916
 
1928
1917
 
2584
2573
bool Item_sum_count_distinct::setup(Session *session)
2585
2574
{
2586
2575
  List<Item> list;
2587
 
  Select_Lex *select_lex= session->getLex()->current_select;
 
2576
  Select_Lex *select_lex= session->lex().current_select;
2588
2577
 
2589
2578
  /*
2590
2579
    Setup can be called twice for ROLLUP items. This is a bug.
2594
2583
  if (tree || table || tmp_table_param)
2595
2584
    return false;
2596
2585
 
2597
 
  if (!(tmp_table_param= new Tmp_Table_Param))
2598
 
    return true;
 
2586
  tmp_table_param= new Tmp_Table_Param;
2599
2587
 
2600
2588
  /* Create a table with an unique key over all parameters */
2601
 
  for (uint32_t i=0; i < arg_count ; i++)
 
2589
  for (uint32_t i= 0; i < arg_count; i++)
2602
2590
  {
2603
2591
    Item *item=args[i];
2604
 
    if (list.push_back(item))
2605
 
      return true;                              // End of memory
 
2592
    list.push_back(item);
2606
2593
    if (item->const_item() && item->is_null())
2607
2594
      always_null= 1;
2608
2595
  }
2612
2599
  tmp_table_param->force_copy_fields= force_copy_fields;
2613
2600
  assert(table == 0);
2614
2601
 
2615
 
  if (!(table= create_tmp_table(session, tmp_table_param, list, (Order*) 0, 1,
2616
 
                                0,
2617
 
                                (select_lex->options | session->options),
2618
 
                                HA_POS_ERROR, (char*)"")))
 
2602
  if (!(table= create_tmp_table(session, tmp_table_param, list, NULL, 1, 0, (select_lex->options | session->options), HA_POS_ERROR, "")))
2619
2603
  {
2620
2604
    return true;
2621
2605
  }
2668
2652
      {
2669
2653
        uint32_t *length;
2670
2654
        compare_key= (qsort_cmp2) composite_key_cmp;
2671
 
        cmp_arg= (void*) this;
2672
 
        field_lengths= (uint32_t*) session->getMemRoot()->allocate(table->getShare()->sizeFields() * sizeof(uint32_t));
 
2655
        cmp_arg= this;
 
2656
        field_lengths= new (session->mem) uint32_t[table->getShare()->sizeFields()];
2673
2657
        for (tree_key_length= 0, length= field_lengths, field= table->getFields();
2674
2658
             field < field_end; ++field, ++length)
2675
2659
        {
2697
2681
 
2698
2682
Item *Item_sum_count_distinct::copy_or_same(Session* session)
2699
2683
{
2700
 
  return new (session->mem_root) Item_sum_count_distinct(session, this);
 
2684
  return new (session->mem) Item_sum_count_distinct(session, this);
2701
2685
}
2702
2686
 
2703
2687
 
2934
2918
  if (result->length() > item->max_length)
2935
2919
  {
2936
2920
    int well_formed_error;
2937
 
    const CHARSET_INFO * const cs= item->collation.collation;
 
2921
    const charset_info_st * const cs= item->collation.collation;
2938
2922
    const char *ptr= result->ptr();
2939
2923
    uint32_t add_length;
2940
2924
    /*
2973
2957
   separator(separator_arg), tree(NULL), unique_filter(NULL), table(0),
2974
2958
   order(0), context(context_arg),
2975
2959
   arg_count_order(order_list ? order_list->elements : 0),
2976
 
   arg_count_field(select_list->elements),
 
2960
   arg_count_field(select_list->size()),
2977
2961
   count_cut_values(0),
2978
2962
   distinct(distinct_arg),
2979
2963
   warning_for_row(false),
3074
3058
        delete_tree(tree);
3075
3059
        tree= 0;
3076
3060
      }
3077
 
      if (unique_filter)
3078
 
      {
3079
 
        delete unique_filter;
3080
 
        unique_filter= NULL;
3081
 
      }
 
3061
 
 
3062
      delete unique_filter;
 
3063
      unique_filter= NULL;
 
3064
 
3082
3065
      if (warning)
3083
3066
      {
3084
3067
        char warn_buff[DRIZZLE_ERRMSG_SIZE];
3095
3078
 
3096
3079
Item *Item_func_group_concat::copy_or_same(Session* session)
3097
3080
{
3098
 
  return new (session->mem_root) Item_func_group_concat(session, this);
 
3081
  return new (session->mem) Item_func_group_concat(session, this);
3099
3082
}
3100
3083
 
3101
3084
 
3208
3191
bool Item_func_group_concat::setup(Session *session)
3209
3192
{
3210
3193
  List<Item> list;
3211
 
  Select_Lex *select_lex= session->getLex()->current_select;
 
3194
  Select_Lex *select_lex= session->lex().current_select;
3212
3195
 
3213
3196
  /*
3214
3197
    Currently setup() can be called twice. Please add
3215
3198
    assertion here when this is fixed.
3216
3199
  */
3217
3200
  if (table || tree)
3218
 
    return(false);
 
3201
    return false;
3219
3202
 
3220
 
  if (!(tmp_table_param= new Tmp_Table_Param))
3221
 
    return(true);
 
3203
  tmp_table_param= new Tmp_Table_Param;
3222
3204
 
3223
3205
  /* We'll convert all blobs to varchar fields in the temporary table */
3224
3206
  tmp_table_param->convert_blob_length= max_length *
3228
3210
  for (uint32_t i= 0; i < arg_count_field; i++)
3229
3211
  {
3230
3212
    Item *item= args[i];
3231
 
    if (list.push_back(item))
3232
 
      return(true);
 
3213
    list.push_back(item);
3233
3214
    if (item->const_item())
3234
3215
    {
3235
3216
      if (item->is_null())
3236
3217
      {
3237
3218
        always_null= 1;
3238
 
        return(false);
 
3219
        return false;
3239
3220
      }
3240
3221
    }
3241
3222
  }
3249
3230
  */
3250
3231
  if (arg_count_order &&
3251
3232
      setup_order(session, args, context->table_list, list, all_fields, *order))
3252
 
    return(true);
 
3233
    return true;
3253
3234
 
3254
3235
  count_field_types(select_lex, tmp_table_param, all_fields, 0);
3255
3236
  tmp_table_param->force_copy_fields= force_copy_fields;
3278
3259
                                (select_lex->options | session->options),
3279
3260
                                HA_POS_ERROR, (char*) "")))
3280
3261
  {
3281
 
    return(true);
 
3262
    return true;
3282
3263
  }
3283
3264
 
3284
3265
  table->cursor->extra(HA_EXTRA_NO_ROWS);
3312
3293
                              tree_key_length,
3313
3294
                              (size_t)session->variables.max_heap_table_size);
3314
3295
 
3315
 
  return(false);
 
3296
  return false;
3316
3297
}
3317
3298
 
3318
3299
 
3368
3349
}
3369
3350
 
3370
3351
 
3371
 
void Item_func_group_concat::print(String *str, enum_query_type query_type)
 
3352
void Item_func_group_concat::print(String *str)
3372
3353
{
3373
3354
  str->append(STRING_WITH_LEN("group_concat("));
3374
3355
  if (distinct)
3377
3358
  {
3378
3359
    if (i)
3379
3360
      str->append(',');
3380
 
    args[i]->print(str, query_type);
 
3361
    args[i]->print(str);
3381
3362
  }
3382
3363
  if (arg_count_order)
3383
3364
  {
3386
3367
    {
3387
3368
      if (i)
3388
3369
        str->append(',');
3389
 
      (*order[i]->item)->print(str, query_type);
 
3370
      (*order[i]->item)->print(str);
3390
3371
      if (order[i]->asc)
3391
3372
        str->append(STRING_WITH_LEN(" ASC"));
3392
3373
      else