~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_sum.cc

  • Committer: Monty Taylor
  • Date: 2008-07-22 05:48:51 UTC
  • mto: (202.1.3 toru)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: monty@inaugust.com-20080722054851-airxt73370725p7x
Re-enabled optimizations for the normal build, and added back the --with-debug option to turn them off. 

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 <drizzled/server_includes.h>
24
 
#include <drizzled/sql_select.h>
25
 
#include <drizzled/drizzled_error_messages.h>
 
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"
26
30
 
27
31
/**
28
32
  Prepare an aggregate function item for checking context conditions.
147
151
    if (register_sum_func(thd, ref))
148
152
      return true;
149
153
    invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
150
 
    if (!invalid && false)
 
154
    if (!invalid && thd->variables.sql_mode & MODE_ANSI)
151
155
      invalid= aggr_level < 0 && max_arg_level < nest_level;
152
156
  }
153
157
  if (!invalid && aggr_level < 0)
356
360
{
357
361
  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
358
362
  {
359
 
    uint32_t i=0;
 
363
    uint i=0;
360
364
    List_iterator_fast<Item> li(list);
361
365
    Item *item;
362
366
 
422
426
void Item_sum::print(String *str, enum_query_type query_type)
423
427
{
424
428
  str->append(func_name());
425
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
429
  for (uint i=0 ; i < arg_count ; i++)
426
430
  {
427
431
    if (i)
428
432
      str->append(',');
434
438
void Item_sum::fix_num_length_and_dec()
435
439
{
436
440
  decimals=0;
437
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
441
  for (uint i=0 ; i < arg_count ; i++)
438
442
    set_if_bigger(decimals,args[i]->decimals);
439
443
  max_length=float_length(decimals);
440
444
}
445
449
  if (sum_item && sum_item->result_field)          // If not a const sum func
446
450
  {
447
451
    Field *result_field_tmp= sum_item->result_field;
448
 
    for (uint32_t i=0 ; i < sum_item->arg_count ; i++)
 
452
    for (uint i=0 ; i < sum_item->arg_count ; i++)
449
453
    {
450
454
      Item *arg= sum_item->args[i];
451
455
      if (!arg->const_item())
462
466
 
463
467
 
464
468
bool Item_sum::walk (Item_processor processor, bool walk_subquery,
465
 
                     unsigned char *argument)
 
469
                     uchar *argument)
466
470
{
467
471
  if (arg_count)
468
472
  {
477
481
}
478
482
 
479
483
 
480
 
Field *Item_sum::create_tmp_field(bool group __attribute__((unused)),
481
 
                                  Table *table,
482
 
                                  uint32_t convert_blob_length)
 
484
Field *Item_sum::create_tmp_field(bool group __attribute__((__unused__)),
 
485
                                  TABLE *table,
 
486
                                  uint convert_blob_length)
483
487
{
484
488
  Field *field;
485
489
  switch (result_type()) {
518
522
  if (!forced_const)
519
523
  {
520
524
    used_tables_cache= 0;
521
 
    for (uint32_t i=0 ; i < arg_count ; i++)
 
525
    for (uint i=0 ; i < arg_count ; i++)
522
526
    {
523
527
      args[i]->update_used_tables();
524
528
      used_tables_cache|= args[i]->used_tables();
568
572
 
569
573
  decimals=0;
570
574
  maybe_null=0;
571
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
575
  for (uint i=0 ; i < arg_count ; i++)
572
576
  {
573
577
    if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
574
578
      return true;
673
677
  return false;
674
678
}
675
679
 
676
 
Field *Item_sum_hybrid::create_tmp_field(bool group, Table *table,
677
 
                                         uint32_t convert_blob_length)
 
680
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
 
681
                                         uint convert_blob_length)
678
682
{
679
683
  Field *field;
680
684
  if (args[0]->type() == Item::FIELD_ITEM)
692
696
    fields creations separately.
693
697
  */
694
698
  switch (args[0]->field_type()) {
695
 
  case DRIZZLE_TYPE_NEWDATE:
 
699
  case MYSQL_TYPE_NEWDATE:
696
700
    field= new Field_newdate(maybe_null, name, collation.collation);
697
701
    break;
698
 
  case DRIZZLE_TYPE_TIME:
 
702
  case MYSQL_TYPE_TIME:
699
703
    field= new Field_time(maybe_null, name, collation.collation);
700
704
    break;
701
 
  case DRIZZLE_TYPE_TIMESTAMP:
702
 
  case DRIZZLE_TYPE_DATETIME:
 
705
  case MYSQL_TYPE_TIMESTAMP:
 
706
  case MYSQL_TYPE_DATETIME:
703
707
    field= new Field_datetime(maybe_null, name, collation.collation);
704
708
    break;
705
709
  default:
846
850
 
847
851
/***************************************************************************/
848
852
 
849
 
#ifdef __cplusplus
850
 
extern "C" {
851
 
#endif
 
853
C_MODE_START
852
854
 
853
855
/* Declarations for auxilary C-callbacks */
854
856
 
855
857
static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
856
858
{
857
 
    return memcmp(key1, key2, *(uint32_t *) arg);
 
859
    return memcmp(key1, key2, *(uint *) arg);
858
860
}
859
861
 
860
862
 
861
863
static int item_sum_distinct_walk(void *element,
862
 
                                  element_count num_of_dups __attribute__((unused)),
 
864
                                  element_count num_of_dups __attribute__((__unused__)),
863
865
                                  void *item)
864
866
{
865
867
  return ((Item_sum_distinct*) (item))->unique_walk_function(element);
866
868
}
867
869
 
868
 
#ifdef __cplusplus
869
 
}
870
 
#endif
 
870
C_MODE_END
871
871
 
872
872
/* Item_sum_distinct */
873
873
 
936
936
  case STRING_RESULT:
937
937
  case REAL_RESULT:
938
938
    val.traits= Hybrid_type_traits::instance();
939
 
    table_field_type= DRIZZLE_TYPE_DOUBLE;
 
939
    table_field_type= MYSQL_TYPE_DOUBLE;
940
940
    break;
941
941
  case INT_RESULT:
942
942
  /*
946
946
    calculations. The range of int64 is enough to hold sum 2^32 distinct
947
947
    integers each <= 2^32.
948
948
  */
949
 
  if (table_field_type >= DRIZZLE_TYPE_TINY && table_field_type <= DRIZZLE_TYPE_LONG)
 
949
  if (table_field_type >= MYSQL_TYPE_TINY && table_field_type <= MYSQL_TYPE_LONG)
950
950
  {
951
951
    val.traits= Hybrid_type_traits_fast_decimal::instance();
952
952
    break;
953
953
  }
954
 
  table_field_type= DRIZZLE_TYPE_LONGLONG;
 
954
  table_field_type= MYSQL_TYPE_LONGLONG;
955
955
  /* fallthrough */
956
956
  case DECIMAL_RESULT:
957
957
    val.traits= Hybrid_type_traits_decimal::instance();
958
 
    if (table_field_type != DRIZZLE_TYPE_LONGLONG)
959
 
      table_field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
958
    if (table_field_type != MYSQL_TYPE_LONGLONG)
 
959
      table_field_type= MYSQL_TYPE_NEWDECIMAL;
960
960
    break;
961
961
  case ROW_RESULT:
962
962
  default:
1131
1131
    AVG() will divide val by count. We need to reserve digits
1132
1132
    after decimal point as the result can be fractional.
1133
1133
  */
1134
 
  decimals= cmin(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
 
1134
  decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
1135
1135
}
1136
1136
 
1137
1137
 
1193
1193
  if (hybrid_type == DECIMAL_RESULT)
1194
1194
  {
1195
1195
    int precision= args[0]->decimal_precision() + prec_increment;
1196
 
    decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
 
1196
    decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
1197
1197
    max_length= my_decimal_precision_to_length(precision, decimals,
1198
1198
                                               unsigned_flag);
1199
 
    f_precision= cmin(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
 
1199
    f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1200
1200
    f_scale=  args[0]->decimals;
1201
1201
    dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
1202
1202
  }
1203
1203
  else {
1204
 
    decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
 
1204
    decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
1205
1205
    max_length= args[0]->max_length + prec_increment;
1206
1206
  }
1207
1207
}
1213
1213
}
1214
1214
 
1215
1215
 
1216
 
Field *Item_sum_avg::create_tmp_field(bool group, Table *table,
1217
 
                                      uint32_t convert_blob_len __attribute__((unused)))
 
1216
Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table,
 
1217
                                      uint convert_blob_len __attribute__((__unused__)))
1218
1218
{
1219
1219
  Field *field;
1220
1220
  if (group)
1224
1224
      The easiest way is to do this is to store both value in a string
1225
1225
      and unpack on access.
1226
1226
    */
1227
 
    field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
1228
 
                                dec_bin_size : sizeof(double)) + sizeof(int64_t),
1229
 
                               0, name, table->s, &my_charset_bin);
 
1227
    field= new Field_string(((hybrid_type == DECIMAL_RESULT) ?
 
1228
                             dec_bin_size : sizeof(double)) + sizeof(int64_t),
 
1229
                            0, name, &my_charset_bin);
1230
1230
  }
1231
1231
  else if (hybrid_type == DECIMAL_RESULT)
1232
1232
    field= new Field_new_decimal(max_length, maybe_null, name,
1392
1392
  switch (args[0]->result_type()) {
1393
1393
  case REAL_RESULT:
1394
1394
  case STRING_RESULT:
1395
 
    decimals= cmin(args[0]->decimals + 4, NOT_FIXED_DEC);
 
1395
    decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
1396
1396
    break;
1397
1397
  case INT_RESULT:
1398
1398
  case DECIMAL_RESULT:
1399
1399
  {
1400
1400
    int precision= args[0]->decimal_precision()*2 + prec_increment;
1401
 
    decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
 
1401
    decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
1402
1402
    max_length= my_decimal_precision_to_length(precision, decimals,
1403
1403
                                               unsigned_flag);
1404
1404
 
1423
1423
  If we're grouping, then we need some space to serialize variables into, to
1424
1424
  pass around.
1425
1425
*/
1426
 
Field *Item_sum_variance::create_tmp_field(bool group, Table *table,
1427
 
                                           uint32_t convert_blob_len __attribute__((unused)))
 
1426
Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table,
 
1427
                                           uint convert_blob_len __attribute__((__unused__)))
1428
1428
{
1429
1429
  Field *field;
1430
1430
  if (group)
1434
1434
      The easiest way is to do this is to store both value in a string
1435
1435
      and unpack on access.
1436
1436
    */
1437
 
    field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->s, &my_charset_bin);
 
1437
    field= new Field_string(sizeof(double)*2 + sizeof(int64_t), 0, name, &my_charset_bin);
1438
1438
  }
1439
1439
  else
1440
1440
    field= new Field_double(max_length, maybe_null, name, decimals, true);
1499
1499
void Item_sum_variance::reset_field()
1500
1500
{
1501
1501
  double nr;
1502
 
  unsigned char *res= result_field->ptr;
 
1502
  uchar *res= result_field->ptr;
1503
1503
 
1504
1504
  nr= args[0]->val_real();              /* sets null_value as side-effect */
1505
1505
 
1506
1506
  if (args[0]->null_value)
1507
 
    memset(res, 0, sizeof(double)*2+sizeof(int64_t));
 
1507
    bzero(res,sizeof(double)*2+sizeof(int64_t));
1508
1508
  else
1509
1509
  {
1510
1510
    /* Serialize format is (double)m, (double)s, (int64_t)count */
1522
1522
void Item_sum_variance::update_field()
1523
1523
{
1524
1524
  uint64_t field_count;
1525
 
  unsigned char *res=result_field->ptr;
 
1525
  uchar *res=result_field->ptr;
1526
1526
 
1527
1527
  double nr= args[0]->val_real();       /* sets null_value as side-effect */
1528
1528
 
1579
1579
                             &end_not_used, &err_not_used) : 0.0);
1580
1580
  }
1581
1581
  case INT_RESULT:
 
1582
    if (unsigned_flag)
 
1583
      return uint64_t2double(sum_int);
1582
1584
    return (double) sum_int;
1583
1585
  case DECIMAL_RESULT:
1584
1586
    my_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
1883
1885
void Item_sum_num::reset_field()
1884
1886
{
1885
1887
  double nr= args[0]->val_real();
1886
 
  unsigned char *res=result_field->ptr;
 
1888
  uchar *res=result_field->ptr;
1887
1889
 
1888
1890
  if (maybe_null)
1889
1891
  {
2005
2007
 
2006
2008
void Item_sum_count::reset_field()
2007
2009
{
2008
 
  unsigned char *res=result_field->ptr;
 
2010
  uchar *res=result_field->ptr;
2009
2011
  int64_t nr=0;
2010
2012
 
2011
2013
  if (!args[0]->maybe_null || !args[0]->is_null())
2016
2018
 
2017
2019
void Item_sum_avg::reset_field()
2018
2020
{
2019
 
  unsigned char *res=result_field->ptr;
 
2021
  uchar *res=result_field->ptr;
2020
2022
  if (hybrid_type == DECIMAL_RESULT)
2021
2023
  {
2022
2024
    int64_t tmp;
2037
2039
    double nr= args[0]->val_real();
2038
2040
 
2039
2041
    if (args[0]->null_value)
2040
 
      memset(res, 0, sizeof(double)+sizeof(int64_t));
 
2042
      bzero(res,sizeof(double)+sizeof(int64_t));
2041
2043
    else
2042
2044
    {
2043
2045
      int64_t tmp= 1;
2057
2059
 
2058
2060
void Item_sum_bit::update_field()
2059
2061
{
2060
 
  unsigned char *res=result_field->ptr;
 
2062
  uchar *res=result_field->ptr;
2061
2063
  bits= uint8korr(res);
2062
2064
  add();
2063
2065
  int8store(res, bits);
2092
2094
  else
2093
2095
  {
2094
2096
    double old_nr,nr;
2095
 
    unsigned char *res=result_field->ptr;
 
2097
    uchar *res=result_field->ptr;
2096
2098
 
2097
2099
    float8get(old_nr,res);
2098
2100
    nr= args[0]->val_real();
2109
2111
void Item_sum_count::update_field()
2110
2112
{
2111
2113
  int64_t nr;
2112
 
  unsigned char *res=result_field->ptr;
 
2114
  uchar *res=result_field->ptr;
2113
2115
 
2114
2116
  nr=sint8korr(res);
2115
2117
  if (!args[0]->maybe_null || !args[0]->is_null())
2121
2123
void Item_sum_avg::update_field()
2122
2124
{
2123
2125
  int64_t field_count;
2124
 
  unsigned char *res=result_field->ptr;
 
2126
  uchar *res=result_field->ptr;
2125
2127
  if (hybrid_type == DECIMAL_RESULT)
2126
2128
  {
2127
2129
    my_decimal value, *arg_val= args[0]->val_decimal(&value);
2294
2296
  // fix_fields() never calls for this Item
2295
2297
  double nr;
2296
2298
  int64_t count;
2297
 
  unsigned char *res;
 
2299
  uchar *res;
2298
2300
 
2299
2301
  if (hybrid_type == DECIMAL_RESULT)
2300
2302
    return val_real_from_decimal();
2427
2429
** COUNT(DISTINCT ...)
2428
2430
****************************************************************************/
2429
2431
 
2430
 
int simple_str_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
 
2432
int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2)
2431
2433
{
2432
2434
  Field *f= (Field*) arg;
2433
2435
  return f->cmp(key1, key2);
2440
2442
  static
2441
2443
*/
2442
2444
 
2443
 
int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
 
2445
int composite_key_cmp(void* arg, uchar* key1, uchar* key2)
2444
2446
{
2445
2447
  Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
2446
2448
  Field **field    = item->table->field;
2447
2449
  Field **field_end= field + item->table->s->fields;
2448
 
  uint32_t *lengths=item->field_lengths;
 
2450
  uint32 *lengths=item->field_lengths;
2449
2451
  for (; field < field_end; ++field)
2450
2452
  {
2451
2453
    Field* f = *field;
2459
2461
  return 0;
2460
2462
}
2461
2463
 
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)),
 
2464
 
 
2465
C_MODE_START
 
2466
 
 
2467
static int count_distinct_walk(void *elem __attribute__((__unused__)),
 
2468
                               element_count count __attribute__((__unused__)),
2468
2469
                               void *arg)
2469
2470
{
2470
2471
  (*((uint64_t*)arg))++;
2471
2472
  return 0;
2472
2473
}
2473
2474
 
2474
 
#ifdef __cplusplus
2475
 
}
2476
 
#endif
2477
 
 
 
2475
C_MODE_END
2478
2476
 
2479
2477
 
2480
2478
void Item_sum_count_distinct::cleanup()
2494
2492
    is_evaluated= false;
2495
2493
    if (table)
2496
2494
    {
2497
 
      table->free_tmp_table(table->in_use);
 
2495
      free_tmp_table(table->in_use, table);
2498
2496
      table= 0;
2499
2497
    }
2500
2498
    delete tmp_table_param;
2545
2543
    return true;
2546
2544
 
2547
2545
  /* Create a table with an unique key over all parameters */
2548
 
  for (uint32_t i=0; i < arg_count ; i++)
 
2546
  for (uint i=0; i < arg_count ; i++)
2549
2547
  {
2550
2548
    Item *item=args[i];
2551
2549
    if (list.push_back(item))
2559
2557
  tmp_table_param->force_copy_fields= force_copy_fields;
2560
2558
  assert(table == 0);
2561
2559
 
2562
 
  if (!(table= create_tmp_table(thd, tmp_table_param, list, (order_st*) 0, 1,
 
2560
  if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
2563
2561
                                0,
2564
2562
                                (select_lex->options | thd->options),
2565
2563
                                HA_POS_ERROR, (char*)"")))
2584
2582
      Field *f= *field;
2585
2583
      enum enum_field_types f_type= f->type();
2586
2584
      tree_key_length+= f->pack_length();
2587
 
      if (f_type == DRIZZLE_TYPE_VARCHAR)
 
2585
      if ((f_type == MYSQL_TYPE_VARCHAR) || (!f->binary() && (f_type == MYSQL_TYPE_STRING)))
2588
2586
      {
2589
2587
        all_binary= false;
2590
2588
        break;
2611
2609
      }
2612
2610
      else
2613
2611
      {
2614
 
        uint32_t *length;
 
2612
        uint32 *length;
2615
2613
        compare_key= (qsort_cmp2) composite_key_cmp;
2616
2614
        cmp_arg= (void*) this;
2617
 
        field_lengths= (uint32_t*) thd->alloc(table->s->fields * sizeof(uint32_t));
 
2615
        field_lengths= (uint32*) thd->alloc(table->s->fields * sizeof(uint32));
2618
2616
        for (tree_key_length= 0, length= field_lengths, field= table->field;
2619
2617
             field < field_end; ++field, ++length)
2620
2618
        {
2697
2695
  int error;
2698
2696
  assert(fixed == 1);
2699
2697
  if (!table)                                   // Empty query
2700
 
    return 0L;
 
2698
    return 0LL;
2701
2699
  if (tree)
2702
2700
  {
2703
2701
    if (is_evaluated)
2721
2719
  return table->file->stats.records;
2722
2720
}
2723
2721
 
 
2722
 
 
2723
/****************************************************************************
 
2724
** Functions to handle dynamic loadable aggregates
 
2725
** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
 
2726
** Adapted for UDAs by: Andreas F. Bobak <bobak@relog.ch>.
 
2727
** Rewritten by: Monty.
 
2728
****************************************************************************/
 
2729
 
 
2730
void Item_udf_sum::clear()
 
2731
{
 
2732
  udf.clear();
 
2733
  return;
 
2734
}
 
2735
 
 
2736
bool Item_udf_sum::add()
 
2737
{
 
2738
  udf.add(&null_value);
 
2739
  return(0);
 
2740
}
 
2741
 
 
2742
void Item_udf_sum::cleanup()
 
2743
{
 
2744
  /*
 
2745
    udf_handler::cleanup() nicely handles case when we have not
 
2746
    original item but one created by copy_or_same() method.
 
2747
  */
 
2748
  udf.cleanup();
 
2749
  Item_sum::cleanup();
 
2750
}
 
2751
 
 
2752
 
 
2753
void Item_udf_sum::print(String *str, enum_query_type query_type)
 
2754
{
 
2755
  str->append(func_name());
 
2756
  str->append('(');
 
2757
  for (uint i=0 ; i < arg_count ; i++)
 
2758
  {
 
2759
    if (i)
 
2760
      str->append(',');
 
2761
    args[i]->print(str, query_type);
 
2762
  }
 
2763
  str->append(')');
 
2764
}
 
2765
 
 
2766
 
 
2767
Item *Item_sum_udf_float::copy_or_same(THD* thd)
 
2768
{
 
2769
  return new (thd->mem_root) Item_sum_udf_float(thd, this);
 
2770
}
 
2771
 
 
2772
double Item_sum_udf_float::val_real()
 
2773
{
 
2774
  assert(fixed == 1);
 
2775
  return(udf.val(&null_value));
 
2776
}
 
2777
 
 
2778
 
 
2779
String *Item_sum_udf_float::val_str(String *str)
 
2780
{
 
2781
  return val_string_from_real(str);
 
2782
}
 
2783
 
 
2784
 
 
2785
my_decimal *Item_sum_udf_float::val_decimal(my_decimal *dec)
 
2786
{
 
2787
  return val_decimal_from_real(dec);
 
2788
}
 
2789
 
 
2790
 
 
2791
String *Item_sum_udf_decimal::val_str(String *str)
 
2792
{
 
2793
  return val_string_from_decimal(str);
 
2794
}
 
2795
 
 
2796
 
 
2797
double Item_sum_udf_decimal::val_real()
 
2798
{
 
2799
  return val_real_from_decimal();
 
2800
}
 
2801
 
 
2802
 
 
2803
int64_t Item_sum_udf_decimal::val_int()
 
2804
{
 
2805
  return val_int_from_decimal();
 
2806
}
 
2807
 
 
2808
 
 
2809
my_decimal *Item_sum_udf_decimal::val_decimal(my_decimal *dec_buf)
 
2810
{
 
2811
  assert(fixed == 1);
 
2812
  return(udf.val_decimal(&null_value, dec_buf));
 
2813
}
 
2814
 
 
2815
 
 
2816
Item *Item_sum_udf_decimal::copy_or_same(THD* thd)
 
2817
{
 
2818
  return new (thd->mem_root) Item_sum_udf_decimal(thd, this);
 
2819
}
 
2820
 
 
2821
 
 
2822
Item *Item_sum_udf_int::copy_or_same(THD* thd)
 
2823
{
 
2824
  return new (thd->mem_root) Item_sum_udf_int(thd, this);
 
2825
}
 
2826
 
 
2827
int64_t Item_sum_udf_int::val_int()
 
2828
{
 
2829
  assert(fixed == 1);
 
2830
  return(udf.val_int(&null_value));
 
2831
}
 
2832
 
 
2833
 
 
2834
String *Item_sum_udf_int::val_str(String *str)
 
2835
{
 
2836
  return val_string_from_int(str);
 
2837
}
 
2838
 
 
2839
my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
 
2840
{
 
2841
  return val_decimal_from_int(dec);
 
2842
}
 
2843
 
 
2844
 
 
2845
/** Default max_length is max argument length. */
 
2846
 
 
2847
void Item_sum_udf_str::fix_length_and_dec()
 
2848
{
 
2849
  max_length=0;
 
2850
  for (uint i = 0; i < arg_count; i++)
 
2851
    set_if_bigger(max_length,args[i]->max_length);
 
2852
  return;
 
2853
}
 
2854
 
 
2855
 
 
2856
Item *Item_sum_udf_str::copy_or_same(THD* thd)
 
2857
{
 
2858
  return new (thd->mem_root) Item_sum_udf_str(thd, this);
 
2859
}
 
2860
 
 
2861
 
 
2862
my_decimal *Item_sum_udf_str::val_decimal(my_decimal *dec)
 
2863
{
 
2864
  return val_decimal_from_string(dec);
 
2865
}
 
2866
 
 
2867
String *Item_sum_udf_str::val_str(String *str)
 
2868
{
 
2869
  assert(fixed == 1);
 
2870
  String *res=udf.val_str(str,&str_value);
 
2871
  null_value = !res;
 
2872
  return(res);
 
2873
}
 
2874
 
2724
2875
/*****************************************************************************
2725
2876
 GROUP_CONCAT function
2726
2877
 
2727
2878
 SQL SYNTAX:
2728
 
  GROUP_CONCAT([DISTINCT] expr,... [order_st BY col [ASC|DESC],...]
 
2879
  GROUP_CONCAT([DISTINCT] expr,... [ORDER BY col [ASC|DESC],...]
2729
2880
    [SEPARATOR str_const])
2730
2881
 
2731
2882
 concat of values from "group by" operation
2732
2883
 
2733
2884
 BUGS
2734
 
   Blobs doesn't work with DISTINCT or order_st BY
 
2885
   Blobs doesn't work with DISTINCT or ORDER BY
2735
2886
*****************************************************************************/
2736
2887
 
2737
2888
 
2740
2891
  @note
2741
2892
       
2742
2893
     GROUP_CONCAT([DISTINCT] expr [,expr ...]
2743
 
              [order_st BY {unsigned_integer | col_name | expr}
 
2894
              [ORDER BY {unsigned_integer | col_name | expr}
2744
2895
                  [ASC | DESC] [,col_name ...]]
2745
2896
              [SEPARATOR str_val])
2746
2897
 
2754
2905
                                       const void* key2)
2755
2906
{
2756
2907
  Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
2757
 
  Table *table= item_func->table;
 
2908
  TABLE *table= item_func->table;
2758
2909
 
2759
 
  for (uint32_t i= 0; i < item_func->arg_count_field; i++)
 
2910
  for (uint i= 0; i < item_func->arg_count_field; i++)
2760
2911
  {
2761
2912
    Item *item= item_func->args[i];
2762
2913
    /* 
2772
2923
    */
2773
2924
    Field *field= item->get_tmp_table_field();
2774
2925
    int res;
2775
 
    uint32_t offset= field->offset(field->table->record[0])-table->s->null_bytes;
2776
 
    if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
 
2926
    uint offset= field->offset(field->table->record[0])-table->s->null_bytes;
 
2927
    if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
2777
2928
      return res;
2778
2929
  }
2779
2930
  return 0;
2781
2932
 
2782
2933
 
2783
2934
/**
2784
 
  function of sort for syntax: GROUP_CONCAT(expr,... order_st BY col,... )
 
2935
  function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
2785
2936
*/
2786
2937
 
2787
2938
int group_concat_key_cmp_with_order(void* arg, const void* key1, 
2788
2939
                                    const void* key2)
2789
2940
{
2790
2941
  Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2791
 
  order_st **order_item, **end;
2792
 
  Table *table= grp_item->table;
 
2942
  ORDER **order_item, **end;
 
2943
  TABLE *table= grp_item->table;
2793
2944
 
2794
2945
  for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
2795
2946
       order_item < end;
2809
2960
    if (field && !item->const_item())
2810
2961
    {
2811
2962
      int res;
2812
 
      uint32_t offset= (field->offset(field->table->record[0]) -
 
2963
      uint offset= (field->offset(field->table->record[0]) -
2813
2964
                    table->s->null_bytes);
2814
 
      if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
 
2965
      if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
2815
2966
        return (*order_item)->asc ? res : -res;
2816
2967
    }
2817
2968
  }
2828
2979
  Append data from current leaf to item->result.
2829
2980
*/
2830
2981
 
2831
 
int dump_leaf_key(unsigned char* key, element_count count __attribute__((unused)),
 
2982
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
2832
2983
                  Item_func_group_concat *item)
2833
2984
{
2834
 
  Table *table= item->table;
 
2985
  TABLE *table= item->table;
2835
2986
  String tmp((char *)table->record[1], table->s->reclength,
2836
2987
             default_charset_info);
2837
2988
  String tmp2;
2838
2989
  String *result= &item->result;
2839
2990
  Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
2840
 
  uint32_t old_length= result->length();
 
2991
  uint old_length= result->length();
2841
2992
 
2842
2993
  if (item->no_appended)
2843
2994
    item->no_appended= false;
2859
3010
        because it contains both order and arg list fields.
2860
3011
      */
2861
3012
      Field *field= (*arg)->get_tmp_table_field();
2862
 
      uint32_t offset= (field->offset(field->table->record[0]) -
 
3013
      uint offset= (field->offset(field->table->record[0]) -
2863
3014
                    table->s->null_bytes);
2864
3015
      assert(offset < table->s->reclength);
2865
3016
      res= field->val_str(&tmp, key + offset);
2874
3025
  if (result->length() > item->max_length)
2875
3026
  {
2876
3027
    int well_formed_error;
2877
 
    const CHARSET_INFO * const cs= item->collation.collation;
 
3028
    CHARSET_INFO *cs= item->collation.collation;
2878
3029
    const char *ptr= result->ptr();
2879
 
    uint32_t add_length;
 
3030
    uint add_length;
2880
3031
    /*
2881
3032
      It's ok to use item->result.length() as the fourth argument
2882
3033
      as this is never used to limit the length of the data.
2932
3083
    order - arg_count_order
2933
3084
  */
2934
3085
  if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
2935
 
                                 sizeof(order_st*)*arg_count_order)))
 
3086
                                 sizeof(ORDER*)*arg_count_order)))
2936
3087
    return;
2937
3088
 
2938
 
  order= (order_st**)(args + arg_count);
 
3089
  order= (ORDER**)(args + arg_count);
2939
3090
 
2940
3091
  /* fill args items of show and sort */
2941
3092
  List_iterator_fast<Item> li(*select_list);
2945
3096
 
2946
3097
  if (arg_count_order)
2947
3098
  {
2948
 
    order_st **order_ptr= order;
2949
 
    for (order_st *order_item= (order_st*) order_list->first;
 
3099
    ORDER **order_ptr= order;
 
3100
    for (ORDER *order_item= (ORDER*) order_list->first;
2950
3101
         order_item != NULL;
2951
3102
         order_item= order_item->next)
2952
3103
    {
2991
3142
  /* Adjust warning message to include total number of cut values */
2992
3143
  if (warning)
2993
3144
  {
2994
 
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
3145
    char warn_buff[MYSQL_ERRMSG_SIZE];
2995
3146
    sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
2996
3147
    warning->set_msg(current_thd, warn_buff);
2997
3148
    warning= 0;
3008
3159
    if (table)
3009
3160
    {
3010
3161
      THD *thd= table->in_use;
3011
 
      table->free_tmp_table(thd);
 
3162
      free_tmp_table(thd, table);
3012
3163
      table= 0;
3013
3164
      if (tree)
3014
3165
      {
3022
3173
      }
3023
3174
      if (warning)
3024
3175
      {
3025
 
        char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
3176
        char warn_buff[MYSQL_ERRMSG_SIZE];
3026
3177
        sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3027
3178
        warning->set_msg(thd, warn_buff);
3028
3179
        warning= 0;
3062
3213
  copy_fields(tmp_table_param);
3063
3214
  copy_funcs(tmp_table_param->items_to_copy);
3064
3215
 
3065
 
  for (uint32_t i= 0; i < arg_count_field; i++)
 
3216
  for (uint i= 0; i < arg_count_field; i++)
3066
3217
  {
3067
3218
    Item *show_item= args[i];
3068
3219
    if (!show_item->const_item())
3069
3220
    {
3070
3221
      Field *f= show_item->get_tmp_table_field();
3071
 
      if (f->is_null_in_record((const unsigned char*) table->record[0]))
 
3222
      if (f->is_null_in_record((const uchar*) table->record[0]))
3072
3223
        return 0;                               // Skip row if it contains null
3073
3224
    }
3074
3225
  }
3079
3230
  if (distinct) 
3080
3231
  {
3081
3232
    /* Filter out duplicate rows. */
3082
 
    uint32_t count= unique_filter->elements_in_tree();
 
3233
    uint count= unique_filter->elements_in_tree();
3083
3234
    unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3084
3235
    if (count == unique_filter->elements_in_tree())
3085
3236
      row_eligible= false;
3105
3256
bool
3106
3257
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3107
3258
{
3108
 
  uint32_t i;                       /* for loop variable */
 
3259
  uint i;                       /* for loop variable */
3109
3260
  assert(fixed == 0);
3110
3261
 
3111
3262
  if (init_sum_func_check(thd))
3114
3265
  maybe_null= 1;
3115
3266
 
3116
3267
  /*
3117
 
    Fix fields for select list and order_st clause
 
3268
    Fix fields for select list and ORDER clause
3118
3269
  */
3119
3270
 
3120
3271
  for (i=0 ; i < arg_count ; i++)
3137
3288
  null_value= 1;
3138
3289
  max_length= thd->variables.group_concat_max_len;
3139
3290
 
3140
 
  uint32_t offset;
 
3291
  uint32 offset;
3141
3292
  if (separator->needs_conversion(separator->length(), separator->charset(),
3142
3293
                                  collation.collation, &offset))
3143
3294
  {
3144
 
    uint32_t buflen= collation.collation->mbmaxlen * separator->length();
3145
 
    uint32_t errors, conv_length;
 
3295
    uint32 buflen= collation.collation->mbmaxlen * separator->length();
 
3296
    uint errors, conv_length;
3146
3297
    char *buf;
3147
3298
    String *new_separator;
3148
3299
 
3149
 
    if (!(buf= (char*) thd->alloc(buflen)) ||
3150
 
        !(new_separator= new(thd->mem_root)
 
3300
    if (!(buf= (char*) thd->stmt_arena->alloc(buflen)) ||
 
3301
        !(new_separator= new(thd->stmt_arena->mem_root)
3151
3302
                           String(buf, buflen, collation.collation)))
3152
3303
      return true;
3153
3304
    
3186
3337
                                        collation.collation->mbmaxlen;
3187
3338
  /* Push all not constant fields to the list and create a temp table */
3188
3339
  always_null= 0;
3189
 
  for (uint32_t i= 0; i < arg_count_field; i++)
 
3340
  for (uint i= 0; i < arg_count_field; i++)
3190
3341
  {
3191
3342
    Item *item= args[i];
3192
3343
    if (list.push_back(item))
3203
3354
 
3204
3355
  List<Item> all_fields(list);
3205
3356
  /*
3206
 
    Try to find every order_st expression in the list of GROUP_CONCAT
 
3357
    Try to find every ORDER expression in the list of GROUP_CONCAT
3207
3358
    arguments. If an expression is not found, prepend it to
3208
3359
    "all_fields". The resulting field list is used as input to create
3209
3360
    tmp table columns.
3219
3370
  {
3220
3371
    /*
3221
3372
      Currently we have to force conversion of BLOB values to VARCHAR's
3222
 
      if we are to store them in TREE objects used for order_st BY and
 
3373
      if we are to store them in TREE objects used for ORDER BY and
3223
3374
      DISTINCT. This leads to truncation if the BLOB's size exceeds
3224
3375
      Field_varstring::MAX_SIZE.
3225
3376
    */
3231
3382
    We have to create a temporary table to get descriptions of fields
3232
3383
    (types, sizes and so on).
3233
3384
 
3234
 
    Note that in the table, we first have the order_st BY fields, then the
 
3385
    Note that in the table, we first have the ORDER BY fields, then the
3235
3386
    field list.
3236
3387
  */
3237
3388
  if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
3238
 
                                (order_st*) 0, 0, true,
 
3389
                                (ORDER*) 0, 0, true,
3239
3390
                                (select_lex->options | thd->options),
3240
3391
                                HA_POS_ERROR, (char*) "")))
3241
3392
    return(true);
3247
3398
     Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3248
3399
     the row is not added to the result.
3249
3400
  */
3250
 
  uint32_t tree_key_length= table->s->reclength - table->s->null_bytes;
 
3401
  uint tree_key_length= table->s->reclength - table->s->null_bytes;
3251
3402
 
3252
3403
  if (arg_count_order)
3253
3404
  {
3254
3405
    tree= &tree_base;
3255
3406
    /*
3256
3407
      Create a tree for sorting. The tree is used to sort (according to the
3257
 
      syntax of this function). If there is no order_st BY clause, we don't
 
3408
      syntax of this function). If there is no ORDER BY clause, we don't
3258
3409
      create this tree.
3259
3410
    */
3260
 
    init_tree(tree, (uint) cmin(thd->variables.max_heap_table_size,
 
3411
    init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
3261
3412
                               thd->variables.sortbuff_size/16), 0,
3262
3413
              tree_key_length, 
3263
3414
              group_concat_key_cmp_with_order , 0, NULL, (void*) this);
3285
3436
}
3286
3437
 
3287
3438
 
3288
 
String* Item_func_group_concat::val_str(String* str __attribute__((unused)))
 
3439
String* Item_func_group_concat::val_str(String* str __attribute__((__unused__)))
3289
3440
{
3290
3441
  assert(fixed == 1);
3291
3442
  if (null_value)
3301
3452
      Item_func_group_concat::cleanup().
3302
3453
    */
3303
3454
    assert(table);
3304
 
    warning= push_warning(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
3455
    warning= push_warning(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
3305
3456
                          ER_CUT_VALUE_GROUP_CONCAT,
3306
3457
                          ER(ER_CUT_VALUE_GROUP_CONCAT));
3307
3458
  }
3314
3465
  str->append(STRING_WITH_LEN("group_concat("));
3315
3466
  if (distinct)
3316
3467
    str->append(STRING_WITH_LEN("distinct "));
3317
 
  for (uint32_t i= 0; i < arg_count_field; i++)
 
3468
  for (uint i= 0; i < arg_count_field; i++)
3318
3469
  {
3319
3470
    if (i)
3320
3471
      str->append(',');
3323
3474
  if (arg_count_order)
3324
3475
  {
3325
3476
    str->append(STRING_WITH_LEN(" order by "));
3326
 
    for (uint32_t i= 0 ; i < arg_count_order ; i++)
 
3477
    for (uint i= 0 ; i < arg_count_order ; i++)
3327
3478
    {
3328
3479
      if (i)
3329
3480
        str->append(',');