Drizzled Public API Documentation

sum.h
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #pragma once
00021 
00022 /* classes for sum functions */
00023 
00024 #include <drizzled/tree.h>
00025 #include <drizzled/hybrid_type.h>
00026 #include <drizzled/item.h>
00027 #include <drizzled/item/field.h>
00028 #include <drizzled/item/bin_string.h>
00029 #include <drizzled/charset.h>
00030 
00031 namespace drizzled {
00032 
00033 int group_concat_key_cmp_with_distinct(void* arg, const void* key1, const void* key2);
00034 
00035 int group_concat_key_cmp_with_order(void* arg, const void* key1, const void* key2);
00036 
00037 /*
00038   Class Item_sum is the base class used for special expressions that SQL calls
00039   'set functions'. These expressions are formed with the help of aggregate
00040   functions such as SUM, MAX, GROUP_CONCAT etc.
00041 
00042  GENERAL NOTES
00043 
00044   A set function cannot be used in certain positions where expressions are
00045   accepted. There are some quite explicable restrictions for the usage of
00046   set functions.
00047 
00048   In the query:
00049     SELECT AVG(b) FROM t1 WHERE SUM(b) > 20 GROUP by a
00050   the usage of the set function AVG(b) is legal, while the usage of SUM(b)
00051   is illegal. A WHERE condition must contain expressions that can be
00052   evaluated for each row of the table. Yet the expression SUM(b) can be
00053   evaluated only for each group of rows with the same value of column a.
00054   In the query:
00055     SELECT AVG(b) FROM t1 WHERE c > 30 GROUP BY a HAVING SUM(b) > 20
00056   both set function expressions AVG(b) and SUM(b) are legal.
00057 
00058   We can say that in a query without nested selects an occurrence of a
00059   set function in an expression of the SELECT list or/and in the HAVING
00060   clause is legal, while in the WHERE clause it's illegal.
00061 
00062   The general rule to detect whether a set function is legal in a query with
00063   nested subqueries is much more complicated.
00064 
00065   Consider the the following query:
00066     SELECT t1.a FROM t1 GROUP BY t1.a
00067       HAVING t1.a > ALL (SELECT t2.c FROM t2 WHERE SUM(t1.b) < t2.c).
00068   The set function SUM(b) is used here in the WHERE clause of the subquery.
00069   Nevertheless it is legal since it is under the HAVING clause of the query
00070   to which this function relates. The expression SUM(t1.b) is evaluated
00071   for each group defined in the main query, not for groups of the subquery.
00072 
00073   The problem of finding the query where to aggregate a particular
00074   set function is not so simple as it seems to be.
00075 
00076   In the query:
00077     SELECT t1.a FROM t1 GROUP BY t1.a
00078      HAVING t1.a > ALL(SELECT t2.c FROM t2 GROUP BY t2.c
00079                          HAVING SUM(t1.a) < t2.c)
00080   the set function can be evaluated for both outer and inner selects.
00081   If we evaluate SUM(t1.a) for the outer query then we get the value of t1.a
00082   multiplied by the cardinality of a group in table t1. In this case
00083   in each correlated subquery SUM(t1.a) is used as a constant. But we also
00084   can evaluate SUM(t1.a) for the inner query. In this case t1.a will be a
00085   constant for each correlated subquery and summation is performed
00086   for each group of table t2.
00087   (Here it makes sense to remind that the query
00088     SELECT c FROM t GROUP BY a HAVING SUM(1) < a
00089   is quite legal in our SQL).
00090 
00091   So depending on what query we assign the set function to we
00092   can get different result sets.
00093 
00094   The general rule to detect the query where a set function is to be
00095   evaluated can be formulated as follows.
00096   Consider a set function S(E) where E is an expression with occurrences
00097   of column references C1, ..., CN. Resolve these column references against
00098   subqueries that contain the set function S(E). Let Q be the innermost
00099   subquery of those subqueries. (It should be noted here that S(E)
00100   in no way can be evaluated in the subquery embedding the subquery Q,
00101   otherwise S(E) would refer to at least one unbound column reference)
00102   If S(E) is used in a construct of Q where set functions are allowed then
00103   we evaluate S(E) in Q.
00104   Otherwise we look for a innermost subquery containing S(E) of those where
00105   usage of S(E) is allowed.
00106 
00107   Let's demonstrate how this rule is applied to the following queries.
00108 
00109   1. SELECT t1.a FROM t1 GROUP BY t1.a
00110        HAVING t1.a > ALL(SELECT t2.b FROM t2 GROUP BY t2.b
00111                            HAVING t2.b > ALL(SELECT t3.c FROM t3 GROUP BY t3.c
00112                                                 HAVING SUM(t1.a+t2.b) < t3.c))
00113   For this query the set function SUM(t1.a+t2.b) depends on t1.a and t2.b
00114   with t1.a defined in the outermost query, and t2.b defined for its
00115   subquery. The set function is in the HAVING clause of the subquery and can
00116   be evaluated in this subquery.
00117 
00118   2. SELECT t1.a FROM t1 GROUP BY t1.a
00119        HAVING t1.a > ALL(SELECT t2.b FROM t2
00120                            WHERE t2.b > ALL (SELECT t3.c FROM t3 GROUP BY t3.c
00121                                                HAVING SUM(t1.a+t2.b) < t3.c))
00122   Here the set function SUM(t1.a+t2.b)is in the WHERE clause of the second
00123   subquery - the most upper subquery where t1.a and t2.b are defined.
00124   If we evaluate the function in this subquery we violate the context rules.
00125   So we evaluate the function in the third subquery (over table t3) where it
00126   is used under the HAVING clause.
00127 
00128   3. SELECT t1.a FROM t1 GROUP BY t1.a
00129        HAVING t1.a > ALL(SELECT t2.b FROM t2
00130                            WHERE t2.b > ALL (SELECT t3.c FROM t3
00131                                                WHERE SUM(t1.a+t2.b) < t3.c))
00132   In this query evaluation of SUM(t1.a+t2.b) is not legal neither in the second
00133   nor in the third subqueries. So this query is invalid.
00134 
00135   Mostly set functions cannot be nested. In the query
00136     SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20
00137   the expression SUM(b) is not acceptable, though it is under a HAVING clause.
00138   Yet it is acceptable in the query:
00139     SELECT t.1 FROM t1 GROUP BY t1.a HAVING SUM(t1.b) > 20.
00140 
00141   An argument of a set function does not have to be a reference to a table
00142   column as we saw it in examples above. This can be a more complex expression
00143     SELECT t1.a FROM t1 GROUP BY t1.a HAVING SUM(t1.b+1) > 20.
00144   The expression SUM(t1.b+1) has a very clear semantics in this context:
00145   we sum up the values of t1.b+1 where t1.b varies for all values within a
00146   group of rows that contain the same t1.a value.
00147 
00148   A set function for an outer query yields a constant within a subquery. So
00149   the semantics of the query
00150     SELECT t1.a FROM t1 GROUP BY t1.a
00151       HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
00152                         HAVING AVG(t2.c+SUM(t1.b)) > 20)
00153   is still clear. For a group of the rows with the same t1.a values we
00154   calculate the value of SUM(t1.b). This value 's' is substituted in the
00155   the subquery:
00156     SELECT t2.c FROM t2 GROUP BY t2.c HAVING AVG(t2.c+s)
00157   than returns some result set.
00158 
00159   By the same reason the following query with a subquery
00160     SELECT t1.a FROM t1 GROUP BY t1.a
00161       HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
00162                         HAVING AVG(SUM(t1.b)) > 20)
00163   is also acceptable.
00164 
00165  IMPLEMENTATION NOTES
00166 
00167   Three methods were added to the class to check the constraints specified
00168   in the previous section. These methods utilize several new members.
00169 
00170   The field 'nest_level' contains the number of the level for the subquery
00171   containing the set function. The main SELECT is of level 0, its subqueries
00172   are of levels 1, the subqueries of the latter are of level 2 and so on.
00173 
00174   The field 'aggr_level' is to contain the nest level of the subquery
00175   where the set function is aggregated.
00176 
00177   The field 'max_arg_level' is for the maximun of the nest levels of the
00178   unbound column references occurred in the set function. A column reference
00179   is unbound  within a set function if it is not bound by any subquery
00180   used as a subexpression in this function. A column reference is bound by
00181   a subquery if it is a reference to the column by which the aggregation
00182   of some set function that is used in the subquery is calculated.
00183   For the set function used in the query
00184     SELECT t1.a FROM t1 GROUP BY t1.a
00185       HAVING t1.a > ALL(SELECT t2.b FROM t2 GROUP BY t2.b
00186                           HAVING t2.b > ALL(SELECT t3.c FROM t3 GROUP BY t3.c
00187                                               HAVING SUM(t1.a+t2.b) < t3.c))
00188   the value of max_arg_level is equal to 1 since t1.a is bound in the main
00189   query, and t2.b is bound by the first subquery whose nest level is 1.
00190   Obviously a set function cannot be aggregated in the subquery whose
00191   nest level is less than max_arg_level. (Yet it can be aggregated in the
00192   subqueries whose nest level is greater than max_arg_level.)
00193   In the query
00194     SELECT t.a FROM t1 HAVING AVG(t1.a+(SELECT MIN(t2.c) FROM t2))
00195   the value of the max_arg_level for the AVG set function is 0 since
00196   the reference t2.c is bound in the subquery.
00197 
00198   The field 'max_sum_func_level' is to contain the maximum of the
00199   nest levels of the set functions that are used as subexpressions of
00200   the arguments of the given set function, but not aggregated in any
00201   subquery within this set function. A nested set function s1 can be
00202   used within set function s0 only if s1.max_sum_func_level <
00203   s0.max_sum_func_level. Set function s1 is considered as nested
00204   for set function s0 if s1 is not calculated in any subquery
00205   within s0.
00206 
00207   A set function that is used as a subexpression in an argument of another
00208   set function refers to the latter via the field 'in_sum_func'.
00209 
00210   The condition imposed on the usage of set functions are checked when
00211   we traverse query subexpressions with the help of the recursive method
00212   fix_fields. When we apply this method to an object of the class
00213   Item_sum, first, on the descent, we call the method init_sum_func_check
00214   that initialize members used at checking. Then, on the ascent, we
00215   call the method check_sum_func that validates the set function usage
00216   and reports an error if it is illegal.
00217   The method register_sum_func serves to link the items for the set functions
00218   that are aggregated in the embedding (sub)queries. Circular chains of such
00219   functions are attached to the corresponding Select_Lex structures
00220   through the field inner_sum_func_list.
00221 
00222   Exploiting the fact that the members mentioned above are used in one
00223   recursive function we could have allocated them on the thread stack.
00224   Yet we don't do it now.
00225 
00226   We assume that the nesting level of subquries does not exceed 127.
00227   TODO: to catch queries where the limit is exceeded to make the
00228   code clean here.
00229 
00230 */
00231 
00232 class Item_sum :public Item_result_field
00233 {
00234 public:
00235   enum Sumfunctype
00236   { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC,
00237     AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC,
00238     VARIANCE_FUNC, SUM_BIT_FUNC, GROUP_CONCAT_FUNC
00239   };
00240 
00241   Item **args, *tmp_args[2];
00242   Item **ref_by; /* pointer to a ref to the object used to register it */
00243   Item_sum *next; /* next in the circular chain of registered objects  */
00244   uint32_t arg_count;
00245   Item_sum *in_sum_func;  /* embedding set function if any */
00246   Select_Lex * aggr_sel; /* select where the function is aggregated       */
00247   int8_t nest_level;        /* number of the nesting level of the set function */
00248   int8_t aggr_level;        /* nesting level of the aggregating subquery       */
00249   int8_t max_arg_level;     /* max level of unbound column references          */
00250   int8_t max_sum_func_level;/* max level of aggregation for embedded functions */
00251   bool quick_group;     /* If incremental update of fields */
00252   /*
00253     This list is used by the check for mixing non aggregated fields and
00254     sum functions in the ONLY_FULL_GROUP_BY_MODE. We save all outer fields
00255     directly or indirectly used under this function it as it's unclear
00256     at the moment of fixing outer field whether it's aggregated or not.
00257   */
00258   List<Item_field> outer_fields;
00259 
00260 protected:
00261   table_map used_tables_cache;
00262   bool forced_const;
00263 
00264 public:
00265 
00266   void mark_as_sum_func();
00267   Item_sum() :arg_count(0), quick_group(1), forced_const(false)
00268   {
00269     mark_as_sum_func();
00270   }
00271   Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1),
00272     forced_const(false)
00273   {
00274     args[0]=a;
00275     mark_as_sum_func();
00276   }
00277   Item_sum( Item *a, Item *b ) :args(tmp_args), arg_count(2), quick_group(1),
00278     forced_const(false)
00279   {
00280     args[0]=a; args[1]=b;
00281     mark_as_sum_func();
00282   }
00283   Item_sum(List<Item> &list);
00284   //Copy constructor, need to perform subselects with temporary tables
00285   Item_sum(Session *session, Item_sum *item);
00286   enum Type type() const { return SUM_FUNC_ITEM; }
00287   virtual enum Sumfunctype sum_func () const=0;
00288 
00289   /*
00290     This method is similar to add(), but it is called when the current
00291     aggregation group changes. Thus it performs a combination of
00292     clear() and add().
00293   */
00294   inline bool reset() { clear(); return add(); };
00295 
00296   /*
00297     Prepare this item for evaluation of an aggregate value. This is
00298     called by reset() when a group changes, or, for correlated
00299     subqueries, between subquery executions.  E.g. for COUNT(), this
00300     method should set count= 0;
00301   */
00302   virtual void clear()= 0;
00303 
00304   /*
00305     This method is called for the next row in the same group. Its
00306     purpose is to aggregate the new value to the previous values in
00307     the group (i.e. since clear() was called last time). For example,
00308     for COUNT(), do count++.
00309   */
00310   virtual bool add()=0;
00311 
00312   /*
00313     Called when new group is started and results are being saved in
00314     a temporary table. Similar to reset(), but must also store value in
00315     result_field. Like reset() it is supposed to reset start value to
00316     default.
00317     This set of methods (reult_field(), reset_field, update_field()) of
00318     Item_sum is used only if quick_group is not null. Otherwise
00319     copy_or_same() is used to obtain a copy of this item.
00320   */
00321   virtual void reset_field()=0;
00322   /*
00323     Called for each new value in the group, when temporary table is in use.
00324     Similar to add(), but uses temporary table field to obtain current value,
00325     Updated value is then saved in the field.
00326   */
00327   virtual void update_field()=0;
00328   virtual bool keep_field_type(void) const { return 0; }
00329   virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
00330   /*
00331     This method is used for debug purposes to print the name of an
00332     item to the debug log. The second use of this method is as
00333     a helper function of print(), where it is applicable.
00334     To suit both goals it should return a meaningful,
00335     distinguishable and sintactically correct string.  This method
00336     should not be used for runtime type identification, use enum
00337     {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
00338     instead.
00339 
00340     NOTE: for Items inherited from Item_sum, func_name() return part of
00341     function name till first argument (including '(') to make difference in
00342     names for functions with 'distinct' clause and without 'distinct' and
00343     also to make printing of items inherited from Item_sum uniform.
00344   */
00345   virtual const char *func_name() const= 0;
00346   virtual Item *result_item(Field *field)
00347     { return new Item_field(field); }
00348   table_map used_tables() const { return used_tables_cache; }
00349   void update_used_tables ();
00350   void cleanup()
00351   {
00352     Item::cleanup();
00353     forced_const= false;
00354   }
00355   bool is_null() { return null_value; }
00356   void make_const ()
00357   {
00358     used_tables_cache= 0;
00359     forced_const= true;
00360   }
00361   virtual bool const_item() const { return forced_const; }
00362   virtual bool const_during_execution() const { return false; }
00363   void make_field(SendField *field);
00364   virtual void print(String *str);
00365   void fix_num_length_and_dec();
00366 
00367   /*
00368     This function is called by the execution engine to assign 'NO ROWS
00369     FOUND' value to an aggregate item, when the underlying result set
00370     has no rows. Such value, in a general case, may be different from
00371     the default value of the item after 'clear()': e.g. a numeric item
00372     may be initialized to 0 by clear() and to NULL by
00373     no_rows_in_result().
00374   */
00375   void no_rows_in_result() { clear(); }
00376 
00377   virtual bool setup(Session *) {return 0;}
00378   virtual void make_unique(void) {}
00379   Item *get_tmp_table_item(Session *session);
00380   virtual Field *create_tmp_field(bool group, Table *table,
00381                                   uint32_t convert_blob_length);
00382   bool walk(Item_processor processor, bool walk_subquery, unsigned char *argument);
00383   bool init_sum_func_check(Session *session);
00384   bool check_sum_func(Session *session, Item **ref);
00385   bool register_sum_func(Session *session, Item **ref);
00386   Select_Lex *depended_from()
00387     { return (nest_level == aggr_level ? 0 : aggr_sel); }
00388 };
00389 
00390 
00391 class Item_sum_num :public Item_sum
00392 {
00393 protected:
00394   /*
00395    val_xxx() functions may be called several times during the execution of a
00396    query. Derived classes that require extensive calculation in val_xxx()
00397    maintain cache of aggregate value. This variable governs the validity of
00398    that cache.
00399   */
00400   bool is_evaluated;
00401 public:
00402   Item_sum_num() :Item_sum(),is_evaluated(false) {}
00403   Item_sum_num(Item *item_par)
00404     :Item_sum(item_par), is_evaluated(false) {}
00405   Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(false) {}
00406   Item_sum_num(List<Item> &list)
00407     :Item_sum(list), is_evaluated(false) {}
00408   Item_sum_num(Session *session, Item_sum_num *item)
00409     :Item_sum(session, item),is_evaluated(item->is_evaluated) {}
00410   bool fix_fields(Session *, Item **);
00411   int64_t val_int();
00412   String *val_str(String*str);
00413   type::Decimal *val_decimal(type::Decimal *);
00414   void reset_field();
00415 };
00416 
00417 
00418 class Item_sum_int :public Item_sum_num
00419 {
00420 public:
00421   Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
00422   Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
00423   Item_sum_int(Session *session, Item_sum_int *item) :Item_sum_num(session, item) {}
00424   double val_real() { assert(fixed == 1); return (double) val_int(); }
00425   String *val_str(String*str);
00426   type::Decimal *val_decimal(type::Decimal *);
00427   enum Item_result result_type () const { return INT_RESULT; }
00428   void fix_length_and_dec()
00429   { decimals=0; max_length=21; maybe_null=null_value=0; }
00430 };
00431 
00432 
00433 class Item_sum_sum :public Item_sum_num
00434 {
00435 protected:
00436   Item_result hybrid_type;
00437   double sum;
00438   type::Decimal dec_buffs[2];
00439   uint32_t curr_dec_buff;
00440   void fix_length_and_dec();
00441 
00442 public:
00443   Item_sum_sum(Item *item_par) :Item_sum_num(item_par) {}
00444   Item_sum_sum(Session *session, Item_sum_sum *item);
00445   enum Sumfunctype sum_func () const {return SUM_FUNC;}
00446   void clear();
00447   bool add();
00448   double val_real();
00449   int64_t val_int();
00450   String *val_str(String*str);
00451   type::Decimal *val_decimal(type::Decimal *);
00452   enum Item_result result_type () const { return hybrid_type; }
00453   void reset_field();
00454   void update_field();
00455   void no_rows_in_result() {}
00456   const char *func_name() const { return "sum("; }
00457   Item *copy_or_same(Session* session);
00458 };
00459 
00460 
00461 
00462 /* Common class for SUM(DISTINCT), AVG(DISTINCT) */
00463 
00464 class Item_sum_distinct :public Item_sum_num
00465 {
00466 protected:
00467   /* storage for the summation result */
00468   uint64_t count;
00469   Hybrid_type val;
00470   /* storage for unique elements */
00471   Unique *tree;
00472   Table *table;
00473   enum enum_field_types table_field_type;
00474   uint32_t tree_key_length;
00475 protected:
00476   Item_sum_distinct(Session *session, Item_sum_distinct *item);
00477 public:
00478   Item_sum_distinct(Item *item_par);
00479   ~Item_sum_distinct();
00480 
00481   bool setup(Session *session);
00482   void clear();
00483   void cleanup();
00484   bool add();
00485   double val_real();
00486   type::Decimal *val_decimal(type::Decimal *);
00487   int64_t val_int();
00488   String *val_str(String *str);
00489 
00490   /* XXX: does it need make_unique? */
00491 
00492   enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
00493   void reset_field() {} // not used
00494   void update_field() {} // not used
00495   virtual void no_rows_in_result() {}
00496   void fix_length_and_dec();
00497   enum Item_result result_type () const;
00498   virtual void calculate_val_and_count();
00499   virtual bool unique_walk_function(void *elem);
00500 };
00501 
00502 
00503 /*
00504   Item_sum_sum_distinct - implementation of SUM(DISTINCT expr).
00505   See also: MySQL manual, chapter 'Adding New Functions To MySQL'
00506   and comments in item_sum.cc.
00507 */
00508 
00509 class Item_sum_sum_distinct :public Item_sum_distinct
00510 {
00511 private:
00512   Item_sum_sum_distinct(Session *session, Item_sum_sum_distinct *item)
00513     :Item_sum_distinct(session, item) {}
00514 public:
00515   Item_sum_sum_distinct(Item *item_arg) :Item_sum_distinct(item_arg) {}
00516 
00517   enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
00518   const char *func_name() const { return "sum(distinct "; }
00519   Item *copy_or_same(Session* session) { return new Item_sum_sum_distinct(session, this); }
00520 };
00521 
00522 
00523 /* Item_sum_avg_distinct - SELECT AVG(DISTINCT expr) FROM ... */
00524 
00525 class Item_sum_avg_distinct: public Item_sum_distinct
00526 {
00527 private:
00528   Item_sum_avg_distinct(Session *session, Item_sum_avg_distinct *original)
00529     :Item_sum_distinct(session, original) {}
00530 public:
00531   uint32_t prec_increment;
00532   Item_sum_avg_distinct(Item *item_arg) : Item_sum_distinct(item_arg) {}
00533 
00534   void fix_length_and_dec();
00535   virtual void calculate_val_and_count();
00536   enum Sumfunctype sum_func () const { return AVG_DISTINCT_FUNC; }
00537   const char *func_name() const { return "avg(distinct "; }
00538   Item *copy_or_same(Session* session) { return new Item_sum_avg_distinct(session, this); }
00539 };
00540 
00541 
00542 class Item_sum_count :public Item_sum_int
00543 {
00544   int64_t count;
00545 
00546   public:
00547   Item_sum_count(Item *item_par)
00548     :Item_sum_int(item_par),count(0)
00549   {}
00550   Item_sum_count(Session *session, Item_sum_count *item)
00551     :Item_sum_int(session, item), count(item->count)
00552   {}
00553   enum Sumfunctype sum_func () const { return COUNT_FUNC; }
00554   void clear();
00555   void no_rows_in_result() { count=0; }
00556   bool add();
00557   void make_const_count(int64_t count_arg)
00558   {
00559     count=count_arg;
00560     Item_sum::make_const();
00561   }
00562   int64_t val_int();
00563   void reset_field();
00564   void cleanup();
00565   void update_field();
00566   const char *func_name() const { return "count("; }
00567   Item *copy_or_same(Session* session);
00568 };
00569 
00570 
00571 class Item_sum_count_distinct :public Item_sum_int
00572 {
00573   Table *table;
00574   uint32_t *field_lengths;
00575   Tmp_Table_Param *tmp_table_param;
00576   bool force_copy_fields;
00577   /*
00578     If there are no blobs, we can use a tree, which
00579     is faster than heap table. In that case, we still use the table
00580     to help get things set up, but we insert nothing in it
00581   */
00582   Unique *tree;
00583   /*
00584    Storage for the value of count between calls to val_int() so val_int()
00585    will not recalculate on each call. Validitiy of the value is stored in
00586    is_evaluated.
00587   */
00588   int64_t count;
00589   /*
00590     Following is 0 normal object and pointer to original one for copy
00591     (to correctly free resources)
00592   */
00593   Item_sum_count_distinct *original;
00594   uint32_t tree_key_length;
00595 
00596 
00597   bool always_null;   // Set to 1 if the result is always NULL
00598 
00599 
00600   friend int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2);
00601   friend int simple_str_key_cmp(void* arg, unsigned char* key1, unsigned char* key2);
00602 
00603 public:
00604   Item_sum_count_distinct(List<Item> &list)
00605     :Item_sum_int(list), table(0), field_lengths(0), tmp_table_param(0),
00606      force_copy_fields(0), tree(0), count(0),
00607      original(0), always_null(false)
00608   { quick_group= 0; }
00609   Item_sum_count_distinct(Session *session, Item_sum_count_distinct *item)
00610     :Item_sum_int(session, item), table(item->table),
00611      field_lengths(item->field_lengths),
00612      tmp_table_param(item->tmp_table_param),
00613      force_copy_fields(0), tree(item->tree), count(item->count),
00614      original(item), tree_key_length(item->tree_key_length),
00615      always_null(item->always_null)
00616   {}
00617   ~Item_sum_count_distinct();
00618 
00619   void cleanup();
00620 
00621   enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
00622   void clear();
00623   bool add();
00624   int64_t val_int();
00625   void reset_field() { return ;}    // Never called
00626   void update_field() { return ; }    // Never called
00627   const char *func_name() const { return "count(distinct "; }
00628   bool setup(Session *session);
00629   void make_unique();
00630   Item *copy_or_same(Session* session);
00631   void no_rows_in_result() {}
00632 };
00633 
00634 
00635 /* Item to get the value of a stored sum function */
00636 
00637 class Item_avg_field :public Item_result_field
00638 {
00639 public:
00640   Field *field;
00641   Item_result hybrid_type;
00642   uint32_t f_precision, f_scale, dec_bin_size;
00643   uint32_t prec_increment;
00644   Item_avg_field(Item_result res_type, Item_sum_avg *item);
00645   enum Type type() const { return FIELD_AVG_ITEM; }
00646   double val_real();
00647   int64_t val_int();
00648   type::Decimal *val_decimal(type::Decimal *);
00649   bool is_null() { update_null_value(); return null_value; }
00650   String *val_str(String*);
00651   enum_field_types field_type() const
00652   {
00653     return hybrid_type == DECIMAL_RESULT ?
00654       DRIZZLE_TYPE_DECIMAL : DRIZZLE_TYPE_DOUBLE;
00655   }
00656   void fix_length_and_dec() {}
00657   enum Item_result result_type () const { return hybrid_type; }
00658 };
00659 
00660 
00661 class Item_sum_avg :public Item_sum_sum
00662 {
00663 public:
00664   uint64_t count;
00665   uint32_t prec_increment;
00666   uint32_t f_precision, f_scale, dec_bin_size;
00667 
00668   Item_sum_avg(Item *item_par) :Item_sum_sum(item_par), count(0) {}
00669   Item_sum_avg(Session *session, Item_sum_avg *item)
00670     :Item_sum_sum(session, item), count(item->count),
00671     prec_increment(item->prec_increment) {}
00672 
00673   void fix_length_and_dec();
00674   enum Sumfunctype sum_func () const {return AVG_FUNC;}
00675   void clear();
00676   bool add();
00677   double val_real();
00678   // In SPs we might force the "wrong" type with select into a declare variable
00679   int64_t val_int();
00680   type::Decimal *val_decimal(type::Decimal *);
00681   String *val_str(String *str);
00682   void reset_field();
00683   void update_field();
00684   Item *result_item(Field *)
00685   { return new Item_avg_field(hybrid_type, this); }
00686   void no_rows_in_result() {}
00687   const char *func_name() const { return "avg("; }
00688   Item *copy_or_same(Session* session);
00689   Field *create_tmp_field(bool group, Table *table, uint32_t convert_blob_length);
00690   void cleanup()
00691   {
00692     count= 0;
00693     Item_sum_sum::cleanup();
00694   }
00695 };
00696 
00697 class Item_variance_field :public Item_result_field
00698 {
00699 public:
00700   Field *field;
00701   Item_result hybrid_type;
00702   uint32_t f_precision0, f_scale0;
00703   uint32_t f_precision1, f_scale1;
00704   uint32_t dec_bin_size0, dec_bin_size1;
00705   uint32_t sample;
00706   uint32_t prec_increment;
00707   Item_variance_field(Item_sum_variance *item);
00708   enum Type type() const {return FIELD_VARIANCE_ITEM; }
00709   double val_real();
00710   int64_t val_int();
00711   String *val_str(String *str)
00712   { return val_string_from_real(str); }
00713   type::Decimal *val_decimal(type::Decimal *dec_buf)
00714   { return val_decimal_from_real(dec_buf); }
00715   bool is_null() { update_null_value(); return null_value; }
00716   enum_field_types field_type() const
00717   {
00718     return hybrid_type == DECIMAL_RESULT ?
00719       DRIZZLE_TYPE_DECIMAL : DRIZZLE_TYPE_DOUBLE;
00720   }
00721   void fix_length_and_dec() {}
00722   enum Item_result result_type () const { return hybrid_type; }
00723 };
00724 
00725 
00726 /*
00727   variance(a) =
00728 
00729   =  sum (ai - avg(a))^2 / count(a) )
00730   =  sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a)
00731   =  (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) =
00732   =  (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) =
00733   =  (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
00734   =  (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
00735   =  (sum(ai^2) - sum(a)^2/count(a))/count(a)
00736 
00737 But, this falls prey to catastrophic cancellation.  Instead, use the recurrence formulas
00738 
00739   M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline
00740   S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline
00741   for 2 <= k <= n newline
00742   ital variance = S_{n} / (n-1)
00743 
00744 */
00745 
00746 class Item_sum_variance : public Item_sum_num
00747 {
00748   void fix_length_and_dec();
00749 
00750 public:
00751   Item_result hybrid_type;
00752   int cur_dec;
00753   double recurrence_m, recurrence_s;    /* Used in recurrence relation. */
00754   uint64_t count;
00755   uint32_t f_precision0, f_scale0;
00756   uint32_t f_precision1, f_scale1;
00757   uint32_t dec_bin_size0, dec_bin_size1;
00758   uint32_t sample;
00759   uint32_t prec_increment;
00760 
00761   Item_sum_variance(Item *item_par, uint32_t sample_arg) :Item_sum_num(item_par),
00762     hybrid_type(REAL_RESULT), count(0), sample(sample_arg)
00763     {}
00764   Item_sum_variance(Session *session, Item_sum_variance *item);
00765   enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
00766   void clear();
00767   bool add();
00768   double val_real();
00769   int64_t val_int();
00770   type::Decimal *val_decimal(type::Decimal *);
00771   void reset_field();
00772   void update_field();
00773   Item *result_item(Field *)
00774   { return new Item_variance_field(this); }
00775   void no_rows_in_result() {}
00776   const char *func_name() const
00777     { return sample ? "var_samp(" : "variance("; }
00778   Item *copy_or_same(Session* session);
00779   Field *create_tmp_field(bool group, Table *table, uint32_t convert_blob_length);
00780   enum Item_result result_type () const { return REAL_RESULT; }
00781   void cleanup()
00782   {
00783     count= 0;
00784     Item_sum_num::cleanup();
00785   }
00786 };
00787 
00788 class Item_std_field :public Item_variance_field
00789 {
00790 public:
00791   Item_std_field(Item_sum_std *item);
00792   enum Type type() const { return FIELD_STD_ITEM; }
00793   double val_real();
00794   type::Decimal *val_decimal(type::Decimal *);
00795   enum Item_result result_type () const { return REAL_RESULT; }
00796   enum_field_types field_type() const { return DRIZZLE_TYPE_DOUBLE;}
00797 };
00798 
00799 /*
00800    standard_deviation(a) = sqrt(variance(a))
00801 */
00802 
00803 class Item_sum_std :public Item_sum_variance
00804 {
00805   public:
00806   Item_sum_std(Item *item_par, uint32_t sample_arg)
00807     :Item_sum_variance(item_par, sample_arg) {}
00808   Item_sum_std(Session *session, Item_sum_std *item)
00809     :Item_sum_variance(session, item)
00810     {}
00811   enum Sumfunctype sum_func () const { return STD_FUNC; }
00812   double val_real();
00813   Item *result_item(Field *)
00814     { return new Item_std_field(this); }
00815   const char *func_name() const { return "std("; }
00816   Item *copy_or_same(Session* session);
00817   enum Item_result result_type () const { return REAL_RESULT; }
00818   enum_field_types field_type() const { return DRIZZLE_TYPE_DOUBLE;}
00819 };
00820 
00821 // This class is a string or number function depending on num_func
00822 
00823 class Item_sum_hybrid :public Item_sum
00824 {
00825 protected:
00826   String value,tmp_value;
00827   double sum;
00828   int64_t sum_int;
00829   type::Decimal sum_dec;
00830   Item_result hybrid_type;
00831   enum_field_types hybrid_field_type;
00832   int cmp_sign;
00833   bool was_values;  // Set if we have found at least one row (for max/min only)
00834 
00835   public:
00836   Item_sum_hybrid(Item *item_par,int sign)
00837     :Item_sum(item_par), sum(0.0), sum_int(0),
00838     hybrid_type(INT_RESULT), hybrid_field_type(DRIZZLE_TYPE_LONGLONG),
00839     cmp_sign(sign), was_values(true)
00840   { collation.set(&my_charset_bin); }
00841   Item_sum_hybrid(Session *session, Item_sum_hybrid *item);
00842   bool fix_fields(Session *, Item **);
00843   void clear();
00844   double val_real();
00845   int64_t val_int();
00846   type::Decimal *val_decimal(type::Decimal *);
00847   void reset_field();
00848   String *val_str(String *);
00849   bool keep_field_type(void) const { return 1; }
00850   enum Item_result result_type () const { return hybrid_type; }
00851   enum enum_field_types field_type() const { return hybrid_field_type; }
00852   void update_field();
00853   void min_max_update_str_field();
00854   void min_max_update_real_field();
00855   void min_max_update_int_field();
00856   void min_max_update_decimal_field();
00857   void cleanup();
00858   bool any_value() { return was_values; }
00859   void no_rows_in_result();
00860   Field *create_tmp_field(bool group, Table *table,
00861         uint32_t convert_blob_length);
00862 };
00863 
00864 
00865 class Item_sum_min :public Item_sum_hybrid
00866 {
00867 public:
00868   Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
00869   Item_sum_min(Session *session, Item_sum_min *item) :Item_sum_hybrid(session, item) {}
00870   enum Sumfunctype sum_func () const {return MIN_FUNC;}
00871 
00872   bool add();
00873   const char *func_name() const { return "min("; }
00874   Item *copy_or_same(Session* session);
00875 };
00876 
00877 
00878 class Item_sum_max :public Item_sum_hybrid
00879 {
00880 public:
00881   Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
00882   Item_sum_max(Session *session, Item_sum_max *item) :Item_sum_hybrid(session, item) {}
00883   enum Sumfunctype sum_func () const {return MAX_FUNC;}
00884 
00885   bool add();
00886   const char *func_name() const { return "max("; }
00887   Item *copy_or_same(Session* session);
00888 };
00889 
00890 
00891 class Item_sum_bit :public Item_sum_int
00892 {
00893 protected:
00894   uint64_t reset_bits,bits;
00895 
00896 public:
00897   Item_sum_bit(Item *item_par,uint64_t reset_arg)
00898     :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
00899   Item_sum_bit(Session *session, Item_sum_bit *item):
00900     Item_sum_int(session, item), reset_bits(item->reset_bits), bits(item->bits) {}
00901   enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
00902   void clear();
00903   int64_t val_int();
00904   void reset_field();
00905   void update_field();
00906   void fix_length_and_dec()
00907   { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
00908   void cleanup()
00909   {
00910     bits= reset_bits;
00911     Item_sum_int::cleanup();
00912   }
00913 };
00914 
00915 
00916 class Item_sum_or :public Item_sum_bit
00917 {
00918 public:
00919   Item_sum_or(Item *item_par) :Item_sum_bit(item_par,0) {}
00920   Item_sum_or(Session *session, Item_sum_or *item) :Item_sum_bit(session, item) {}
00921   bool add();
00922   const char *func_name() const { return "bit_or("; }
00923   Item *copy_or_same(Session* session);
00924 };
00925 
00926 
00927 class Item_sum_and :public Item_sum_bit
00928 {
00929   public:
00930   Item_sum_and(Item *item_par) :Item_sum_bit(item_par, UINT64_MAX) {}
00931   Item_sum_and(Session *session, Item_sum_and *item) :Item_sum_bit(session, item) {}
00932   bool add();
00933   const char *func_name() const { return "bit_and("; }
00934   Item *copy_or_same(Session* session);
00935 };
00936 
00937 class Item_sum_xor :public Item_sum_bit
00938 {
00939   public:
00940   Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,0) {}
00941   Item_sum_xor(Session *session, Item_sum_xor *item) :Item_sum_bit(session, item) {}
00942   bool add();
00943   const char *func_name() const { return "bit_xor("; }
00944   Item *copy_or_same(Session* session);
00945 };
00946 
00947 class Item_func_group_concat : public Item_sum
00948 {
00949   Tmp_Table_Param *tmp_table_param;
00950   DRIZZLE_ERROR *warning;
00951   String result;
00952   String *separator;
00953   Tree tree_base;
00954   Tree *tree;
00955 
00963   Unique *unique_filter;
00964   Table *table;
00965   Order **order;
00966   Name_resolution_context *context;
00968   uint32_t arg_count_order;
00970   uint32_t arg_count_field;
00971   uint32_t count_cut_values;
00972   bool distinct;
00973   bool warning_for_row;
00974   bool always_null;
00975   bool force_copy_fields;
00976   bool no_appended;
00977   /*
00978     Following is 0 normal object and pointer to original one for copy
00979     (to correctly free resources)
00980   */
00981   Item_func_group_concat *original;
00982 
00983   friend int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
00984                                                 const void* key2);
00985   friend int group_concat_key_cmp_with_order(void* arg, const void* key1,
00986                const void* key2);
00987   friend int dump_leaf_key(unsigned char* key, uint32_t,
00988                            Item_func_group_concat *group_concat_item);
00989 
00990 public:
00991   Item_func_group_concat(Name_resolution_context *context_arg,
00992                          bool is_distinct, List<Item> *is_select,
00993                          SQL_LIST *is_order, String *is_separator);
00994 
00995   Item_func_group_concat(Session *session, Item_func_group_concat *item);
00996   ~Item_func_group_concat();
00997   void cleanup();
00998 
00999   enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
01000   const char *func_name() const { return "group_concat"; }
01001   virtual Item_result result_type () const { return STRING_RESULT; }
01002   enum_field_types field_type() const
01003   {
01004     if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB )
01005       return DRIZZLE_TYPE_BLOB;
01006     else
01007       return DRIZZLE_TYPE_VARCHAR;
01008   }
01009   void clear();
01010   bool add();
01011   void reset_field() { assert(0); }        // not used
01012   void update_field() { assert(0); }       // not used
01013   bool fix_fields(Session *,Item **);
01014   bool setup(Session *session);
01015   void make_unique();
01016   double val_real();
01017   int64_t val_int();
01018   type::Decimal *val_decimal(type::Decimal *decimal_value)
01019   {
01020     return val_decimal_from_string(decimal_value);
01021   }
01022   String* val_str(String* str);
01023   Item *copy_or_same(Session* session);
01024   void no_rows_in_result() {}
01025   virtual void print(String *str);
01026   virtual bool change_context_processor(unsigned char *cntx)
01027     { context= (Name_resolution_context *)cntx; return false; }
01028 };
01029 
01030 } /* namespace drizzled */
01031