item_sum.h 21.8 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
unknown's avatar
unknown committed
2

unknown's avatar
unknown committed
3 4 5 6
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
unknown's avatar
unknown committed
7

unknown's avatar
unknown committed
8 9 10 11
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
unknown's avatar
unknown committed
12

unknown's avatar
unknown committed
13 14 15 16 17 18 19 20 21 22 23
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


/* classes for sum functions */

#ifdef __GNUC__
#pragma interface			/* gcc class implementation */
#endif

24 25
#include <my_tree.h>

unknown's avatar
unknown committed
26 27 28
class Item_sum :public Item_result_field
{
public:
29 30 31 32 33
  enum Sumfunctype
  { COUNT_FUNC,COUNT_DISTINCT_FUNC,SUM_FUNC,AVG_FUNC,MIN_FUNC,
    MAX_FUNC, UNIQUE_USERS_FUNC,STD_FUNC,VARIANCE_FUNC,SUM_BIT_FUNC,
    UDF_SUM_FUNC, GROUP_CONCAT_FUNC
  };
unknown's avatar
unknown committed
34 35 36 37 38

  Item **args,*tmp_args[2];
  uint arg_count;
  bool quick_group;			/* If incremental update of fields */

39
  void mark_as_sum_func();
40 41 42 43
  Item_sum() : arg_count(0),quick_group(1) 
  {
    mark_as_sum_func();
  }
unknown's avatar
unknown committed
44 45 46 47 48
  Item_sum(Item *a) :quick_group(1)
  {
    arg_count=1;
    args=tmp_args;
    args[0]=a;
49
    mark_as_sum_func();
unknown's avatar
unknown committed
50 51 52 53 54 55
  }
  Item_sum( Item *a, Item *b ) :quick_group(1)
  {
    arg_count=2;
    args=tmp_args;
    args[0]=a; args[1]=b;
56
    mark_as_sum_func();
unknown's avatar
unknown committed
57 58
  }
  Item_sum(List<Item> &list);
59
  //Copy constructor, need to perform subselects with temporary tables
60
  Item_sum(THD *thd, Item_sum &item);
unknown's avatar
unknown committed
61
  ~Item_sum() { result_field=0; }
62

unknown's avatar
unknown committed
63 64
  enum Type type() const { return SUM_FUNC_ITEM; }
  virtual enum Sumfunctype sum_func () const=0;
65 66
  inline bool reset() { clear(); return add(); };
  virtual void clear()= 0;
unknown's avatar
unknown committed
67 68
  virtual bool add()=0;
  virtual void reset_field()=0;
unknown's avatar
unknown committed
69
  virtual void update_field()=0;
unknown's avatar
unknown committed
70 71 72 73 74 75 76
  virtual bool keep_field_type(void) const { return 0; }
  virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
  virtual const char *func_name() const { return "?"; }
  virtual Item *result_item(Field *field)
  { return new Item_field(field);}
  table_map used_tables() const { return ~(table_map) 0; } /* Not used */
  bool const_item() const { return 0; }
77
  bool is_null() { return null_value; }
unknown's avatar
unknown committed
78 79 80 81
  void update_used_tables() { }
  void make_field(Send_field *field);
  void print(String *str);
  void fix_num_length_and_dec();
unknown's avatar
unknown committed
82
  void no_rows_in_result() { reset(); }
unknown's avatar
unknown committed
83
  virtual bool setup(THD *thd) {return 0;}
84
  virtual void make_unique() {}
85
  Item *get_tmp_table_item(THD *thd);
unknown's avatar
unknown committed
86 87 88 89 90 91 92 93 94 95
};


class Item_sum_num :public Item_sum
{
public:
  Item_sum_num() :Item_sum() {}
  Item_sum_num(Item *item_par) :Item_sum(item_par) {}
  Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
  Item_sum_num(List<Item> &list) :Item_sum(list) {}
96
  Item_sum_num(THD *thd, Item_sum_num &item) :Item_sum(thd, item) {}
unknown's avatar
unknown committed
97
  bool fix_fields(THD *, TABLE_LIST *, Item **);
unknown's avatar
unknown committed
98 99 100 101 102 103 104 105 106 107 108
  longlong val_int() { return (longlong) val(); } /* Real as default */
  String *val_str(String*str);
  void reset_field();
};


class Item_sum_int :public Item_sum_num
{
public:
  Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
  Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
109
  Item_sum_int(THD *thd, Item_sum_int &item) :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
110 111 112
  double val() { return (double) val_int(); }
  String *val_str(String*str);
  enum Item_result result_type () const { return INT_RESULT; }
unknown's avatar
unknown committed
113 114
  void fix_length_and_dec()
  { decimals=0; max_length=21; maybe_null=null_value=0; }
unknown's avatar
unknown committed
115 116 117 118 119 120 121 122 123 124
};


class Item_sum_sum :public Item_sum_num
{
  double sum;
  void fix_length_and_dec() { maybe_null=null_value=1; }

  public:
  Item_sum_sum(Item *item_par) :Item_sum_num(item_par),sum(0.0) {}
125 126
  Item_sum_sum(THD *thd, Item_sum_sum &item) 
    :Item_sum_num(thd, item), sum(item.sum) {}
unknown's avatar
unknown committed
127
  enum Sumfunctype sum_func () const {return SUM_FUNC;}
128
  void clear();
unknown's avatar
unknown committed
129 130 131
  bool add();
  double val();
  void reset_field();
unknown's avatar
unknown committed
132
  void update_field();
unknown's avatar
unknown committed
133
  void no_rows_in_result() {}
unknown's avatar
unknown committed
134
  const char *func_name() const { return "sum"; }
135
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
136 137 138 139 140 141 142 143 144 145 146 147
};


class Item_sum_count :public Item_sum_int
{
  longlong count;
  table_map used_table_cache;

  public:
  Item_sum_count(Item *item_par)
    :Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0)
  {}
148 149 150
  Item_sum_count(THD *thd, Item_sum_count &item)
    :Item_sum_int(thd, item), count(item.count),
     used_table_cache(item.used_table_cache)
151
  {}
unknown's avatar
unknown committed
152 153 154
  table_map used_tables() const { return used_table_cache; }
  bool const_item() const { return !used_table_cache; }
  enum Sumfunctype sum_func () const { return COUNT_FUNC; }
155
  void clear();
unknown's avatar
unknown committed
156
  void no_rows_in_result() { count=0; }
unknown's avatar
unknown committed
157 158 159 160
  bool add();
  void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
  longlong val_int();
  void reset_field();
unknown's avatar
unknown committed
161
  void update_field();
unknown's avatar
unknown committed
162
  const char *func_name() const { return "count"; }
163
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
164 165 166 167 168 169 170 171 172
};


class TMP_TABLE_PARAM;

class Item_sum_count_distinct :public Item_sum_int
{
  TABLE *table;
  table_map used_table_cache;
unknown's avatar
unknown committed
173
  bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
unknown's avatar
unknown committed
174
  uint32 *field_lengths;
unknown's avatar
unknown committed
175
  TMP_TABLE_PARAM *tmp_table_param;
176 177 178 179 180 181 182 183
  TREE tree_base;
  TREE *tree;
  /*
    Following is 0 normal object and pointer to original one for copy 
    (to correctly free resources)
  */
  Item_sum_count_distinct *original;

184
  uint key_length;
185 186
  CHARSET_INFO *key_charset;
  
187 188
  // calculated based on max_heap_table_size. If reached,
  // walk the tree and dump it into MyISAM table
unknown's avatar
unknown committed
189
  uint max_elements_in_tree;
unknown's avatar
merge  
unknown committed
190 191 192 193 194

  // the first few bytes of record ( at least one)
  // are just markers for deleted and NULLs. We want to skip them since
  // they will just bloat the tree without providing any valuable info
  int rec_offset;
unknown's avatar
unknown committed
195

196
  // If there are no blobs, we can use a tree, which
197 198
  // is faster than heap table. In that case, we still use the table
  // to help get things set up, but we insert nothing in it
unknown's avatar
unknown committed
199
  bool use_tree;
unknown's avatar
merge  
unknown committed
200
  bool always_null;		// Set to 1 if the result is always NULL
201

202
  int tree_to_myisam();
unknown's avatar
unknown committed
203

204
  friend int composite_key_cmp(void* arg, byte* key1, byte* key2);
205 206
  friend int simple_str_key_cmp(void* arg, byte* key1, byte* key2);
  friend int simple_raw_key_cmp(void* arg, byte* key1, byte* key2);
207
  friend int dump_leaf(byte* key, uint32 count __attribute__((unused)),
208
		       Item_sum_count_distinct* item);
209

unknown's avatar
unknown committed
210 211
  public:
  Item_sum_count_distinct(List<Item> &list)
212 213 214 215
    :Item_sum_int(list), table(0), used_table_cache(~(table_map) 0),
     tmp_table_param(0), tree(&tree_base), original(0), use_tree(0),
     always_null(0)
  { quick_group= 0; }
216 217 218 219 220 221 222 223 224
  Item_sum_count_distinct(THD *thd, Item_sum_count_distinct &item)
    :Item_sum_int(thd, item), table(item.table),
     used_table_cache(item.used_table_cache),
     field_lengths(item.field_lengths), tmp_table_param(item.tmp_table_param),
     tree(item.tree), original(&item), key_length(item.key_length),
     max_elements_in_tree(item.max_elements_in_tree),
     rec_offset(item.rec_offset), use_tree(item.use_tree),
     always_null(item.always_null)
  {}
unknown's avatar
unknown committed
225
  ~Item_sum_count_distinct();
226

unknown's avatar
unknown committed
227 228
  table_map used_tables() const { return used_table_cache; }
  enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
229
  void clear();
unknown's avatar
unknown committed
230 231 232
  bool add();
  longlong val_int();
  void reset_field() { return ;}		// Never called
unknown's avatar
unknown committed
233
  void update_field() { return ; }		// Never called
unknown's avatar
unknown committed
234 235
  const char *func_name() const { return "count_distinct"; }
  bool setup(THD *thd);
236 237
  void make_unique();
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
238
  void no_rows_in_result() {}
unknown's avatar
unknown committed
239 240 241 242 243
};


/* Item to get the value of a stored sum function */

244 245
class Item_sum_avg;

unknown's avatar
unknown committed
246 247 248 249 250 251 252 253
class Item_avg_field :public Item_result_field
{
public:
  Field *field;
  Item_avg_field(Item_sum_avg *item);
  enum Type type() const { return FIELD_AVG_ITEM; }
  double val();
  longlong val_int() { return (longlong) val(); }
254
  bool is_null() { (void) val_int(); return null_value; }
unknown's avatar
unknown committed
255
  String *val_str(String*);
256
  enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
unknown's avatar
unknown committed
257 258 259 260 261 262 263 264 265 266 267 268 269
  void fix_length_and_dec() {}
};


class Item_sum_avg :public Item_sum_num
{
  void fix_length_and_dec() { decimals+=4; maybe_null=1; }

  double sum;
  ulonglong count;

  public:
  Item_sum_avg(Item *item_par) :Item_sum_num(item_par),count(0) {}
270 271
  Item_sum_avg(THD *thd, Item_sum_avg &item)
    :Item_sum_num(thd, item), sum(item.sum), count(item.count) {}
unknown's avatar
unknown committed
272
  enum Sumfunctype sum_func () const {return AVG_FUNC;}
273
  void clear();
unknown's avatar
unknown committed
274 275 276
  bool add();
  double val();
  void reset_field();
unknown's avatar
unknown committed
277
  void update_field();
unknown's avatar
unknown committed
278 279 280
  Item *result_item(Field *field)
  { return new Item_avg_field(this); }
  const char *func_name() const { return "avg"; }
281
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
282 283
};

unknown's avatar
unknown committed
284
class Item_sum_variance;
unknown's avatar
unknown committed
285

unknown's avatar
unknown committed
286
class Item_variance_field :public Item_result_field
unknown's avatar
unknown committed
287 288 289
{
public:
  Field *field;
unknown's avatar
unknown committed
290 291
  Item_variance_field(Item_sum_variance *item);
  enum Type type() const {return FIELD_VARIANCE_ITEM; }
unknown's avatar
unknown committed
292 293 294
  double val();
  longlong val_int() { return (longlong) val(); }
  String *val_str(String*);
295
  bool is_null() { (void) val_int(); return null_value; }
296
  enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
unknown's avatar
unknown committed
297 298 299
  void fix_length_and_dec() {}
};

unknown's avatar
unknown committed
300 301 302 303
/*

variance(a) =

304 305 306 307 308 309 310
= sum (ai - avg(a))^2 / count(a) )
=  sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a)
=  (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) = 
=  (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) = 
=  (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) = 
=  (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) = 
=  (sum(ai^2) - sum(a)^2/count(a))/count(a)
unknown's avatar
unknown committed
311

312
*/
unknown's avatar
unknown committed
313 314

class Item_sum_variance : public Item_sum_num
unknown's avatar
unknown committed
315
{
unknown's avatar
unknown committed
316
  double sum, sum_sqr;
unknown's avatar
unknown committed
317 318 319 320
  ulonglong count;
  void fix_length_and_dec() { decimals+=4; maybe_null=1; }

  public:
unknown's avatar
unknown committed
321
  Item_sum_variance(Item *item_par) :Item_sum_num(item_par),count(0) {}
322 323
  Item_sum_variance(THD *thd, Item_sum_variance &item):
    Item_sum_num(thd, item), sum(item.sum), sum_sqr(item.sum_sqr),
324
    count(item.count) {}
unknown's avatar
unknown committed
325
  enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
326
  void clear();
unknown's avatar
unknown committed
327 328 329
  bool add();
  double val();
  void reset_field();
unknown's avatar
unknown committed
330
  void update_field();
unknown's avatar
unknown committed
331
  Item *result_item(Field *field)
unknown's avatar
unknown committed
332 333
  { return new Item_variance_field(this); }
  const char *func_name() const { return "variance"; }
334
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
335 336 337 338 339 340 341 342 343 344
};

class Item_sum_std;

class Item_std_field :public Item_variance_field
{
public:
  Item_std_field(Item_sum_std *item);
  enum Type type() const { return FIELD_STD_ITEM; }
  double val();
345 346 347 348 349 350 351 352 353
};

/*
   standard_deviation(a) = sqrt(variance(a))
*/

class Item_sum_std :public Item_sum_variance
{
  public:
354 355 356 357
  Item_sum_std(Item *item_par) :Item_sum_variance(item_par) {}
  Item_sum_std(THD *thd, Item_sum_std &item)
    :Item_sum_variance(thd, item)
    {}
358 359 360 361 362
  enum Sumfunctype sum_func () const { return STD_FUNC; }
  double val();
  Item *result_item(Field *field)
    { return new Item_std_field(this); }
  const char *func_name() const { return "std"; }
363
  Item *copy_or_same(THD* thd);
364
};
unknown's avatar
unknown committed
365 366 367 368 369 370 371 372

// This class is a string or number function depending on num_func

class Item_sum_hybrid :public Item_sum
{
 protected:
  String value,tmp_value;
  double sum;
373
  longlong sum_int;
unknown's avatar
unknown committed
374
  Item_result hybrid_type;
375
  enum_field_types hybrid_field_type;
unknown's avatar
unknown committed
376 377
  int cmp_sign;
  table_map used_table_cache;
378
  CHARSET_INFO *cmp_charset;
unknown's avatar
unknown committed
379 380

  public:
381 382
  Item_sum_hybrid(Item *item_par,int sign)
    :Item_sum(item_par), hybrid_type(INT_RESULT), cmp_sign(sign),
383 384
    used_table_cache(~(table_map) 0),
    cmp_charset(&my_charset_bin)
unknown's avatar
unknown committed
385
  {}
386 387
  Item_sum_hybrid(THD *thd, Item_sum_hybrid &item):
    Item_sum(thd, item), value(item.value), tmp_value(item.tmp_value),
388
    sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type),
unknown's avatar
BUG  
unknown committed
389
    hybrid_field_type(item.hybrid_field_type),cmp_sign(item.cmp_sign), 
390
    used_table_cache(item.used_table_cache), cmp_charset(item.cmp_charset) {}
unknown's avatar
unknown committed
391
  bool fix_fields(THD *, TABLE_LIST *, Item **);
unknown's avatar
unknown committed
392 393 394
  table_map used_tables() const { return used_table_cache; }
  bool const_item() const { return !used_table_cache; }

395
  void clear()
unknown's avatar
unknown committed
396 397
  {
    sum=0.0;
398
    sum_int=0;
unknown's avatar
unknown committed
399 400 401 402
    value.length(0);
    null_value=1;
  }
  double val();
403
  longlong val_int();
unknown's avatar
unknown committed
404 405 406 407 408
  void reset_field();
  String *val_str(String *);
  void make_const() { used_table_cache=0; }
  bool keep_field_type(void) const { return 1; }
  enum Item_result result_type () const { return hybrid_type; }
409
  enum enum_field_types field_type() const { return hybrid_field_type; }
unknown's avatar
unknown committed
410 411 412 413
  void update_field();
  void min_max_update_str_field();
  void min_max_update_real_field();
  void min_max_update_int_field();
unknown's avatar
unknown committed
414 415 416 417 418 419 420
};


class Item_sum_min :public Item_sum_hybrid
{
public:
  Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
421
  Item_sum_min(THD *thd, Item_sum_min &item) :Item_sum_hybrid(thd, item) {}
unknown's avatar
unknown committed
422 423 424 425
  enum Sumfunctype sum_func () const {return MIN_FUNC;}

  bool add();
  const char *func_name() const { return "min"; }
426
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
427 428 429 430 431 432 433
};


class Item_sum_max :public Item_sum_hybrid
{
public:
  Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
434
  Item_sum_max(THD *thd, Item_sum_max &item) :Item_sum_hybrid(thd, item) {}
unknown's avatar
unknown committed
435 436 437 438
  enum Sumfunctype sum_func () const {return MAX_FUNC;}

  bool add();
  const char *func_name() const { return "max"; }
439
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
440 441 442 443 444 445 446 447 448 449 450
};


class Item_sum_bit :public Item_sum_int
{
 protected:
  ulonglong reset_bits,bits;

  public:
  Item_sum_bit(Item *item_par,ulonglong reset_arg)
    :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
451 452
  Item_sum_bit(THD *thd, Item_sum_bit &item):
    Item_sum_int(thd, item), reset_bits(item.reset_bits), bits(item.bits) {}
unknown's avatar
unknown committed
453
  enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
454
  void clear();
unknown's avatar
unknown committed
455 456
  longlong val_int();
  void reset_field();
unknown's avatar
unknown committed
457 458
  void fix_length_and_dec()
  { decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; }
unknown's avatar
unknown committed
459 460 461 462 463 464 465
};


class Item_sum_or :public Item_sum_bit
{
  public:
  Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
466
  Item_sum_or(THD *thd, Item_sum_or &item) :Item_sum_bit(thd, item) {}
unknown's avatar
unknown committed
467
  bool add();
unknown's avatar
unknown committed
468
  void update_field();
unknown's avatar
unknown committed
469
  const char *func_name() const { return "bit_or"; }
470
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
471 472 473 474 475 476 477
};


class Item_sum_and :public Item_sum_bit
{
  public:
  Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
478
  Item_sum_and(THD *thd, Item_sum_and &item) :Item_sum_bit(thd, item) {}
unknown's avatar
unknown committed
479
  bool add();
unknown's avatar
unknown committed
480
  void update_field();
unknown's avatar
unknown committed
481
  const char *func_name() const { return "bit_and"; }
482
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
};

/*
**	user defined aggregates
*/
#ifdef HAVE_DLOPEN

class Item_udf_sum : public Item_sum
{
protected:
  udf_handler udf;

public:
  Item_udf_sum(udf_func *udf_arg) :Item_sum(), udf(udf_arg) { quick_group=0;}
  Item_udf_sum( udf_func *udf_arg, List<Item> &list )
    :Item_sum( list ), udf(udf_arg)
  { quick_group=0;}
500 501
  Item_udf_sum(THD *thd, Item_udf_sum &item)
    :Item_sum(thd, item), udf(item.udf) {}
unknown's avatar
unknown committed
502 503
  ~Item_udf_sum() {}
  const char *func_name() const { return udf.name(); }
unknown's avatar
unknown committed
504
  bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
unknown's avatar
unknown committed
505
  {
506
    fixed= 1;
unknown's avatar
unknown committed
507 508 509 510 511
    return udf.fix_fields(thd,tables,this,this->arg_count,this->args);
  }
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  virtual bool have_field_update(void) const { return 0; }

512
  void clear();
unknown's avatar
unknown committed
513 514
  bool add();
  void reset_field() {};
unknown's avatar
unknown committed
515
  void update_field() {};
unknown's avatar
unknown committed
516 517 518 519 520 521 522 523 524
};


class Item_sum_udf_float :public Item_udf_sum
{
 public:
  Item_sum_udf_float(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
    :Item_udf_sum(udf_arg,list) {}
525 526
  Item_sum_udf_float(THD *thd, Item_sum_udf_float &item)
    :Item_udf_sum(thd, item) {}
unknown's avatar
unknown committed
527 528 529 530 531
  ~Item_sum_udf_float() {}
  longlong val_int() { return (longlong) Item_sum_udf_float::val(); }
  double val();
  String *val_str(String*str);
  void fix_length_and_dec() { fix_num_length_and_dec(); }
532
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
533 534 535 536 537 538 539 540 541
};


class Item_sum_udf_int :public Item_udf_sum
{
public:
  Item_sum_udf_int(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
    :Item_udf_sum(udf_arg,list) {}
542 543
  Item_sum_udf_int(THD *thd, Item_sum_udf_int &item)
    :Item_udf_sum(thd, item) {}
unknown's avatar
unknown committed
544 545 546 547 548 549
  ~Item_sum_udf_int() {}
  longlong val_int();
  double val() { return (double) Item_sum_udf_int::val_int(); }
  String *val_str(String*str);
  enum Item_result result_type () const { return INT_RESULT; }
  void fix_length_and_dec() { decimals=0; max_length=21; }
550
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
551 552 553 554 555 556 557 558 559
};


class Item_sum_udf_str :public Item_udf_sum
{
public:
  Item_sum_udf_str(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
    :Item_udf_sum(udf_arg,list) {}
560 561
  Item_sum_udf_str(THD *thd, Item_sum_udf_str &item)
    :Item_udf_sum(thd, item) {}
unknown's avatar
unknown committed
562 563 564 565
  ~Item_sum_udf_str() {}
  String *val_str(String *);
  double val()
  {
566
    int err;
unknown's avatar
unknown committed
567
    String *res;  res=val_str(&str_value);
568
    return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
569
			    (char**) 0, &err) : 0.0;
unknown's avatar
unknown committed
570 571 572
  }
  longlong val_int()
  {
573
    int err;
unknown's avatar
unknown committed
574
    String *res;  res=val_str(&str_value);
575
    return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, (char**) 0, &err) : (longlong) 0;
unknown's avatar
unknown committed
576 577 578
  }
  enum Item_result result_type () const { return STRING_RESULT; }
  void fix_length_and_dec();
579
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
580 581 582 583 584 585 586 587 588
};

#else /* Dummy functions to get sql_yacc.cc compiled */

class Item_sum_udf_float :public Item_sum_num
{
 public:
  Item_sum_udf_float(udf_func *udf_arg) :Item_sum_num() {}
  Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
589 590
  Item_sum_udf_float(THD *thd, Item_sum_udf_float &item)
    :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
591 592 593
  ~Item_sum_udf_float() {}
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  double val() { return 0.0; }
unknown's avatar
unknown committed
594
  void clear() {}
unknown's avatar
unknown committed
595
  bool add() { return 0; }  
unknown's avatar
unknown committed
596
  void update_field() {}
unknown's avatar
unknown committed
597 598 599 600 601 602 603 604
};


class Item_sum_udf_int :public Item_sum_num
{
public:
  Item_sum_udf_int(udf_func *udf_arg) :Item_sum_num() {}
  Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
605 606
  Item_sum_udf_int(THD *thd, Item_sum_udf_int &item)
    :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
607 608 609 610
  ~Item_sum_udf_int() {}
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  longlong val_int() { return 0; }
  double val() { return 0; }
611
  void clear() {}
unknown's avatar
unknown committed
612
  bool add() { return 0; }  
unknown's avatar
unknown committed
613
  void update_field() {}
unknown's avatar
unknown committed
614 615 616 617 618 619 620 621
};


class Item_sum_udf_str :public Item_sum_num
{
public:
  Item_sum_udf_str(udf_func *udf_arg) :Item_sum_num() {}
  Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)  :Item_sum_num() {}
622 623
  Item_sum_udf_str(THD *thd, Item_sum_udf_str &item)
    :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
624 625 626 627 628 629 630
  ~Item_sum_udf_str() {}
  String *val_str(String *) { null_value=1; return 0; }
  double val() { null_value=1; return 0.0; }
  longlong val_int() { null_value=1; return 0; }
  enum Item_result result_type () const { return STRING_RESULT; }
  void fix_length_and_dec() { maybe_null=1; max_length=0; }
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
631
  void clear() {}
unknown's avatar
unknown committed
632
  bool add() { return 0; }  
unknown's avatar
unknown committed
633
  void update_field() {}
unknown's avatar
unknown committed
634 635 636
};

#endif /* HAVE_DLOPEN */
637

638 639
class MYSQL_ERROR;

640 641 642 643 644
class Item_func_group_concat : public Item_sum
{
  THD *item_thd;
  TMP_TABLE_PARAM *tmp_table_param;
  uint max_elements_in_tree;
645
  MYSQL_ERROR *warning;
646
  bool warning_available;
unknown's avatar
unknown committed
647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
  uint key_length;
  int rec_offset;
  bool tree_mode;
  bool distinct;
  bool warning_for_row;
  bool always_null;

  friend int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
					      byte* key2);
  friend int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2);
  friend int group_concat_key_cmp_with_distinct_and_order(void* arg,
							byte* key1,
							byte* key2);
  friend int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
                  Item_func_group_concat *group_concat_item);

663 664 665 666 667 668 669
 public:
  String result;
  String *separator;
  TREE tree_base;
  TREE *tree;
  TABLE *table;
  ORDER **order;
unknown's avatar
unknown committed
670
  TABLE_LIST *tables_list;
671
  ulong group_concat_max_len;
unknown's avatar
unknown committed
672 673 674 675 676
  uint show_elements;
  uint arg_count_order;
  uint arg_count_field;
  uint arg_show_fields;
  uint count_cut_values;
677 678 679 680 681 682
  /*
    Following is 0 normal object and pointer to original one for copy 
    (to correctly free resources)
  */
  Item_func_group_concat *original;
  
unknown's avatar
unknown committed
683
  Item_func_group_concat(bool is_distinct,List<Item> *is_select,
684 685 686 687 688 689 690 691
                         SQL_LIST *is_order,String *is_separator);
			 
  Item_func_group_concat(THD *thd, Item_func_group_concat &item)
    :Item_sum(thd, item),item_thd(thd),
     tmp_table_param(item.tmp_table_param),
     max_elements_in_tree(item.max_elements_in_tree),
     warning(item.warning),
     warning_available(item.warning_available),
unknown's avatar
unknown committed
692 693
     key_length(item.key_length), 
     rec_offset(item.rec_offset), 
unknown's avatar
unknown committed
694
     tree_mode(item.tree_mode),
unknown's avatar
unknown committed
695 696
     distinct(item.distinct),
     warning_for_row(item.warning_for_row),
697
     separator(item.separator),
698
     tree(item.tree),
699
     table(item.table),
unknown's avatar
unknown committed
700 701 702 703
     order(item.order),
     tables_list(item.tables_list),
     group_concat_max_len(item.group_concat_max_len),
     show_elements(item.show_elements),
704 705 706 707 708 709
     arg_count_order(item.arg_count_order),
     arg_count_field(item.arg_count_field),
     arg_show_fields(item.arg_show_fields),
     count_cut_values(item.count_cut_values),
     original(&item)
    {
unknown's avatar
unknown committed
710
     quick_group= item.quick_group;
711 712 713 714 715 716
    };
  ~Item_func_group_concat();
  enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
  const char *func_name() const { return "group_concat"; }
  enum Type type() const { return SUM_FUNC_ITEM; }  
  virtual Item_result result_type () const { return STRING_RESULT; }
717
  void clear();
718 719 720 721
  bool add();
  void reset_field();
  bool fix_fields(THD *, TABLE_LIST *, Item **);
  bool setup(THD *thd);
722
  void make_unique();
unknown's avatar
unknown committed
723
  virtual void update_field() {}
724 725 726 727 728 729 730 731 732 733 734
  double val()
  {
    String *res;  res=val_str(&str_value);
    return res ? atof(res->c_ptr()) : 0.0;
  }
  longlong val_int()
  {
    String *res;  res=val_str(&str_value);
    return res ? strtoll(res->c_ptr(),(char**) 0,10) : (longlong) 0;
  }
  String* val_str(String* str);
735
  Item *copy_or_same(THD* thd);
unknown's avatar
BUG  
unknown committed
736
  void no_rows_in_result() {}
737
};