item_sum.h 39.5 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
   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 */

20
#ifdef USE_PRAGMA_INTERFACE
unknown's avatar
unknown committed
21 22 23
#pragma interface			/* gcc class implementation */
#endif

24 25
#include <my_tree.h>

unknown's avatar
unknown committed
26 27 28 29 30 31 32
/*
  Class Item_sum is the base class used for special expressions that SQL calls
  'set functions'. These expressions are formed with the help of aggregate
  functions such as SUM, MAX, GROUP_CONCAT etc.

 GENERAL NOTES

unknown's avatar
unknown committed
33
  A set function cannot be used in certain positions where expressions are
unknown's avatar
unknown committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
  accepted. There are some quite explicable restrictions for the usage of 
  set functions.

  In the query:
    SELECT AVG(b) FROM t1 WHERE SUM(b) > 20 GROUP by a
  the usage of the set function AVG(b) is legal, while the usage of SUM(b)
  is illegal. A WHERE condition must contain expressions that can be 
  evaluated for each row of the table. Yet the expression SUM(b) can be
  evaluated only for each group of rows with the same value of column a.
  In the query:
    SELECT AVG(b) FROM t1 WHERE c > 30 GROUP BY a HAVING SUM(b) > 20
  both set function expressions AVG(b) and SUM(b) are legal.

  We can say that in a query without nested selects an occurrence of a
  set function in an expression of the SELECT list or/and in the HAVING
  clause is legal, while in the WHERE clause it's illegal.

  The general rule to detect whether a set function is legal in a query with
  nested subqueries is much more complicated.

  Consider the the following query:
    SELECT t1.a FROM t1 GROUP BY t1.a
      HAVING t1.a > ALL (SELECT t2.c FROM t2 WHERE SUM(t1.b) < t2.c).
  The set function SUM(b) is used here in the WHERE clause of the subquery.
  Nevertheless it is legal since it is under the HAVING clause of the query
  to which this function relates. The expression SUM(t1.b) is evaluated
  for each group defined in the main query, not for groups of the subquery.

  The problem of finding the query where to aggregate a particular
unknown's avatar
unknown committed
63
  set function is not so simple as it seems to be.
unknown's avatar
unknown committed
64 65 66 67 68 69

  In the query: 
    SELECT t1.a FROM t1 GROUP BY t1.a
     HAVING t1.a > ALL(SELECT t2.c FROM t2 GROUP BY t2.c
                         HAVING SUM(t1.a) < t2.c)
  the set function can be evaluated for both outer and inner selects.
unknown's avatar
unknown committed
70
  If we evaluate SUM(t1.a) for the outer query then we get the value of t1.a
unknown's avatar
unknown committed
71 72
  multiplied by the cardinality of a group in table t1. In this case 
  in each correlated subquery SUM(t1.a) is used as a constant. But we also
unknown's avatar
unknown committed
73
  can evaluate SUM(t1.a) for the inner query. In this case t1.a will be a
unknown's avatar
unknown committed
74 75 76 77 78 79
  constant for each correlated subquery and summation is performed
  for each group of table t2.
  (Here it makes sense to remind that the query
    SELECT c FROM t GROUP BY a HAVING SUM(1) < a 
  is quite legal in our SQL).

unknown's avatar
unknown committed
80
  So depending on what query we assign the set function to we
unknown's avatar
unknown committed
81 82 83 84 85
  can get different result sets.

  The general rule to detect the query where a set function is to be
  evaluated can be formulated as follows.
  Consider a set function S(E) where E is an expression with occurrences
unknown's avatar
unknown committed
86 87 88 89 90 91
  of column references C1, ..., CN. Resolve these column references against
  subqueries that contain the set function S(E). Let Q be the innermost
  subquery of those subqueries. (It should be noted here that S(E)
  in no way can be evaluated in the subquery embedding the subquery Q,
  otherwise S(E) would refer to at least one unbound column reference)
  If S(E) is used in a construct of Q where set functions are allowed then
unknown's avatar
unknown committed
92
  we evaluate S(E) in Q.
unknown's avatar
unknown committed
93
  Otherwise we look for a innermost subquery containing S(E) of those where
unknown's avatar
unknown committed
94 95 96 97 98 99 100 101 102
  usage of S(E) is allowed.

  Let's demonstrate how this rule is applied to the following queries.

  1. SELECT t1.a FROM t1 GROUP BY t1.a
       HAVING t1.a > ALL(SELECT t2.b FROM t2 GROUP BY t2.b
                           HAVING t2.b > ALL(SELECT t3.c FROM t3 GROUP BY t3.c
                                                HAVING SUM(t1.a+t2.b) < t3.c))
  For this query the set function SUM(t1.a+t2.b) depends on t1.a and t2.b
unknown's avatar
unknown committed
103
  with t1.a defined in the outermost query, and t2.b defined for its
unknown's avatar
unknown committed
104 105 106 107 108 109 110 111 112 113
  subquery. The set function is in the HAVING clause of the subquery and can
  be evaluated in this subquery.

  2. SELECT t1.a FROM t1 GROUP BY t1.a
       HAVING t1.a > ALL(SELECT t2.b FROM t2
                           WHERE t2.b > ALL (SELECT t3.c FROM t3 GROUP BY t3.c
                                               HAVING SUM(t1.a+t2.b) < t3.c))
  Here the set function SUM(t1.a+t2.b)is in the WHERE clause of the second
  subquery - the most upper subquery where t1.a and t2.b are defined.
  If we evaluate the function in this subquery we violate the context rules.
unknown's avatar
unknown committed
114 115
  So we evaluate the function in the third subquery (over table t3) where it
  is used under the HAVING clause.
unknown's avatar
unknown committed
116 117 118 119 120 121 122 123 124 125 126

  3. SELECT t1.a FROM t1 GROUP BY t1.a
       HAVING t1.a > ALL(SELECT t2.b FROM t2
                           WHERE t2.b > ALL (SELECT t3.c FROM t3 
                                               WHERE SUM(t1.a+t2.b) < t3.c))
  In this query evaluation of SUM(t1.a+t2.b) is not legal neither in the second
  nor in the third subqueries. So this query is invalid.

  Mostly set functions cannot be nested. In the query
    SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20
  the expression SUM(b) is not acceptable, though it is under a HAVING clause.
unknown's avatar
unknown committed
127
  Yet it is acceptable in the query:
unknown's avatar
unknown committed
128 129 130 131 132 133 134 135 136 137 138 139 140 141
    SELECT t.1 FROM t1 GROUP BY t1.a HAVING SUM(t1.b) > 20.

  An argument of a set function does not have to be a reference to a table
  column as we saw it in examples above. This can be a more complex expression
    SELECT t1.a FROM t1 GROUP BY t1.a HAVING SUM(t1.b+1) > 20.
  The expression SUM(t1.b+1) has a very clear semantics in this context:
  we sum up the values of t1.b+1 where t1.b varies for all values within a
  group of rows that contain the same t1.a value.

  A set function for an outer query yields a constant within a subquery. So
  the semantics of the query
    SELECT t1.a FROM t1 GROUP BY t1.a
      HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
                        HAVING AVG(t2.c+SUM(t1.b)) > 20)
unknown's avatar
unknown committed
142
  is still clear. For a group of the rows with the same t1.a values we
unknown's avatar
unknown committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156
  calculate the value of SUM(t1.b). This value 's' is substituted in the
  the subquery:
    SELECT t2.c FROM t2 GROUP BY t2.c HAVING AVG(t2.c+s)
  than returns some result set.

  By the same reason the following query with a subquery 
    SELECT t1.a FROM t1 GROUP BY t1.a
      HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
                        HAVING AVG(SUM(t1.b)) > 20)
  is also acceptable.

 IMPLEMENTATION NOTES

  Three methods were added to the class to check the constraints specified
unknown's avatar
unknown committed
157
  in the previous section. These methods utilize several new members.
unknown's avatar
unknown committed
158 159 160

  The field 'nest_level' contains the number of the level for the subquery
  containing the set function. The main SELECT is of level 0, its subqueries
unknown's avatar
unknown committed
161
  are of levels 1, the subqueries of the latter are of level 2 and so on.
unknown's avatar
unknown committed
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177

  The field 'aggr_level' is to contain the nest level of the subquery
  where the set function is aggregated.

  The field 'max_arg_level' is for the maximun of the nest levels of the
  unbound column references occurred in the set function. A column reference
  is unbound  within a set function if it is not bound by any subquery
  used as a subexpression in this function. A column reference is bound by
  a subquery if it is a reference to the column by which the aggregation
  of some set function that is used in the subquery is calculated.
  For the set function used in the query
    SELECT t1.a FROM t1 GROUP BY t1.a
      HAVING t1.a > ALL(SELECT t2.b FROM t2 GROUP BY t2.b
                          HAVING t2.b > ALL(SELECT t3.c FROM t3 GROUP BY t3.c
                                              HAVING SUM(t1.a+t2.b) < t3.c))
  the value of max_arg_level is equal to 1 since t1.a is bound in the main
unknown's avatar
unknown committed
178
  query, and t2.b is bound by the first subquery whose nest level is 1.
unknown's avatar
unknown committed
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
  Obviously a set function cannot be aggregated in the subquery whose
  nest level is less than max_arg_level. (Yet it can be aggregated in the
  subqueries whose nest level is greater than max_arg_level.)
  In the query
    SELECT t.a FROM t1 HAVING AVG(t1.a+(SELECT MIN(t2.c) FROM t2))
  the value of the max_arg_level for the AVG set function is 0 since
  the reference t2.c is bound in the subquery.

  The field 'max_sum_func_level' is to contain the maximum of the
  nest levels of the set functions that are used as subexpressions of
  the arguments of the given set function, but not aggregated in any
  subquery within this set function. A nested set function s1 can be
  used within set function s0 only if s1.max_sum_func_level <
  s0.max_sum_func_level. Set function s1 is considered as nested
  for set function s0 if s1 is not calculated in any subquery
  within s0.

unknown's avatar
unknown committed
196 197
  A set function that is used as a subexpression in an argument of another
  set function refers to the latter via the field 'in_sum_func'.
unknown's avatar
unknown committed
198 199

  The condition imposed on the usage of set functions are checked when
unknown's avatar
unknown committed
200
  we traverse query subexpressions with the help of the recursive method
unknown's avatar
unknown committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
  fix_fields. When we apply this method to an object of the class
  Item_sum, first, on the descent, we call the method init_sum_func_check
  that initialize members used at checking. Then, on the ascent, we
  call the method check_sum_func that validates the set function usage
  and reports an error if it is illegal.
  The method register_sum_func serves to link the items for the set functions
  that are aggregated in the embedding (sub)queries. Circular chains of such
  functions are attached to the corresponding st_select_lex structures
  through the field inner_sum_func_list.

  Exploiting the fact that the members mentioned above are used in one
  recursive function we could have allocated them on the thread stack.
  Yet we don't do it now.
  
  We assume that the nesting level of subquries does not exceed 127.
  TODO: to catch queries where the limit is exceeded to make the
  code clean here.  
    
*/        

unknown's avatar
unknown committed
221 222 223
class Item_sum :public Item_result_field
{
public:
224
  enum Sumfunctype
unknown's avatar
unknown committed
225 226 227
  { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC,
    AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, UNIQUE_USERS_FUNC, STD_FUNC,
    VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC
228
  };
unknown's avatar
unknown committed
229

unknown's avatar
unknown committed
230
  Item **args, *tmp_args[2];
unknown's avatar
unknown committed
231 232
  Item **ref_by; /* pointer to a ref to the object used to register it */
  Item_sum *next; /* next in the circular chain of registered objects  */
unknown's avatar
unknown committed
233
  uint arg_count;
unknown's avatar
unknown committed
234 235 236 237 238
  Item_sum *in_sum_func;  /* embedding set function if any */ 
  int8 nest_level;        /* number of the nesting level of the set function */
  int8 aggr_level;        /* nesting level of the aggregating subquery       */
  int8 max_arg_level;     /* max level of unbound column references          */
  int8 max_sum_func_level;/* max level of aggregation for embedded functions */
unknown's avatar
unknown committed
239 240
  bool quick_group;			/* If incremental update of fields */

241
  void mark_as_sum_func();
242
  Item_sum() :arg_count(0), quick_group(1) 
243 244 245
  {
    mark_as_sum_func();
  }
unknown's avatar
unknown committed
246
  Item_sum(Item *a)
247
    :args(tmp_args), arg_count(1), quick_group(1)
unknown's avatar
unknown committed
248 249
  {
    args[0]=a;
250
    mark_as_sum_func();
unknown's avatar
unknown committed
251
  }
unknown's avatar
unknown committed
252
  Item_sum( Item *a, Item *b )
253
    :args(tmp_args), arg_count(2), quick_group(1)
unknown's avatar
unknown committed
254 255
  {
    args[0]=a; args[1]=b;
256
    mark_as_sum_func();
unknown's avatar
unknown committed
257 258
  }
  Item_sum(List<Item> &list);
259
  //Copy constructor, need to perform subselects with temporary tables
260
  Item_sum(THD *thd, Item_sum *item);
unknown's avatar
unknown committed
261 262
  enum Type type() const { return SUM_FUNC_ITEM; }
  virtual enum Sumfunctype sum_func () const=0;
263 264
  inline bool reset() { clear(); return add(); };
  virtual void clear()= 0;
unknown's avatar
unknown committed
265
  virtual bool add()=0;
unknown's avatar
unknown committed
266 267 268 269 270
  /*
    Called when new group is started and results are being saved in
    a temporary table. Similar to reset(), but must also store value in
    result_field. Like reset() it is supposed to reset start value to
    default.
unknown's avatar
unknown committed
271 272 273
    This set of methods (reult_field(), reset_field, update_field()) of
    Item_sum is used only if quick_group is not null. Otherwise
    copy_or_same() is used to obtain a copy of this item.
unknown's avatar
unknown committed
274
  */
unknown's avatar
unknown committed
275
  virtual void reset_field()=0;
unknown's avatar
unknown committed
276 277 278 279 280
  /*
    Called for each new value in the group, when temporary table is in use.
    Similar to add(), but uses temporary table field to obtain current value,
    Updated value is then saved in the field.
  */
unknown's avatar
unknown committed
281
  virtual void update_field()=0;
unknown's avatar
unknown committed
282 283
  virtual bool keep_field_type(void) const { return 0; }
  virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
unknown's avatar
unknown committed
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
  /*
    This method is used for debug purposes to print the name of an
    item to the debug log. The second use of this method is as
    a helper function of print(), where it is applicable.
    To suit both goals it should return a meaningful,
    distinguishable and sintactically correct string.  This method
    should not be used for runtime type identification, use enum
    {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
    instead.

    NOTE: for Items inherited from Item_sum, func_name() return part of
    function name till first argument (including '(') to make difference in
    names for functions with 'distinct' clause and without 'distinct' and
    also to make printing of items inherited from Item_sum uniform.
  */
  virtual const char *func_name() const= 0;
unknown's avatar
unknown committed
300
  virtual Item *result_item(Field *field)
unknown's avatar
unknown committed
301
    { return new Item_field(field); }
unknown's avatar
unknown committed
302 303
  table_map used_tables() const { return ~(table_map) 0; } /* Not used */
  bool const_item() const { return 0; }
304
  bool is_null() { return null_value; }
unknown's avatar
unknown committed
305 306 307 308
  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
309
  void no_rows_in_result() { reset(); }
unknown's avatar
unknown committed
310
  virtual bool setup(THD *thd) {return 0;}
311
  virtual void make_unique() {}
312
  Item *get_tmp_table_item(THD *thd);
unknown's avatar
unknown committed
313 314
  virtual Field *create_tmp_field(bool group, TABLE *table,
                                  uint convert_blob_length);
315
  bool walk (Item_processor processor, byte *argument);
unknown's avatar
unknown committed
316 317 318
  bool init_sum_func_check(THD *thd);
  bool check_sum_func(THD *thd, Item **ref);
  bool register_sum_func(THD *thd, Item **ref);
unknown's avatar
unknown committed
319 320 321 322 323
};


class Item_sum_num :public Item_sum
{
324 325 326 327 328 329 330 331
protected:
  /*
   val_xxx() functions may be called several times during the execution of a 
   query. Derived classes that require extensive calculation in val_xxx()
   maintain cache of aggregate value. This variable governs the validity of 
   that cache.
  */
  bool is_evaluated;
unknown's avatar
unknown committed
332
public:
333 334 335 336 337 338 339 340
  Item_sum_num() :Item_sum(),is_evaluated(FALSE) {}
  Item_sum_num(Item *item_par) 
    :Item_sum(item_par), is_evaluated(FALSE) {}
  Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(FALSE) {}
  Item_sum_num(List<Item> &list) 
    :Item_sum(list), is_evaluated(FALSE) {}
  Item_sum_num(THD *thd, Item_sum_num *item) 
    :Item_sum(thd, item),is_evaluated(item->is_evaluated) {}
unknown's avatar
unknown committed
341
  bool fix_fields(THD *, Item **);
342
  longlong val_int()
unknown's avatar
unknown committed
343 344
  {
    DBUG_ASSERT(fixed == 1);
345
    return (longlong) rint(val_real());             /* Real as default */
unknown's avatar
unknown committed
346
  }
unknown's avatar
unknown committed
347
  String *val_str(String*str);
unknown's avatar
unknown committed
348
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
349 350 351 352 353 354 355 356 357
  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) {}
358
  Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
359
  double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
unknown's avatar
unknown committed
360
  String *val_str(String*str);
unknown's avatar
unknown committed
361
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
362
  enum Item_result result_type () const { return INT_RESULT; }
unknown's avatar
unknown committed
363 364
  void fix_length_and_dec()
  { decimals=0; max_length=21; maybe_null=null_value=0; }
unknown's avatar
unknown committed
365 366 367 368 369
};


class Item_sum_sum :public Item_sum_num
{
unknown's avatar
unknown committed
370 371
protected:
  Item_result hybrid_type;
unknown's avatar
unknown committed
372
  double sum;
unknown's avatar
unknown committed
373 374 375
  my_decimal dec_buffs[2];
  uint curr_dec_buff;
  void fix_length_and_dec();
unknown's avatar
unknown committed
376

unknown's avatar
unknown committed
377 378 379
public:
  Item_sum_sum(Item *item_par) :Item_sum_num(item_par) {}
  Item_sum_sum(THD *thd, Item_sum_sum *item);
unknown's avatar
unknown committed
380
  enum Sumfunctype sum_func () const {return SUM_FUNC;}
381
  void clear();
unknown's avatar
unknown committed
382
  bool add();
unknown's avatar
unknown committed
383 384 385 386 387
  double val_real();
  longlong val_int();
  String *val_str(String*str);
  my_decimal *val_decimal(my_decimal *);
  enum Item_result result_type () const { return hybrid_type; }
unknown's avatar
unknown committed
388
  void reset_field();
unknown's avatar
unknown committed
389
  void update_field();
unknown's avatar
unknown committed
390
  void no_rows_in_result() {}
unknown's avatar
unknown committed
391
  const char *func_name() const { return "sum("; }
392
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
393 394 395
};


unknown's avatar
unknown committed
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478

/* Common class for SUM(DISTINCT), AVG(DISTINCT) */

class Unique;

class Item_sum_distinct :public Item_sum_num
{
protected:
  /* storage for the summation result */
  ulonglong count;
  Hybrid_type val;
  /* storage for unique elements */
  Unique *tree;
  TABLE *table;
  enum enum_field_types table_field_type;
  uint tree_key_length;
protected:
  Item_sum_distinct(THD *thd, Item_sum_distinct *item);
public:
  Item_sum_distinct(Item *item_par);
  ~Item_sum_distinct();

  bool setup(THD *thd);
  void clear();
  void cleanup();
  bool add();
  double val_real();
  my_decimal *val_decimal(my_decimal *);
  longlong val_int();
  String *val_str(String *str);

  /* XXX: does it need make_unique? */

  enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
  void reset_field() {} // not used
  void update_field() {} // not used
  virtual void no_rows_in_result() {}
  void fix_length_and_dec();
  enum Item_result result_type () const { return val.traits->type(); }
  virtual void calculate_val_and_count();
  virtual bool unique_walk_function(void *elem);
};


/*
  Item_sum_sum_distinct - implementation of SUM(DISTINCT expr).
  See also: MySQL manual, chapter 'Adding New Functions To MySQL'
  and comments in item_sum.cc.
*/

class Item_sum_sum_distinct :public Item_sum_distinct
{
private:
  Item_sum_sum_distinct(THD *thd, Item_sum_sum_distinct *item)
    :Item_sum_distinct(thd, item) {}
public:
  Item_sum_sum_distinct(Item *item_arg) :Item_sum_distinct(item_arg) {}

  enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
  const char *func_name() const { return "sum(distinct "; }
  Item *copy_or_same(THD* thd) { return new Item_sum_sum_distinct(thd, this); }
};


/* Item_sum_avg_distinct - SELECT AVG(DISTINCT expr) FROM ... */

class Item_sum_avg_distinct: public Item_sum_distinct
{
private:
  Item_sum_avg_distinct(THD *thd, Item_sum_avg_distinct *original)
    :Item_sum_distinct(thd, original) {}
public:
  uint prec_increment;
  Item_sum_avg_distinct(Item *item_arg) : Item_sum_distinct(item_arg) {}

  void fix_length_and_dec();
  virtual void calculate_val_and_count();
  enum Sumfunctype sum_func () const { return AVG_DISTINCT_FUNC; }
  const char *func_name() const { return "avg(distinct "; }
  Item *copy_or_same(THD* thd) { return new Item_sum_avg_distinct(thd, this); }
};


unknown's avatar
unknown committed
479 480 481 482 483 484 485 486 487
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)
  {}
488 489 490
  Item_sum_count(THD *thd, Item_sum_count *item)
    :Item_sum_int(thd, item), count(item->count),
     used_table_cache(item->used_table_cache)
491
  {}
unknown's avatar
unknown committed
492 493 494
  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; }
495
  void clear();
unknown's avatar
unknown committed
496
  void no_rows_in_result() { count=0; }
unknown's avatar
unknown committed
497 498 499 500
  bool add();
  void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
  longlong val_int();
  void reset_field();
501
  void cleanup();
unknown's avatar
unknown committed
502
  void update_field();
unknown's avatar
unknown committed
503
  const char *func_name() const { return "count("; }
504
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
505 506 507 508 509 510 511 512
};


class TMP_TABLE_PARAM;

class Item_sum_count_distinct :public Item_sum_int
{
  TABLE *table;
unknown's avatar
unknown committed
513
  uint32 *field_lengths;
unknown's avatar
unknown committed
514
  TMP_TABLE_PARAM *tmp_table_param;
515
  bool force_copy_fields;
unknown's avatar
unknown committed
516 517 518 519 520 521
  /*
    If there are no blobs, we can use a tree, which
    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
  */
  Unique *tree;
522 523 524 525 526 527
  /*
   Storage for the value of count between calls to val_int() so val_int()
   will not recalculate on each call. Validitiy of the value is stored in
   is_evaluated.
  */
  longlong count;
528 529 530 531 532
  /*
    Following is 0 normal object and pointer to original one for copy 
    (to correctly free resources)
  */
  Item_sum_count_distinct *original;
unknown's avatar
unknown committed
533
  uint tree_key_length;
534

unknown's avatar
unknown committed
535

unknown's avatar
merge  
unknown committed
536
  bool always_null;		// Set to 1 if the result is always NULL
537

unknown's avatar
unknown committed
538

539
  friend int composite_key_cmp(void* arg, byte* key1, byte* key2);
540
  friend int simple_str_key_cmp(void* arg, byte* key1, byte* key2);
541

unknown's avatar
unknown committed
542
public:
unknown's avatar
unknown committed
543
  Item_sum_count_distinct(List<Item> &list)
unknown's avatar
unknown committed
544
    :Item_sum_int(list), table(0), field_lengths(0), tmp_table_param(0),
545 546
     force_copy_fields(0), tree(0), count(0),
     original(0), always_null(FALSE)
547
  { quick_group= 0; }
548 549
  Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
    :Item_sum_int(thd, item), table(item->table),
unknown's avatar
unknown committed
550 551
     field_lengths(item->field_lengths),
     tmp_table_param(item->tmp_table_param),
552 553
     force_copy_fields(0), tree(item->tree), count(item->count), 
     original(item), tree_key_length(item->tree_key_length),
554
     always_null(item->always_null)
555
  {}
unknown's avatar
unknown committed
556 557
  ~Item_sum_count_distinct();

unknown's avatar
unknown committed
558
  void cleanup();
559

unknown's avatar
unknown committed
560
  enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
561
  void clear();
unknown's avatar
unknown committed
562 563 564
  bool add();
  longlong val_int();
  void reset_field() { return ;}		// Never called
unknown's avatar
unknown committed
565
  void update_field() { return ; }		// Never called
unknown's avatar
unknown committed
566
  const char *func_name() const { return "count(distinct "; }
unknown's avatar
unknown committed
567
  bool setup(THD *thd);
568 569
  void make_unique();
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
570
  void no_rows_in_result() {}
unknown's avatar
unknown committed
571 572 573 574 575
};


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

576 577
class Item_sum_avg;

unknown's avatar
unknown committed
578 579 580 581
class Item_avg_field :public Item_result_field
{
public:
  Field *field;
unknown's avatar
unknown committed
582 583 584 585
  Item_result hybrid_type;
  uint f_precision, f_scale, dec_bin_size;
  uint prec_increment;
  Item_avg_field(Item_result res_type, Item_sum_avg *item);
unknown's avatar
unknown committed
586
  enum Type type() const { return FIELD_AVG_ITEM; }
unknown's avatar
unknown committed
587 588 589
  double val_real();
  longlong val_int();
  my_decimal *val_decimal(my_decimal *);
590
  bool is_null() { (void) val_int(); return null_value; }
unknown's avatar
unknown committed
591
  String *val_str(String*);
unknown's avatar
unknown committed
592 593 594 595 596
  enum_field_types field_type() const
  {
    return hybrid_type == DECIMAL_RESULT ?
      MYSQL_TYPE_NEWDECIMAL : MYSQL_TYPE_DOUBLE;
  }
unknown's avatar
unknown committed
597
  void fix_length_and_dec() {}
unknown's avatar
unknown committed
598
  enum Item_result result_type () const { return hybrid_type; }
unknown's avatar
unknown committed
599 600 601
};


unknown's avatar
unknown committed
602
class Item_sum_avg :public Item_sum_sum
unknown's avatar
unknown committed
603
{
unknown's avatar
unknown committed
604
public:
unknown's avatar
unknown committed
605
  ulonglong count;
unknown's avatar
unknown committed
606 607
  uint prec_increment;
  uint f_precision, f_scale, dec_bin_size;
unknown's avatar
unknown committed
608

unknown's avatar
unknown committed
609
  Item_sum_avg(Item *item_par) :Item_sum_sum(item_par), count(0) {}
610
  Item_sum_avg(THD *thd, Item_sum_avg *item)
unknown's avatar
unknown committed
611 612 613 614
    :Item_sum_sum(thd, item), count(item->count),
    prec_increment(item->prec_increment) {}

  void fix_length_and_dec();
unknown's avatar
unknown committed
615
  enum Sumfunctype sum_func () const {return AVG_FUNC;}
616
  void clear();
unknown's avatar
unknown committed
617
  bool add();
unknown's avatar
unknown committed
618 619
  double val_real();
  // In SPs we might force the "wrong" type with select into a declare variable
620
  longlong val_int() { return (longlong) rint(val_real()); }
unknown's avatar
unknown committed
621 622
  my_decimal *val_decimal(my_decimal *);
  String *val_str(String *str);
unknown's avatar
unknown committed
623
  void reset_field();
unknown's avatar
unknown committed
624
  void update_field();
unknown's avatar
unknown committed
625
  Item *result_item(Field *field)
unknown's avatar
unknown committed
626
  { return new Item_avg_field(hybrid_type, this); }
627
  void no_rows_in_result() {}
unknown's avatar
unknown committed
628
  const char *func_name() const { return "avg("; }
629
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
630
  Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
unknown's avatar
unknown committed
631 632
};

unknown's avatar
unknown committed
633
class Item_sum_variance;
unknown's avatar
unknown committed
634

unknown's avatar
unknown committed
635
class Item_variance_field :public Item_result_field
unknown's avatar
unknown committed
636 637 638
{
public:
  Field *field;
unknown's avatar
unknown committed
639 640 641 642 643 644
  Item_result hybrid_type;
  uint f_precision0, f_scale0;
  uint f_precision1, f_scale1;
  uint dec_bin_size0, dec_bin_size1;
  uint sample;
  uint prec_increment;
unknown's avatar
unknown committed
645 646
  Item_variance_field(Item_sum_variance *item);
  enum Type type() const {return FIELD_VARIANCE_ITEM; }
unknown's avatar
unknown committed
647 648
  double val_real();
  longlong val_int()
649
  { /* can't be fix_fields()ed */ return (longlong) rint(val_real()); }
unknown's avatar
unknown committed
650
  String *val_str(String*);
unknown's avatar
unknown committed
651
  my_decimal *val_decimal(my_decimal *);
652
  bool is_null() { (void) val_int(); return null_value; }
unknown's avatar
unknown committed
653 654 655 656 657
  enum_field_types field_type() const
  {
    return hybrid_type == DECIMAL_RESULT ?
      MYSQL_TYPE_NEWDECIMAL : MYSQL_TYPE_DOUBLE;
  }
unknown's avatar
unknown committed
658
  void fix_length_and_dec() {}
unknown's avatar
unknown committed
659
  enum Item_result result_type () const { return hybrid_type; }
unknown's avatar
unknown committed
660 661
};

unknown's avatar
unknown committed
662

unknown's avatar
unknown committed
663 664 665 666 667 668 669 670 671 672
/*
  variance(a) =

  =  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)
673
*/
unknown's avatar
unknown committed
674 675

class Item_sum_variance : public Item_sum_num
unknown's avatar
unknown committed
676
{
unknown's avatar
unknown committed
677 678 679 680
  void fix_length_and_dec();

public:
  Item_result hybrid_type;
unknown's avatar
unknown committed
681
  double sum, sum_sqr;
unknown's avatar
unknown committed
682 683
  my_decimal dec_sum[2], dec_sqr[2];
  int cur_dec;
unknown's avatar
unknown committed
684
  ulonglong count;
unknown's avatar
unknown committed
685 686 687 688 689 690 691 692 693 694
  uint f_precision0, f_scale0;
  uint f_precision1, f_scale1;
  uint dec_bin_size0, dec_bin_size1;
  uint sample;
  uint prec_increment;

  Item_sum_variance(Item *item_par, uint sample_arg) :Item_sum_num(item_par),
    hybrid_type(REAL_RESULT), cur_dec(0), count(0), sample(sample_arg)
    {}
  Item_sum_variance(THD *thd, Item_sum_variance *item);
unknown's avatar
unknown committed
695
  enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
696
  void clear();
unknown's avatar
unknown committed
697
  bool add();
unknown's avatar
unknown committed
698 699
  double val_real();
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
700
  void reset_field();
unknown's avatar
unknown committed
701
  void update_field();
unknown's avatar
unknown committed
702
  Item *result_item(Field *field)
unknown's avatar
unknown committed
703
  { return new Item_variance_field(this); }
704
  void no_rows_in_result() {}
unknown's avatar
unknown committed
705 706
  const char *func_name() const
    { return sample ? "var_samp(" : "variance("; }
707
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
708
  Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
709
  enum Item_result result_type () const { return REAL_RESULT; }
unknown's avatar
unknown committed
710 711 712 713 714 715 716 717 718
};

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; }
unknown's avatar
unknown committed
719 720 721 722
  double val_real();
  my_decimal *val_decimal(my_decimal *);
  enum Item_result result_type () const { return REAL_RESULT; }
  enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
723 724 725 726 727 728 729 730 731
};

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

class Item_sum_std :public Item_sum_variance
{
  public:
unknown's avatar
unknown committed
732 733
  Item_sum_std(Item *item_par, uint sample_arg)
    :Item_sum_variance(item_par, sample_arg) {}
734
  Item_sum_std(THD *thd, Item_sum_std *item)
735 736
    :Item_sum_variance(thd, item)
    {}
737
  enum Sumfunctype sum_func () const { return STD_FUNC; }
unknown's avatar
unknown committed
738
  double val_real();
739 740
  Item *result_item(Field *field)
    { return new Item_std_field(this); }
unknown's avatar
unknown committed
741
  const char *func_name() const { return "std("; }
742
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
743 744
  enum Item_result result_type () const { return REAL_RESULT; }
  enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
745
};
unknown's avatar
unknown committed
746 747 748 749 750

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

class Item_sum_hybrid :public Item_sum
{
unknown's avatar
unknown committed
751
protected:
unknown's avatar
unknown committed
752 753
  String value,tmp_value;
  double sum;
754
  longlong sum_int;
unknown's avatar
unknown committed
755
  my_decimal sum_dec;
unknown's avatar
unknown committed
756
  Item_result hybrid_type;
unknown's avatar
unknown committed
757
  enum_field_types hybrid_field_type;
unknown's avatar
unknown committed
758 759
  int cmp_sign;
  table_map used_table_cache;
unknown's avatar
unknown committed
760
  bool was_values;  // Set if we have found at least one row (for max/min only)
unknown's avatar
unknown committed
761 762

  public:
763
  Item_sum_hybrid(Item *item_par,int sign)
unknown's avatar
unknown committed
764 765
    :Item_sum(item_par), sum(0.0), sum_int(0),
    hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG),
unknown's avatar
unknown committed
766
    cmp_sign(sign), used_table_cache(~(table_map) 0),
767
    was_values(TRUE)
unknown's avatar
unknown committed
768 769 770
  { collation.set(&my_charset_bin); }
  Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
  bool fix_fields(THD *, Item **);
unknown's avatar
unknown committed
771 772 773
  table_map used_tables() const { return used_table_cache; }
  bool const_item() const { return !used_table_cache; }

774
  void clear();
unknown's avatar
unknown committed
775
  double val_real();
776
  longlong val_int();
unknown's avatar
unknown committed
777
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
778 779 780 781 782
  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; }
unknown's avatar
unknown committed
783
  enum enum_field_types field_type() const { return hybrid_field_type; }
unknown's avatar
unknown committed
784 785 786 787
  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
788
  void min_max_update_decimal_field();
789
  void cleanup();
790 791
  bool any_value() { return was_values; }
  void no_rows_in_result();
unknown's avatar
unknown committed
792 793
  Field *create_tmp_field(bool group, TABLE *table,
			  uint convert_blob_length);
unknown's avatar
unknown committed
794 795 796 797 798 799 800
};


class Item_sum_min :public Item_sum_hybrid
{
public:
  Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
801
  Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {}
unknown's avatar
unknown committed
802 803 804
  enum Sumfunctype sum_func () const {return MIN_FUNC;}

  bool add();
unknown's avatar
unknown committed
805
  const char *func_name() const { return "min("; }
806
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
807 808 809 810 811 812 813
};


class Item_sum_max :public Item_sum_hybrid
{
public:
  Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
814
  Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {}
unknown's avatar
unknown committed
815 816 817
  enum Sumfunctype sum_func () const {return MAX_FUNC;}

  bool add();
unknown's avatar
unknown committed
818
  const char *func_name() const { return "max("; }
819
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
820 821 822 823 824
};


class Item_sum_bit :public Item_sum_int
{
825
protected:
unknown's avatar
unknown committed
826 827
  ulonglong reset_bits,bits;

828
public:
unknown's avatar
unknown committed
829 830
  Item_sum_bit(Item *item_par,ulonglong reset_arg)
    :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
831 832
  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
833
  enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
834
  void clear();
unknown's avatar
unknown committed
835 836
  longlong val_int();
  void reset_field();
unknown's avatar
unknown committed
837
  void update_field();
unknown's avatar
unknown committed
838
  void fix_length_and_dec()
unknown's avatar
unknown committed
839
  { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
unknown's avatar
unknown committed
840 841 842 843 844
};


class Item_sum_or :public Item_sum_bit
{
unknown's avatar
unknown committed
845
public:
unknown's avatar
unknown committed
846
  Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
847
  Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {}
unknown's avatar
unknown committed
848
  bool add();
unknown's avatar
unknown committed
849
  const char *func_name() const { return "bit_or("; }
850
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
851 852 853 854 855 856
};


class Item_sum_and :public Item_sum_bit
{
  public:
857
  Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {}
858
  Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {}
unknown's avatar
unknown committed
859
  bool add();
unknown's avatar
unknown committed
860
  const char *func_name() const { return "bit_and("; }
861
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
862 863
};

864 865 866 867
class Item_sum_xor :public Item_sum_bit
{
  public:
  Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
868
  Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {}
869
  bool add();
unknown's avatar
unknown committed
870
  const char *func_name() const { return "bit_xor("; }
871 872 873 874
  Item *copy_or_same(THD* thd);
};


unknown's avatar
unknown committed
875
/*
unknown's avatar
unknown committed
876
  User defined aggregates
unknown's avatar
unknown committed
877
*/
unknown's avatar
unknown committed
878

unknown's avatar
unknown committed
879 880 881 882 883 884 885 886
#ifdef HAVE_DLOPEN

class Item_udf_sum : public Item_sum
{
protected:
  udf_handler udf;

public:
unknown's avatar
unknown committed
887 888 889 890 891
  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)
unknown's avatar
unknown committed
892
  { quick_group=0;}
893
  Item_udf_sum(THD *thd, Item_udf_sum *item)
unknown's avatar
unknown committed
894 895
    :Item_sum(thd, item), udf(item->udf)
  { udf.not_original= TRUE; }
unknown's avatar
unknown committed
896
  const char *func_name() const { return udf.name(); }
unknown's avatar
unknown committed
897
  bool fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
898
  {
899
    DBUG_ASSERT(fixed == 0);
900
    fixed= 1;
unknown's avatar
unknown committed
901
    return udf.fix_fields(thd, this, this->arg_count, this->args);
unknown's avatar
unknown committed
902 903 904 905
  }
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  virtual bool have_field_update(void) const { return 0; }

906
  void clear();
unknown's avatar
unknown committed
907 908
  bool add();
  void reset_field() {};
unknown's avatar
unknown committed
909
  void update_field() {};
910
  void cleanup();
unknown's avatar
unknown committed
911
  void print(String *str);
unknown's avatar
unknown committed
912 913 914 915 916 917
};


class Item_sum_udf_float :public Item_udf_sum
{
 public:
unknown's avatar
unknown committed
918 919
  Item_sum_udf_float(udf_func *udf_arg)
    :Item_udf_sum(udf_arg) {}
unknown's avatar
unknown committed
920
  Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
unknown's avatar
unknown committed
921
    :Item_udf_sum(udf_arg, list) {}
922
  Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
923
    :Item_udf_sum(thd, item) {}
924
  longlong val_int()
unknown's avatar
unknown committed
925 926
  {
    DBUG_ASSERT(fixed == 1);
927
    return (longlong) rint(Item_sum_udf_float::val_real());
unknown's avatar
unknown committed
928 929
  }
  double val_real();
unknown's avatar
unknown committed
930
  String *val_str(String*str);
unknown's avatar
unknown committed
931
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
932
  void fix_length_and_dec() { fix_num_length_and_dec(); }
933
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
934 935 936 937 938 939
};


class Item_sum_udf_int :public Item_udf_sum
{
public:
unknown's avatar
unknown committed
940 941
  Item_sum_udf_int(udf_func *udf_arg)
    :Item_udf_sum(udf_arg) {}
unknown's avatar
unknown committed
942
  Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
unknown's avatar
unknown committed
943
    :Item_udf_sum(udf_arg, list) {}
944
  Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
945
    :Item_udf_sum(thd, item) {}
unknown's avatar
unknown committed
946
  longlong val_int();
unknown's avatar
unknown committed
947
  double val_real()
948
    { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); }
unknown's avatar
unknown committed
949
  String *val_str(String*str);
unknown's avatar
unknown committed
950
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
951 952
  enum Item_result result_type () const { return INT_RESULT; }
  void fix_length_and_dec() { decimals=0; max_length=21; }
953
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
954 955 956 957 958 959
};


class Item_sum_udf_str :public Item_udf_sum
{
public:
unknown's avatar
unknown committed
960 961
  Item_sum_udf_str(udf_func *udf_arg)
    :Item_udf_sum(udf_arg) {}
unknown's avatar
unknown committed
962 963
  Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
    :Item_udf_sum(udf_arg,list) {}
964
  Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
965
    :Item_udf_sum(thd, item) {}
unknown's avatar
unknown committed
966
  String *val_str(String *);
unknown's avatar
unknown committed
967
  double val_real()
unknown's avatar
unknown committed
968
  {
unknown's avatar
unknown committed
969
    int err_not_used;
unknown's avatar
unknown committed
970 971 972
    char *end_not_used;
    String *res;
    res=val_str(&str_value);
973
    return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
unknown's avatar
unknown committed
974
			    &end_not_used, &err_not_used) : 0.0;
unknown's avatar
unknown committed
975 976 977
  }
  longlong val_int()
  {
unknown's avatar
unknown committed
978 979 980 981 982 983 984 985 986 987
    int err_not_used;
    char *end;
    String *res;
    CHARSET_INFO *cs;

    if (!(res= val_str(&str_value)))
      return 0;                                 /* Null value */
    cs= res->charset();
    end= (char*) res->ptr()+res->length();
    return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used);
unknown's avatar
unknown committed
988
  }
unknown's avatar
unknown committed
989
  my_decimal *val_decimal(my_decimal *dec);
unknown's avatar
unknown committed
990 991
  enum Item_result result_type () const { return STRING_RESULT; }
  void fix_length_and_dec();
992
  Item *copy_or_same(THD* thd);
unknown's avatar
unknown committed
993 994
};

unknown's avatar
unknown committed
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013

class Item_sum_udf_decimal :public Item_udf_sum
{
public:
  Item_sum_udf_decimal(udf_func *udf_arg)
    :Item_udf_sum(udf_arg) {}
  Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
    :Item_udf_sum(udf_arg, list) {}
  Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item)
    :Item_udf_sum(thd, item) {}
  String *val_str(String *);
  double val_real();
  longlong val_int();
  my_decimal *val_decimal(my_decimal *);
  enum Item_result result_type () const { return DECIMAL_RESULT; }
  void fix_length_and_dec() { fix_num_length_and_dec(); }
  Item *copy_or_same(THD* thd);
};

unknown's avatar
unknown committed
1014 1015 1016 1017 1018
#else /* Dummy functions to get sql_yacc.cc compiled */

class Item_sum_udf_float :public Item_sum_num
{
 public:
unknown's avatar
unknown committed
1019 1020
  Item_sum_udf_float(udf_func *udf_arg)
    :Item_sum_num() {}
unknown's avatar
unknown committed
1021
  Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
unknown's avatar
unknown committed
1022
  Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
1023
    :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
1024
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
unknown's avatar
unknown committed
1025
  double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
unknown's avatar
unknown committed
1026
  void clear() {}
unknown's avatar
unknown committed
1027
  bool add() { return 0; }  
unknown's avatar
unknown committed
1028
  void update_field() {}
unknown's avatar
unknown committed
1029 1030 1031 1032 1033 1034
};


class Item_sum_udf_int :public Item_sum_num
{
public:
unknown's avatar
unknown committed
1035 1036
  Item_sum_udf_int(udf_func *udf_arg)
    :Item_sum_num() {}
unknown's avatar
unknown committed
1037
  Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
unknown's avatar
unknown committed
1038
  Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
1039
    :Item_sum_num(thd, item) {}
unknown's avatar
unknown committed
1040
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
1041
  longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; }
unknown's avatar
unknown committed
1042
  double val_real() { DBUG_ASSERT(fixed == 1); return 0; }
1043
  void clear() {}
unknown's avatar
unknown committed
1044
  bool add() { return 0; }  
unknown's avatar
unknown committed
1045
  void update_field() {}
unknown's avatar
unknown committed
1046 1047 1048
};


unknown's avatar
unknown committed
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
class Item_sum_udf_decimal :public Item_sum_num
{
 public:
  Item_sum_udf_decimal(udf_func *udf_arg)
    :Item_sum_num() {}
  Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
    :Item_sum_num() {}
  Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item)
    :Item_sum_num(thd, item) {}
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
  my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; }
  void clear() {}
  bool add() { return 0; }
  void update_field() {}
};


unknown's avatar
unknown committed
1067 1068 1069
class Item_sum_udf_str :public Item_sum_num
{
public:
unknown's avatar
unknown committed
1070 1071 1072 1073
  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() {}
unknown's avatar
unknown committed
1074
  Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
1075
    :Item_sum_num(thd, item) {}
1076 1077
  String *val_str(String *)
    { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
unknown's avatar
unknown committed
1078
  double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; }
1079
  longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
unknown's avatar
unknown committed
1080 1081 1082
  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; }
1083
  void clear() {}
unknown's avatar
unknown committed
1084
  bool add() { return 0; }  
unknown's avatar
unknown committed
1085
  void update_field() {}
unknown's avatar
unknown committed
1086 1087 1088
};

#endif /* HAVE_DLOPEN */
1089

1090 1091
class MYSQL_ERROR;

1092 1093 1094
class Item_func_group_concat : public Item_sum
{
  TMP_TABLE_PARAM *tmp_table_param;
1095
  MYSQL_ERROR *warning;
unknown's avatar
unknown committed
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
  String result;
  String *separator;
  TREE tree_base;
  TREE *tree;
  TABLE *table;
  ORDER **order;
  Name_resolution_context *context;
  uint arg_count_order;               // total count of ORDER BY items
  uint arg_count_field;               // count of arguments
  uint count_cut_values;
unknown's avatar
URGENT  
unknown committed
1106 1107 1108
  bool distinct;
  bool warning_for_row;
  bool always_null;
1109
  bool force_copy_fields;
unknown's avatar
unknown committed
1110
  bool no_appended;
unknown's avatar
unknown committed
1111 1112 1113 1114 1115
  /*
    Following is 0 normal object and pointer to original one for copy
    (to correctly free resources)
  */
  Item_func_group_concat *original;
unknown's avatar
URGENT  
unknown committed
1116 1117 1118

  friend int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
					      byte* key2);
unknown's avatar
unknown committed
1119 1120
  friend int group_concat_key_cmp_with_order(void* arg, byte* key1,
					     byte* key2);
unknown's avatar
URGENT  
unknown committed
1121 1122 1123
  friend int group_concat_key_cmp_with_distinct_and_order(void* arg,
							byte* key1,
							byte* key2);
unknown's avatar
unknown committed
1124 1125
  friend int dump_leaf_key(byte* key,
                           element_count count __attribute__((unused)),
unknown's avatar
unknown committed
1126
			   Item_func_group_concat *group_concat_item);
unknown's avatar
URGENT  
unknown committed
1127

unknown's avatar
unknown committed
1128 1129 1130 1131 1132
public:
  Item_func_group_concat(Name_resolution_context *context_arg,
                         bool is_distinct, List<Item> *is_select,
                         SQL_LIST *is_order, String *is_separator);

unknown's avatar
unknown committed
1133
  Item_func_group_concat(THD *thd, Item_func_group_concat *item);
unknown's avatar
unknown committed
1134
  ~Item_func_group_concat() {}
unknown's avatar
unknown committed
1135 1136
  void cleanup();

1137 1138 1139
  enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
  const char *func_name() const { return "group_concat"; }
  virtual Item_result result_type () const { return STRING_RESULT; }
1140 1141
  enum_field_types field_type() const
  {
unknown's avatar
unknown committed
1142
    if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB )
1143 1144
      return FIELD_TYPE_BLOB;
    else
unknown's avatar
unknown committed
1145
      return MYSQL_TYPE_VARCHAR;
1146
  }
1147
  void clear();
1148
  bool add();
unknown's avatar
unknown committed
1149 1150
  void reset_field() { DBUG_ASSERT(0); }        // not used
  void update_field() { DBUG_ASSERT(0); }       // not used
unknown's avatar
unknown committed
1151
  bool fix_fields(THD *,Item **);
1152
  bool setup(THD *thd);
1153
  void make_unique();
unknown's avatar
unknown committed
1154
  double val_real()
1155 1156
  {
    String *res;  res=val_str(&str_value);
unknown's avatar
unknown committed
1157
    return res ? my_atof(res->c_ptr()) : 0.0;
1158 1159 1160
  }
  longlong val_int()
  {
unknown's avatar
unknown committed
1161 1162 1163
    String *res;
    char *end_ptr;
    int error;
1164 1165
    if (!(res= val_str(&str_value)))
      return (longlong) 0;
unknown's avatar
unknown committed
1166
    end_ptr= (char*) res->ptr()+ res->length();
1167
    return my_strtoll10(res->ptr(), &end_ptr, &error);
1168
  }
unknown's avatar
unknown committed
1169 1170 1171 1172
  my_decimal *val_decimal(my_decimal *decimal_value)
  {
    return val_decimal_from_string(decimal_value);
  }
1173
  String* val_str(String* str);
1174
  Item *copy_or_same(THD* thd);
unknown's avatar
BUG  
unknown committed
1175
  void no_rows_in_result() {}
1176
  void print(String *str);
unknown's avatar
unknown committed
1177 1178
  virtual bool change_context_processor(byte *cntx)
    { context= (Name_resolution_context *)cntx; return FALSE; }
1179
};