item_sum.h 19 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 29
class Item_sum :public Item_result_field
{
public:
  enum Sumfunctype {COUNT_FUNC,COUNT_DISTINCT_FUNC,SUM_FUNC,AVG_FUNC,MIN_FUNC,
unknown's avatar
unknown committed
30
		    MAX_FUNC, UNIQUE_USERS_FUNC,STD_FUNC,VARIANCE_FUNC,SUM_BIT_FUNC,
unknown's avatar
unknown committed
31 32 33 34 35 36
		    UDF_SUM_FUNC };

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

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

unknown's avatar
unknown committed
61 62 63 64 65 66 67 68 69 70 71 72 73
  enum Type type() const { return SUM_FUNC_ITEM; }
  virtual enum Sumfunctype sum_func () const=0;
  virtual void reset()=0;
  virtual bool add()=0;
  virtual void reset_field()=0;
  virtual void update_field(int offset)=0;
  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; }
74
  bool is_null() { return null_value; }
unknown's avatar
unknown committed
75 76 77 78 79
  void update_used_tables() { }
  void make_field(Send_field *field);
  void print(String *str);
  void fix_num_length_and_dec();
  virtual bool setup(THD *thd) {return 0;}
80
  Item *get_tmp_table_item(THD *thd);
unknown's avatar
unknown committed
81 82 83 84 85 86 87 88 89 90
};


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) {}
91
  Item_sum_num(THD *thd, Item_sum_num &item) :Item_sum(thd, item) {}
unknown's avatar
unknown committed
92
  bool fix_fields(THD *, TABLE_LIST *, Item **);
unknown's avatar
unknown committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106
  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
{
  void fix_length_and_dec()
    { decimals=0; max_length=21; maybe_null=null_value=0; }

public:
  Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
  Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
107
  Item_sum_int(THD *thd, Item_sum_int &item) :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
108 109 110 111 112 113 114 115 116 117 118 119 120
  double val() { return (double) val_int(); }
  String *val_str(String*str);
  enum Item_result result_type () const { return INT_RESULT; }
};


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) {}
121 122
  Item_sum_sum(THD *thd, Item_sum_sum &item) 
    :Item_sum_num(thd, item), sum(item.sum) {}
unknown's avatar
unknown committed
123 124 125 126 127 128 129
  enum Sumfunctype sum_func () const {return SUM_FUNC;}
  void reset();
  bool add();
  double val();
  void reset_field();
  void update_field(int offset);
  const char *func_name() const { return "sum"; }
130
  Item *copy_or_same(THD* thd) { return new Item_sum_sum(thd, *this); }
unknown's avatar
unknown committed
131 132 133 134 135 136 137 138 139 140 141 142
};


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)
  {}
143 144 145
  Item_sum_count(THD *thd, Item_sum_count &item)
    :Item_sum_int(thd, item), count(item.count),
     used_table_cache(item.used_table_cache)
146
  {}
unknown's avatar
unknown committed
147 148 149 150 151 152 153 154 155 156
  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; }
  void reset();
  bool add();
  void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
  longlong val_int();
  void reset_field();
  void update_field(int offset);
  const char *func_name() const { return "count"; }
157
  Item *copy_or_same(THD* thd) { return new Item_sum_count(thd, *this); }
unknown's avatar
unknown committed
158 159 160 161 162 163 164 165 166
};


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
167
  bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
unknown's avatar
unknown committed
168
  uint32 *field_lengths;
unknown's avatar
unknown committed
169
  TMP_TABLE_PARAM *tmp_table_param;
170 171 172 173 174 175 176 177
  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;

178
  uint key_length;
179 180
  CHARSET_INFO *key_charset;
  
181 182
  // calculated based on max_heap_table_size. If reached,
  // walk the tree and dump it into MyISAM table
unknown's avatar
unknown committed
183
  uint max_elements_in_tree;
unknown's avatar
merge  
unknown committed
184 185 186 187 188

  // 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
189

190
  // If there are no blobs, we can use a tree, which
191 192
  // 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
193
  bool use_tree;
unknown's avatar
merge  
unknown committed
194
  bool always_null;		// Set to 1 if the result is always NULL
195

196
  int tree_to_myisam();
unknown's avatar
unknown committed
197

198
  friend int composite_key_cmp(void* arg, byte* key1, byte* key2);
199 200
  friend int simple_str_key_cmp(void* arg, byte* key1, byte* key2);
  friend int simple_raw_key_cmp(void* arg, byte* key1, byte* key2);
201
  friend int dump_leaf(byte* key, uint32 count __attribute__((unused)),
202
		       Item_sum_count_distinct* item);
203

unknown's avatar
unknown committed
204 205
  public:
  Item_sum_count_distinct(List<Item> &list)
206 207 208 209
    :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; }
210 211 212 213 214 215 216 217 218
  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
219 220 221 222 223 224 225 226 227 228
  ~Item_sum_count_distinct();
  table_map used_tables() const { return used_table_cache; }
  enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
  void reset();
  bool add();
  longlong val_int();
  void reset_field() { return ;}		// Never called
  void update_field(int offset) { return ; }	// Never called
  const char *func_name() const { return "count_distinct"; }
  bool setup(THD *thd);
229 230 231 232
  Item *copy_or_same(THD* thd) 
  {
    return new Item_sum_count_distinct(thd, *this);
  }
unknown's avatar
unknown committed
233 234 235 236 237
};


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

238 239
class Item_sum_avg;

unknown's avatar
unknown committed
240 241 242 243 244 245 246 247
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(); }
248
  bool is_null() { (void) val_int(); return null_value; }
unknown's avatar
unknown committed
249
  String *val_str(String*);
250
  enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
unknown's avatar
unknown committed
251 252 253 254 255 256 257 258 259 260 261 262 263
  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) {}
264 265
  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
266 267 268 269 270 271 272 273 274
  enum Sumfunctype sum_func () const {return AVG_FUNC;}
  void reset();
  bool add();
  double val();
  void reset_field();
  void update_field(int offset);
  Item *result_item(Field *field)
  { return new Item_avg_field(this); }
  const char *func_name() const { return "avg"; }
275
  Item *copy_or_same(THD* thd) { return new Item_sum_avg(thd, *this); }
unknown's avatar
unknown committed
276 277
};

unknown's avatar
unknown committed
278
class Item_sum_variance;
unknown's avatar
unknown committed
279

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

unknown's avatar
unknown committed
294 295 296 297
/*

variance(a) =

298 299 300 301 302 303 304
= 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
305

306
*/
unknown's avatar
unknown committed
307 308

class Item_sum_variance : public Item_sum_num
unknown's avatar
unknown committed
309
{
unknown's avatar
unknown committed
310
  double sum, sum_sqr;
unknown's avatar
unknown committed
311 312 313 314
  ulonglong count;
  void fix_length_and_dec() { decimals+=4; maybe_null=1; }

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

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();
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
};

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

class Item_sum_std :public Item_sum_variance
{
  public:
  Item_sum_std(Item *item_par) :Item_sum_variance(item_par){}
  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"; }
};
unknown's avatar
unknown committed
355 356 357 358 359 360 361 362

// 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;
363
  longlong sum_int;
unknown's avatar
unknown committed
364
  Item_result hybrid_type;
365
  enum_field_types hybrid_field_type;
unknown's avatar
unknown committed
366 367 368 369 370 371 372
  int cmp_sign;
  table_map used_table_cache;

  public:
  Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign),
    used_table_cache(~(table_map) 0)
  {}
373 374
  Item_sum_hybrid(THD *thd, Item_sum_hybrid &item):
    Item_sum(thd, item), value(item.value), tmp_value(item.tmp_value),
375 376
    sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type),
    cmp_sign(item.cmp_sign), used_table_cache(used_table_cache) {}
unknown's avatar
unknown committed
377
  bool fix_fields(THD *, TABLE_LIST *, Item **);
unknown's avatar
unknown committed
378 379 380 381 382 383
  table_map used_tables() const { return used_table_cache; }
  bool const_item() const { return !used_table_cache; }

  void reset()
  {
    sum=0.0;
384
    sum_int=0;
unknown's avatar
unknown committed
385 386 387 388 389
    value.length(0);
    null_value=1;
    add();
  }
  double val();
390
  longlong val_int();
unknown's avatar
unknown committed
391 392 393 394 395
  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; }
396
  enum enum_field_types field_type() const { return hybrid_field_type; }
unknown's avatar
unknown committed
397 398 399 400 401 402 403 404 405 406 407
  void update_field(int offset);
  void min_max_update_str_field(int offset);
  void min_max_update_real_field(int offset);
  void min_max_update_int_field(int offset);
};


class Item_sum_min :public Item_sum_hybrid
{
public:
  Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
408
  Item_sum_min(THD *thd, Item_sum_min &item) :Item_sum_hybrid(thd, item) {}
unknown's avatar
unknown committed
409 410 411 412
  enum Sumfunctype sum_func () const {return MIN_FUNC;}

  bool add();
  const char *func_name() const { return "min"; }
413
  Item *copy_or_same(THD* thd) { return new Item_sum_min(thd, *this); }
unknown's avatar
unknown committed
414 415 416 417 418 419 420
};


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

  bool add();
  const char *func_name() const { return "max"; }
426
  Item *copy_or_same(THD* thd) { return new Item_sum_max(thd, *this); }
unknown's avatar
unknown committed
427 428 429 430 431 432 433 434 435 436 437
};


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) {}
438 439
  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
440 441 442 443 444 445 446 447 448 449 450
  enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
  void reset();
  longlong val_int();
  void reset_field();
};


class Item_sum_or :public Item_sum_bit
{
  public:
  Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
451
  Item_sum_or(THD *thd, Item_sum_or &item) :Item_sum_bit(thd, item) {}
unknown's avatar
unknown committed
452 453 454
  bool add();
  void update_field(int offset);
  const char *func_name() const { return "bit_or"; }
455
  Item *copy_or_same(THD* thd) { return new Item_sum_or(thd, *this); }
unknown's avatar
unknown committed
456 457 458 459 460 461 462
};


class Item_sum_and :public Item_sum_bit
{
  public:
  Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
463
  Item_sum_and(THD *thd, Item_sum_and &item) :Item_sum_bit(thd, item) {}
unknown's avatar
unknown committed
464 465 466
  bool add();
  void update_field(int offset);
  const char *func_name() const { return "bit_and"; }
467
  Item *copy_or_same(THD* thd) { return new Item_sum_and(thd, *this); }
unknown's avatar
unknown committed
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
};

/*
**	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;}
485 486
  Item_udf_sum(THD *thd, Item_udf_sum &item)
    :Item_sum(thd, item), udf(item.udf) {}
unknown's avatar
unknown committed
487 488
  ~Item_udf_sum() {}
  const char *func_name() const { return udf.name(); }
unknown's avatar
unknown committed
489
  bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
unknown's avatar
unknown committed
490
  {
491
    fixed= 1;
unknown's avatar
unknown committed
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
    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; }

  void reset();
  bool add();
  void reset_field() {};
  void update_field(int offset_arg) {};
};


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) {}
510 511
  Item_sum_udf_float(THD *thd, Item_sum_udf_float &item)
    :Item_udf_sum(thd, item) {}
unknown's avatar
unknown committed
512 513 514 515 516
  ~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(); }
517
  Item *copy_or_same(THD* thd) { return new Item_sum_udf_float(thd, *this); }
unknown's avatar
unknown committed
518 519 520 521 522 523 524 525 526
};


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) {}
527 528
  Item_sum_udf_int(THD *thd, Item_sum_udf_int &item)
    :Item_udf_sum(thd, item) {}
unknown's avatar
unknown committed
529 530 531 532 533 534
  ~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; }
535
  Item *copy_or_same(THD* thd) { return new Item_sum_udf_int(thd, *this); }
unknown's avatar
unknown committed
536 537 538 539 540 541 542 543 544
};


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) {}
545 546
  Item_sum_udf_str(THD *thd, Item_sum_udf_str &item)
    :Item_udf_sum(thd, item) {}
unknown's avatar
unknown committed
547 548 549 550
  ~Item_sum_udf_str() {}
  String *val_str(String *);
  double val()
  {
551
    int err;
unknown's avatar
unknown committed
552
    String *res;  res=val_str(&str_value);
553
    return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
554
			    (char**) 0, &err) : 0.0;
unknown's avatar
unknown committed
555 556 557
  }
  longlong val_int()
  {
558
    int err;
unknown's avatar
unknown committed
559
    String *res;  res=val_str(&str_value);
560
    return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, (char**) 0, &err) : (longlong) 0;
unknown's avatar
unknown committed
561 562 563
  }
  enum Item_result result_type () const { return STRING_RESULT; }
  void fix_length_and_dec();
564
  Item *copy_or_same(THD* thd) { return new Item_sum_udf_str(thd, *this); }
unknown's avatar
unknown committed
565 566 567 568 569 570 571 572 573
};

#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() {}
574 575
  Item_sum_udf_float(THD *thd, Item_sum_udf_float &item)
    :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
576 577 578 579 580 581
  ~Item_sum_udf_float() {}
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  double val() { return 0.0; }
  void reset() {}
  bool add() { return 0; }  
  void update_field(int offset) {}
582
  Item *copy_or_same(THD* thd) { return new Item_sum_udf_float(thd, *this); }
unknown's avatar
unknown committed
583 584 585 586 587 588 589 590
};


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() {}
591 592
  Item_sum_udf_int(THD *thd, Item_sum_udf_int &item)
    :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
593 594 595 596 597 598 599
  ~Item_sum_udf_int() {}
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  longlong val_int() { return 0; }
  double val() { return 0; }
  void reset() {}
  bool add() { return 0; }  
  void update_field(int offset) {}
600
  Item *copy_or_same(THD* thd) { return new Item_sum_udf_int(thd, *this); }
unknown's avatar
unknown committed
601 602 603 604 605 606 607 608
};


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() {}
609 610
  Item_sum_udf_str(THD *thd, Item_sum_udf_str &item)
    :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
611 612 613 614 615 616 617 618 619 620
  ~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; }
  void reset() {}
  bool add() { return 0; }  
  void update_field(int offset) {}
621
  Item *copy_or_same(THD* thd) { return new Item_sum_udf_str(thd, *this); }
unknown's avatar
unknown committed
622 623 624
};

#endif /* HAVE_DLOPEN */