My Project
item_sum.h
00001 #ifndef ITEM_SUM_INCLUDED
00002 #define ITEM_SUM_INCLUDED
00003 
00004 /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. reserved.
00005    reserved.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; version 2 of the License.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
00019 
00020 
00021 /* classes for sum functions */
00022 
00023 #include <my_tree.h>
00024 #include "sql_udf.h"                            /* udf_handler */
00025 
00026 class Item_sum;
00027 class Aggregator_distinct;
00028 class Aggregator_simple;
00029 
00042 class Aggregator : public Sql_alloc
00043 {
00044   friend class Item_sum;
00045   friend class Item_sum_sum;
00046   friend class Item_sum_count;
00047   friend class Item_sum_avg;
00048 
00049   /* 
00050     All members are protected as this class is not usable outside of an 
00051     Item_sum descendant.
00052   */
00053 protected:
00054   /* the aggregate function class to act on */
00055   Item_sum *item_sum;
00056 
00057 public:
00058   Aggregator (Item_sum *arg): item_sum(arg) {}
00059   virtual ~Aggregator () {}                   /* Keep gcc happy */
00060 
00061   enum Aggregator_type { SIMPLE_AGGREGATOR, DISTINCT_AGGREGATOR }; 
00062   virtual Aggregator_type Aggrtype() = 0;
00063 
00069   virtual bool setup(THD *) = 0;
00070 
00076   virtual void clear() = 0;
00077 
00082   virtual bool add() = 0;
00083 
00088   virtual void endup() = 0;
00089 
00091   virtual my_decimal *arg_val_decimal(my_decimal * value) = 0;
00093   virtual double arg_val_real() = 0;
00104   virtual bool arg_is_null(bool use_null_value) = 0;
00105 };
00106 
00107 
00108 class st_select_lex;
00109 
00305 class Item_sum :public Item_result_field
00306 {
00307   friend class Aggregator_distinct;
00308   friend class Aggregator_simple;
00309 
00310 protected:
00315   Aggregator *aggr;
00316 
00317 private:
00324   bool force_copy_fields;
00325 
00331   bool with_distinct;
00332 
00333 public:
00334 
00335   bool has_force_copy_fields() const { return force_copy_fields; }
00336   bool has_with_distinct()     const { return with_distinct; }
00337 
00338   enum Sumfunctype
00339   { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC,
00340     AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC,
00341     VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC
00342   };
00343 
00344   Item **ref_by; /* pointer to a ref to the object used to register it */
00345   Item_sum *next; /* next in the circular chain of registered objects  */
00346   Item_sum *in_sum_func;  /* embedding set function if any */ 
00347   st_select_lex * aggr_sel; /* select where the function is aggregated       */ 
00348   int8 nest_level;        /* number of the nesting level of the set function */
00349   int8 aggr_level;        /* nesting level of the aggregating subquery       */
00350   int8 max_arg_level;     /* max level of unbound column references          */
00351   int8 max_sum_func_level;/* max level of aggregation for embedded functions */
00352   bool quick_group;                     /* If incremental update of fields */
00353   /*
00354     This list is used by the check for mixing non aggregated fields and
00355     sum functions in the ONLY_FULL_GROUP_BY_MODE. We save all outer fields
00356     directly or indirectly used under this function it as it's unclear
00357     at the moment of fixing outer field whether it's aggregated or not.
00358   */
00359   List<Item_field> outer_fields;
00360 
00361 protected:  
00362   uint arg_count;
00363   Item **args, *tmp_args[2];
00364   /* 
00365     Copy of the arguments list to hold the original set of arguments.
00366     Used in EXPLAIN EXTENDED instead of the current argument list because 
00367     the current argument list can be altered by usage of temporary tables.
00368   */
00369   Item **orig_args, *tmp_orig_args[2];
00370   table_map used_tables_cache;
00371   bool forced_const;
00372   static ulonglong ram_limitation(THD *thd);
00373 
00374 public:  
00375 
00376   void mark_as_sum_func();
00377   Item_sum() :next(NULL), quick_group(1), arg_count(0), forced_const(FALSE)
00378   {
00379     mark_as_sum_func();
00380     init_aggregator();
00381   }
00382   Item_sum(Item *a) :next(NULL), quick_group(1), arg_count(1), args(tmp_args),
00383     orig_args(tmp_orig_args), forced_const(FALSE)
00384   {
00385     args[0]=a;
00386     mark_as_sum_func();
00387     init_aggregator();
00388   }
00389   Item_sum( Item *a, Item *b ) :next(NULL), quick_group(1), arg_count(2), args(tmp_args),
00390     orig_args(tmp_orig_args), forced_const(FALSE)
00391   {
00392     args[0]=a; args[1]=b;
00393     mark_as_sum_func();
00394     init_aggregator();
00395   }
00396   Item_sum(List<Item> &list);
00397   //Copy constructor, need to perform subselects with temporary tables
00398   Item_sum(THD *thd, Item_sum *item);
00399   enum Type type() const { return SUM_FUNC_ITEM; }
00400   virtual enum Sumfunctype sum_func () const=0;
00405   inline bool reset_and_add() 
00406   { 
00407     aggregator_clear(); 
00408     return aggregator_add(); 
00409   };
00410 
00411   /*
00412     Called when new group is started and results are being saved in
00413     a temporary table. Similarly to reset_and_add() it resets the 
00414     value to its default and aggregates the value of its 
00415     attribute(s), but must also store it in result_field. 
00416     This set of methods (result_item(), reset_field, update_field()) of
00417     Item_sum is used only if quick_group is not null. Otherwise
00418     copy_or_same() is used to obtain a copy of this item.
00419   */
00420   virtual void reset_field()=0;
00421   /*
00422     Called for each new value in the group, when temporary table is in use.
00423     Similar to add(), but uses temporary table field to obtain current value,
00424     Updated value is then saved in the field.
00425   */
00426   virtual void update_field()=0;
00427   virtual bool keep_field_type(void) const { return 0; }
00428   virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
00429   virtual Item *result_item(Field *field)
00430     { return new Item_field(field); }
00431   table_map used_tables() const { return used_tables_cache; }
00432   void update_used_tables ();
00433   bool is_null() { return null_value; }
00434   void make_const () 
00435   { 
00436     used_tables_cache= 0; 
00437     forced_const= TRUE; 
00438   }
00439   virtual bool const_item() const { return forced_const; }
00440   virtual bool const_during_execution() const { return false; }
00441   virtual void print(String *str, enum_query_type query_type);
00442   void fix_num_length_and_dec();
00443 
00454   virtual void no_rows_in_result()
00455   {
00456     set_aggregator(with_distinct ?
00457                    Aggregator::DISTINCT_AGGREGATOR :
00458                    Aggregator::SIMPLE_AGGREGATOR);
00459     aggregator_clear();
00460   }
00461   virtual void make_unique() { force_copy_fields= TRUE; }
00462   Item *get_tmp_table_item(THD *thd);
00463   virtual Field *create_tmp_field(bool group, TABLE *table);
00464   bool walk(Item_processor processor, bool walk_subquery, uchar *argument);
00465   virtual bool clean_up_after_removal(uchar *arg);
00466   bool init_sum_func_check(THD *thd);
00467   bool check_sum_func(THD *thd, Item **ref);
00468   bool register_sum_func(THD *thd, Item **ref);
00469   st_select_lex *depended_from() 
00470     { return (nest_level == aggr_level ? 0 : aggr_sel); }
00471 
00472   Item *get_arg(uint i) { return args[i]; }
00473   Item *set_arg(uint i, THD *thd, Item *new_val);
00474   uint get_arg_count() const { return arg_count; }
00475 
00476   /* Initialization of distinct related members */
00477   void init_aggregator()
00478   {
00479     aggr= NULL;
00480     with_distinct= FALSE;
00481     force_copy_fields= FALSE;
00482   }
00483 
00488   inline bool aggregator_setup(THD *thd) { return aggr->setup(thd); };
00489 
00494   inline void aggregator_clear() { aggr->clear(); }
00495 
00500   inline bool aggregator_add() { return aggr->add(); };
00501 
00502   /* stores the declared DISTINCT flag (from the parser) */
00503   void set_distinct(bool distinct)
00504   {
00505     with_distinct= distinct;
00506     quick_group= with_distinct ? 0 : 1;
00507   }
00508 
00509   /*
00510     Set the type of aggregation : DISTINCT or not.
00511 
00512     May be called multiple times.
00513   */
00514 
00515   int set_aggregator(Aggregator::Aggregator_type aggregator);
00516 
00517   virtual void clear()= 0;
00518   virtual bool add()= 0;
00519   virtual bool setup(THD *thd) { return false; }
00520 
00521   virtual void cleanup();
00522 };
00523 
00524 
00525 class Unique;
00526 
00527 
00536 class Aggregator_distinct : public Aggregator
00537 {
00538   friend class Item_sum_sum;
00539 
00540   /* 
00541     flag to prevent consecutive runs of endup(). Normally in endup there are 
00542     expensive calculations (like walking the distinct tree for example) 
00543     which we must do only once if there are no data changes.
00544     We can re-use the data for the second and subsequent val_xxx() calls.
00545     endup_done set to TRUE also means that the calculated values for
00546     the aggregate functions are correct and don't need recalculation.
00547   */
00548   bool endup_done;
00549 
00550   /*
00551     Used depending on the type of the aggregate function and the presence of
00552     blob columns in it:
00553     - For COUNT(DISTINCT) and no blob fields this points to a real temporary
00554       table. It's used as a hash table.
00555     - For AVG/SUM(DISTINCT) or COUNT(DISTINCT) with blob fields only the
00556       in-memory data structure of a temporary table is constructed.
00557       It's used by the Field classes to transform data into row format.
00558   */
00559   TABLE *table;
00560   
00561   /*
00562     An array of field lengths on row allocated and used only for 
00563     COUNT(DISTINCT) with multiple columns and no blobs. Used in 
00564     Aggregator_distinct::composite_key_cmp (called from Unique to compare 
00565     nodes
00566   */
00567   uint32 *field_lengths;
00568 
00569   /*
00570     Used in conjunction with 'table' to support the access to Field classes 
00571     for COUNT(DISTINCT). Needed by copy_fields()/copy_funcs().
00572   */
00573   TMP_TABLE_PARAM *tmp_table_param;
00574   
00575   /*
00576     If there are no blobs in the COUNT(DISTINCT) arguments, we can use a tree,
00577     which is faster than heap table. In that case, we still use the table
00578     to help get things set up, but we insert nothing in it. 
00579     For AVG/SUM(DISTINCT) we always use this tree (as it takes a single 
00580     argument) to get the distinct rows.
00581   */
00582   Unique *tree;
00583 
00584   /* 
00585     The length of the temp table row. Must be a member of the class as it
00586     gets passed down to simple_raw_key_cmp () as a compare function argument
00587     to Unique. simple_raw_key_cmp () is used as a fast comparison function 
00588     when the entire row can be binary compared.
00589   */  
00590   uint tree_key_length;
00591 
00592   enum Const_distinct{
00593     NOT_CONST= 0,
00601     CONST_NULL,
00608     CONST_NOT_NULL
00609   } const_distinct;
00610 
00619   bool use_distinct_values;
00620 
00621 public:
00622   Aggregator_distinct (Item_sum *sum) :
00623     Aggregator(sum), table(NULL), tmp_table_param(NULL), tree(NULL),
00624     const_distinct(NOT_CONST), use_distinct_values(false) {}
00625   virtual ~Aggregator_distinct ();
00626   Aggregator_type Aggrtype() { return DISTINCT_AGGREGATOR; }
00627 
00628   bool setup(THD *);
00629   void clear(); 
00630   bool add();
00631   void endup();
00632   virtual my_decimal *arg_val_decimal(my_decimal * value);
00633   virtual double arg_val_real();
00634   virtual bool arg_is_null(bool use_null_value);
00635 
00636   bool unique_walk_function(void *element);
00637   static int composite_key_cmp(void* arg, uchar* key1, uchar* key2);
00638 };
00639 
00640 
00646 class Aggregator_simple : public Aggregator
00647 {
00648 public:
00649 
00650   Aggregator_simple (Item_sum *sum) :
00651     Aggregator(sum) {}
00652   Aggregator_type Aggrtype() { return Aggregator::SIMPLE_AGGREGATOR; }
00653 
00654   bool setup(THD * thd) { return item_sum->setup(thd); }
00655   void clear() { item_sum->clear(); }
00656   bool add() { return item_sum->add(); }
00657   void endup() {};
00658   virtual my_decimal *arg_val_decimal(my_decimal * value);
00659   virtual double arg_val_real();
00660   virtual bool arg_is_null(bool use_null_value);
00661 };
00662 
00663 
00664 class Item_sum_num :public Item_sum
00665 {
00666 protected:
00667   /*
00668    val_xxx() functions may be called several times during the execution of a 
00669    query. Derived classes that require extensive calculation in val_xxx()
00670    maintain cache of aggregate value. This variable governs the validity of 
00671    that cache.
00672   */
00673   bool is_evaluated;
00674 public:
00675   Item_sum_num() :Item_sum(),is_evaluated(FALSE) {}
00676   Item_sum_num(Item *item_par) 
00677     :Item_sum(item_par), is_evaluated(FALSE) {}
00678   Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(FALSE) {}
00679   Item_sum_num(List<Item> &list) 
00680     :Item_sum(list), is_evaluated(FALSE) {}
00681   Item_sum_num(THD *thd, Item_sum_num *item) 
00682     :Item_sum(thd, item),is_evaluated(item->is_evaluated) {}
00683   bool fix_fields(THD *, Item **);
00684   longlong val_int()
00685   {
00686     DBUG_ASSERT(fixed == 1);
00687     return (longlong) rint(val_real());             /* Real as default */
00688   }
00689   String *val_str(String*str);
00690   my_decimal *val_decimal(my_decimal *);
00691   bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
00692   {
00693     return get_date_from_numeric(ltime, fuzzydate); /* Decimal or real */
00694   }
00695   bool get_time(MYSQL_TIME *ltime)
00696   {
00697     return get_time_from_numeric(ltime); /* Decimal or real */
00698   }
00699   void reset_field();
00700 };
00701 
00702 
00703 class Item_sum_int :public Item_sum_num
00704 {
00705 public:
00706   Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
00707   Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
00708   Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {}
00709   double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
00710   String *val_str(String*str);
00711   my_decimal *val_decimal(my_decimal *);
00712   bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
00713   {
00714     return get_date_from_int(ltime, fuzzydate);
00715   }
00716   bool get_time(MYSQL_TIME *ltime)
00717   {
00718     return get_time_from_int(ltime);
00719   }
00720   enum Item_result result_type () const { return INT_RESULT; }
00721   void fix_length_and_dec()
00722   { decimals=0; max_length=21; maybe_null=null_value=0; }
00723 };
00724 
00725 
00726 class Item_sum_sum :public Item_sum_num
00727 {
00728 protected:
00729   Item_result hybrid_type;
00730   double sum;
00731   my_decimal dec_buffs[2];
00732   uint curr_dec_buff;
00733   void fix_length_and_dec();
00734 
00735 public:
00736   Item_sum_sum(Item *item_par, bool distinct) :Item_sum_num(item_par) 
00737   {
00738     set_distinct(distinct);
00739   }
00740   Item_sum_sum(THD *thd, Item_sum_sum *item);
00741   enum Sumfunctype sum_func () const 
00742   { 
00743     return has_with_distinct() ? SUM_DISTINCT_FUNC : SUM_FUNC; 
00744   }
00745   void clear();
00746   bool add();
00747   double val_real();
00748   longlong val_int();
00749   String *val_str(String*str);
00750   my_decimal *val_decimal(my_decimal *);
00751   enum Item_result result_type () const { return hybrid_type; }
00752   void reset_field();
00753   void update_field();
00754   void no_rows_in_result() {}
00755   const char *func_name() const 
00756   { 
00757     return has_with_distinct() ? "sum(distinct " : "sum("; 
00758   }
00759   Item *copy_or_same(THD* thd);
00760 };
00761 
00762 
00763 class Item_sum_count :public Item_sum_int
00764 {
00765   longlong count;
00766 
00767   friend class Aggregator_distinct;
00768 
00769   void clear();
00770   bool add();
00771   void cleanup();
00772 
00773   public:
00774   Item_sum_count(Item *item_par)
00775     :Item_sum_int(item_par),count(0)
00776   {}
00777 
00786   Item_sum_count(List<Item> &list)
00787     :Item_sum_int(list),count(0)
00788   {
00789     set_distinct(TRUE);
00790   }
00791   Item_sum_count(THD *thd, Item_sum_count *item)
00792     :Item_sum_int(thd, item), count(item->count)
00793   {}
00794   enum Sumfunctype sum_func () const 
00795   { 
00796     return has_with_distinct() ? COUNT_DISTINCT_FUNC : COUNT_FUNC; 
00797   }
00798   void no_rows_in_result() { count=0; }
00799   void make_const(longlong count_arg) 
00800   { 
00801     count=count_arg;
00802     Item_sum::make_const();
00803   }
00804   longlong val_int();
00805   void reset_field();
00806   void update_field();
00807   const char *func_name() const 
00808   { 
00809     return has_with_distinct() ? "count(distinct " : "count(";
00810   }
00811   Item *copy_or_same(THD* thd);
00812 };
00813 
00814 
00815 /* Item to get the value of a stored sum function */
00816 
00817 class Item_sum_avg;
00818 
00824 class Item_sum_num_field: public Item_result_field
00825 {
00826 protected:
00827   Field *field;
00828   Item_result hybrid_type;
00829 public:
00830   longlong val_int()
00831   {
00832     /* can't be fix_fields()ed */
00833     return (longlong) rint(val_real());
00834   }
00835   bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
00836   {
00837     return get_date_from_numeric(ltime, fuzzydate); /* Decimal or real */
00838   }
00839   bool get_time(MYSQL_TIME *ltime)
00840   {
00841     return get_time_from_numeric(ltime); /* Decimal or real */
00842   }
00843   enum_field_types field_type() const
00844   {
00845     return hybrid_type == DECIMAL_RESULT ?
00846       MYSQL_TYPE_NEWDECIMAL : MYSQL_TYPE_DOUBLE;
00847   }
00848   enum Item_result result_type () const { return hybrid_type; }
00849   bool is_null() { update_null_value(); return null_value; }
00850 };
00851 
00852 
00853 class Item_avg_field :public Item_sum_num_field
00854 {
00855 public:
00856   uint f_precision, f_scale, dec_bin_size;
00857   uint prec_increment;
00858   Item_avg_field(Item_result res_type, Item_sum_avg *item);
00859   enum Type type() const { return FIELD_AVG_ITEM; }
00860   double val_real();
00861   my_decimal *val_decimal(my_decimal *);
00862   String *val_str(String*);
00863   void fix_length_and_dec() {}
00864   const char *func_name() const { DBUG_ASSERT(0); return "avg_field"; }
00865 };
00866 
00867 
00868 class Item_sum_avg :public Item_sum_sum
00869 {
00870 public:
00871   ulonglong count;
00872   uint prec_increment;
00873   uint f_precision, f_scale, dec_bin_size;
00874   Item_sum_avg(Item *item_par, bool distinct) 
00875     :Item_sum_sum(item_par, distinct), count(0) 
00876   {}
00877   Item_sum_avg(THD *thd, Item_sum_avg *item)
00878     :Item_sum_sum(thd, item), count(item->count),
00879     prec_increment(item->prec_increment) {}
00880 
00881   void fix_length_and_dec();
00882   enum Sumfunctype sum_func () const 
00883   {
00884     return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC;
00885   }
00886   void clear();
00887   bool add();
00888   double val_real();
00889   // In SPs we might force the "wrong" type with select into a declare variable
00890   longlong val_int() { return (longlong) rint(val_real()); }
00891   my_decimal *val_decimal(my_decimal *);
00892   String *val_str(String *str);
00893   void reset_field();
00894   void update_field();
00895   Item *result_item(Field *field)
00896   { return new Item_avg_field(hybrid_type, this); }
00897   void no_rows_in_result() {}
00898   const char *func_name() const 
00899   { 
00900     return has_with_distinct() ? "avg(distinct " : "avg("; 
00901   }
00902   Item *copy_or_same(THD* thd);
00903   Field *create_tmp_field(bool group, TABLE *table);
00904   void cleanup()
00905   {
00906     count= 0;
00907     Item_sum_sum::cleanup();
00908   }
00909 };
00910 
00911 class Item_sum_variance;
00912 
00913 class Item_variance_field :public Item_sum_num_field
00914 {
00915 protected:
00916   uint f_precision0, f_scale0;
00917   uint f_precision1, f_scale1;
00918   uint dec_bin_size0, dec_bin_size1;
00919   uint sample;
00920   uint prec_increment;
00921 public:
00922   Item_variance_field(Item_sum_variance *item);
00923   enum Type type() const {return FIELD_VARIANCE_ITEM; }
00924   double val_real();
00925   String *val_str(String *str)
00926   { return val_string_from_real(str); }
00927   my_decimal *val_decimal(my_decimal *dec_buf)
00928   { return val_decimal_from_real(dec_buf); }
00929   void fix_length_and_dec() {}
00930   const char *func_name() const { DBUG_ASSERT(0); return "variance_field"; }
00931 };
00932 
00933 
00934 /*
00935   variance(a) =
00936 
00937   =  sum (ai - avg(a))^2 / count(a) )
00938   =  sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a)
00939   =  (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) = 
00940   =  (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) = 
00941   =  (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) = 
00942   =  (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) = 
00943   =  (sum(ai^2) - sum(a)^2/count(a))/count(a)
00944 
00945 But, this falls prey to catastrophic cancellation.  Instead, use the recurrence formulas
00946 
00947   M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline 
00948   S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline
00949   for 2 <= k <= n newline
00950   ital variance = S_{n} / (n-1)
00951 
00952 */
00953 
00954 class Item_sum_variance : public Item_sum_num
00955 {
00956   void fix_length_and_dec();
00957 
00958 public:
00959   Item_result hybrid_type;
00960   int cur_dec;
00961   double recurrence_m, recurrence_s;    /* Used in recurrence relation. */
00962   ulonglong count;
00963   uint f_precision0, f_scale0;
00964   uint f_precision1, f_scale1;
00965   uint dec_bin_size0, dec_bin_size1;
00966   uint sample;
00967   uint prec_increment;
00968 
00969   Item_sum_variance(Item *item_par, uint sample_arg) :Item_sum_num(item_par),
00970     hybrid_type(REAL_RESULT), count(0), sample(sample_arg)
00971     {}
00972   Item_sum_variance(THD *thd, Item_sum_variance *item);
00973   enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
00974   void clear();
00975   bool add();
00976   double val_real();
00977   my_decimal *val_decimal(my_decimal *);
00978   void reset_field();
00979   void update_field();
00980   Item *result_item(Field *field)
00981   { return new Item_variance_field(this); }
00982   void no_rows_in_result() {}
00983   const char *func_name() const
00984     { return sample ? "var_samp(" : "variance("; }
00985   Item *copy_or_same(THD* thd);
00986   Field *create_tmp_field(bool group, TABLE *table);
00987   enum Item_result result_type () const { return REAL_RESULT; }
00988   void cleanup()
00989   {
00990     count= 0;
00991     Item_sum_num::cleanup();
00992   }
00993 };
00994 
00995 class Item_sum_std;
00996 
00997 class Item_std_field :public Item_variance_field
00998 {
00999 public:
01000   Item_std_field(Item_sum_std *item);
01001   enum Type type() const { return FIELD_STD_ITEM; }
01002   double val_real();
01003   my_decimal *val_decimal(my_decimal *);
01004   enum Item_result result_type () const { return REAL_RESULT; }
01005   enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
01006   const char *func_name() const { DBUG_ASSERT(0); return "std_field"; }
01007 };
01008 
01009 /*
01010    standard_deviation(a) = sqrt(variance(a))
01011 */
01012 
01013 class Item_sum_std :public Item_sum_variance
01014 {
01015   public:
01016   Item_sum_std(Item *item_par, uint sample_arg)
01017     :Item_sum_variance(item_par, sample_arg) {}
01018   Item_sum_std(THD *thd, Item_sum_std *item)
01019     :Item_sum_variance(thd, item)
01020     {}
01021   enum Sumfunctype sum_func () const { return STD_FUNC; }
01022   double val_real();
01023   Item *result_item(Field *field)
01024     { return new Item_std_field(this); }
01025   const char *func_name() const { return "std("; }
01026   Item *copy_or_same(THD* thd);
01027   enum Item_result result_type () const { return REAL_RESULT; }
01028   enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
01029 };
01030 
01031 // This class is a string or number function depending on num_func
01032 class Arg_comparator;
01033 class Item_cache;
01034 class Item_sum_hybrid :public Item_sum
01035 {
01036 protected:
01037   Item_cache *value, *arg_cache;
01038   Arg_comparator *cmp;
01039   Item_result hybrid_type;
01040   enum_field_types hybrid_field_type;
01041   int cmp_sign;
01042   bool was_values;  // Set if we have found at least one row (for max/min only)
01043 
01044   public:
01045   Item_sum_hybrid(Item *item_par,int sign)
01046     :Item_sum(item_par), value(0), arg_cache(0), cmp(0),
01047     hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG),
01048     cmp_sign(sign), was_values(TRUE)
01049   { collation.set(&my_charset_bin); }
01050   Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
01051     :Item_sum(thd, item), value(item->value), arg_cache(0),
01052     hybrid_type(item->hybrid_type), hybrid_field_type(item->hybrid_field_type),
01053     cmp_sign(item->cmp_sign), was_values(item->was_values)
01054   { }
01055   bool fix_fields(THD *, Item **);
01056   void setup_hybrid(Item *item, Item *value_arg);
01057   void clear();
01058   double val_real();
01059   longlong val_int();
01060   longlong val_time_temporal();
01061   longlong val_date_temporal();
01062   my_decimal *val_decimal(my_decimal *);
01063   bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
01064   bool get_time(MYSQL_TIME *ltime);
01065   void reset_field();
01066   String *val_str(String *);
01067   bool keep_field_type(void) const { return 1; }
01068   enum Item_result result_type () const { return hybrid_type; }
01069   enum enum_field_types field_type() const { return hybrid_field_type; }
01070   void update_field();
01071   void min_max_update_str_field();
01072   void min_max_update_temporal_field();
01073   void min_max_update_real_field();
01074   void min_max_update_int_field();
01075   void min_max_update_decimal_field();
01076   void cleanup();
01077   bool any_value() { return was_values; }
01078   void no_rows_in_result();
01079   Field *create_tmp_field(bool group, TABLE *table);
01080 };
01081 
01082 
01083 class Item_sum_min :public Item_sum_hybrid
01084 {
01085 public:
01086   Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
01087   Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {}
01088   enum Sumfunctype sum_func () const {return MIN_FUNC;}
01089 
01090   bool add();
01091   const char *func_name() const { return "min("; }
01092   Item *copy_or_same(THD* thd);
01093 };
01094 
01095 
01096 class Item_sum_max :public Item_sum_hybrid
01097 {
01098 public:
01099   Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
01100   Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {}
01101   enum Sumfunctype sum_func () const {return MAX_FUNC;}
01102 
01103   bool add();
01104   const char *func_name() const { return "max("; }
01105   Item *copy_or_same(THD* thd);
01106 };
01107 
01108 
01109 class Item_sum_bit :public Item_sum_int
01110 {
01111 protected:
01112   ulonglong reset_bits,bits;
01113 
01114 public:
01115   Item_sum_bit(Item *item_par,ulonglong reset_arg)
01116     :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
01117   Item_sum_bit(THD *thd, Item_sum_bit *item):
01118     Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits) {}
01119   enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
01120   void clear();
01121   longlong val_int();
01122   void reset_field();
01123   void update_field();
01124   void fix_length_and_dec()
01125   { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
01126   void cleanup()
01127   {
01128     bits= reset_bits;
01129     Item_sum_int::cleanup();
01130   }
01131 };
01132 
01133 
01134 class Item_sum_or :public Item_sum_bit
01135 {
01136 public:
01137   Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
01138   Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {}
01139   bool add();
01140   const char *func_name() const { return "bit_or("; }
01141   Item *copy_or_same(THD* thd);
01142 };
01143 
01144 
01145 class Item_sum_and :public Item_sum_bit
01146 {
01147   public:
01148   Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {}
01149   Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {}
01150   bool add();
01151   const char *func_name() const { return "bit_and("; }
01152   Item *copy_or_same(THD* thd);
01153 };
01154 
01155 class Item_sum_xor :public Item_sum_bit
01156 {
01157   public:
01158   Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
01159   Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {}
01160   bool add();
01161   const char *func_name() const { return "bit_xor("; }
01162   Item *copy_or_same(THD* thd);
01163 };
01164 
01165 
01166 /*
01167   User defined aggregates
01168 */
01169 
01170 #ifdef HAVE_DLOPEN
01171 
01172 class Item_udf_sum : public Item_sum
01173 {
01174 protected:
01175   udf_handler udf;
01176 
01177 public:
01178   Item_udf_sum(udf_func *udf_arg)
01179     :Item_sum(), udf(udf_arg)
01180   { quick_group=0; }
01181   Item_udf_sum(udf_func *udf_arg, List<Item> &list)
01182     :Item_sum(list), udf(udf_arg)
01183   { quick_group=0;}
01184   Item_udf_sum(THD *thd, Item_udf_sum *item)
01185     :Item_sum(thd, item), udf(item->udf)
01186   { udf.not_original= TRUE; }
01187   const char *func_name() const { return udf.name(); }
01188   bool fix_fields(THD *thd, Item **ref)
01189   {
01190     DBUG_ASSERT(fixed == 0);
01191 
01192     if (init_sum_func_check(thd))
01193       return TRUE;
01194 
01195     fixed= 1;
01196     if (udf.fix_fields(thd, this, this->arg_count, this->args))
01197       return TRUE;
01198 
01199     memcpy (orig_args, args, sizeof (Item *) * arg_count);
01200     return check_sum_func(thd, ref);
01201   }
01202   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
01203   virtual bool have_field_update(void) const { return 0; }
01204 
01205   void clear();
01206   bool add();
01207   void reset_field() {};
01208   void update_field() {};
01209   void cleanup();
01210   virtual void print(String *str, enum_query_type query_type);
01211 };
01212 
01213 
01214 class Item_sum_udf_float :public Item_udf_sum
01215 {
01216  public:
01217   Item_sum_udf_float(udf_func *udf_arg)
01218     :Item_udf_sum(udf_arg) {}
01219   Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
01220     :Item_udf_sum(udf_arg, list) {}
01221   Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
01222     :Item_udf_sum(thd, item) {}
01223   longlong val_int()
01224   {
01225     DBUG_ASSERT(fixed == 1);
01226     return (longlong) rint(Item_sum_udf_float::val_real());
01227   }
01228   double val_real();
01229   String *val_str(String*str);
01230   my_decimal *val_decimal(my_decimal *);
01231   bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
01232   {
01233     return get_date_from_real(ltime, fuzzydate);
01234   }
01235   bool get_time(MYSQL_TIME *ltime)
01236   {
01237     return get_time_from_real(ltime);
01238   }
01239   void fix_length_and_dec() { fix_num_length_and_dec(); }
01240   Item *copy_or_same(THD* thd);
01241 };
01242 
01243 
01244 class Item_sum_udf_int :public Item_udf_sum
01245 {
01246 public:
01247   Item_sum_udf_int(udf_func *udf_arg)
01248     :Item_udf_sum(udf_arg) {}
01249   Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
01250     :Item_udf_sum(udf_arg, list) {}
01251   Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
01252     :Item_udf_sum(thd, item) {}
01253   longlong val_int();
01254   double val_real()
01255     { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); }
01256   String *val_str(String*str);
01257   my_decimal *val_decimal(my_decimal *);
01258   bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
01259   {
01260     return get_date_from_int(ltime, fuzzydate);
01261   }
01262   bool get_time(MYSQL_TIME *ltime)
01263   {
01264     return get_time_from_int(ltime);
01265   }
01266   enum Item_result result_type () const { return INT_RESULT; }
01267   void fix_length_and_dec() { decimals=0; max_length=21; }
01268   Item *copy_or_same(THD* thd);
01269 };
01270 
01271 
01272 class Item_sum_udf_str :public Item_udf_sum
01273 {
01274 public:
01275   Item_sum_udf_str(udf_func *udf_arg)
01276     :Item_udf_sum(udf_arg) {}
01277   Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
01278     :Item_udf_sum(udf_arg,list) {}
01279   Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
01280     :Item_udf_sum(thd, item) {}
01281   String *val_str(String *);
01282   double val_real()
01283   {
01284     int err_not_used;
01285     char *end_not_used;
01286     String *res;
01287     res=val_str(&str_value);
01288     return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
01289                             &end_not_used, &err_not_used) : 0.0;
01290   }
01291   longlong val_int()
01292   {
01293     int err_not_used;
01294     char *end;
01295     String *res;
01296     const CHARSET_INFO *cs;
01297 
01298     if (!(res= val_str(&str_value)))
01299       return 0;                                 /* Null value */
01300     cs= res->charset();
01301     end= (char*) res->ptr()+res->length();
01302     return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used);
01303   }
01304   my_decimal *val_decimal(my_decimal *dec);
01305   bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
01306   {
01307     return get_date_from_string(ltime, fuzzydate);
01308   }
01309   bool get_time(MYSQL_TIME *ltime)
01310   {
01311     return get_time_from_string(ltime);
01312   }
01313   enum Item_result result_type () const { return STRING_RESULT; }
01314   void fix_length_and_dec();
01315   Item *copy_or_same(THD* thd);
01316 };
01317 
01318 
01319 class Item_sum_udf_decimal :public Item_udf_sum
01320 {
01321 public:
01322   Item_sum_udf_decimal(udf_func *udf_arg)
01323     :Item_udf_sum(udf_arg) {}
01324   Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
01325     :Item_udf_sum(udf_arg, list) {}
01326   Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item)
01327     :Item_udf_sum(thd, item) {}
01328   String *val_str(String *);
01329   double val_real();
01330   longlong val_int();
01331   my_decimal *val_decimal(my_decimal *);
01332   bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
01333   {
01334     return get_date_from_decimal(ltime, fuzzydate);
01335   }
01336   bool get_time(MYSQL_TIME *ltime)
01337   {
01338     return get_time_from_decimal(ltime);
01339   }
01340   enum Item_result result_type () const { return DECIMAL_RESULT; }
01341   void fix_length_and_dec() { fix_num_length_and_dec(); }
01342   Item *copy_or_same(THD* thd);
01343 };
01344 
01345 #else /* Dummy functions to get sql_yacc.cc compiled */
01346 
01347 class Item_sum_udf_float :public Item_sum_num
01348 {
01349  public:
01350   Item_sum_udf_float(udf_func *udf_arg)
01351     :Item_sum_num() {}
01352   Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
01353   Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
01354     :Item_sum_num(thd, item) {}
01355   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
01356   double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
01357   void clear() {}
01358   bool add() { return 0; }  
01359   void update_field() {}
01360 };
01361 
01362 
01363 class Item_sum_udf_int :public Item_sum_num
01364 {
01365 public:
01366   Item_sum_udf_int(udf_func *udf_arg)
01367     :Item_sum_num() {}
01368   Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
01369   Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
01370     :Item_sum_num(thd, item) {}
01371   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
01372   longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; }
01373   double val_real() { DBUG_ASSERT(fixed == 1); return 0; }
01374   void clear() {}
01375   bool add() { return 0; }  
01376   void update_field() {}
01377 };
01378 
01379 
01380 class Item_sum_udf_decimal :public Item_sum_num
01381 {
01382  public:
01383   Item_sum_udf_decimal(udf_func *udf_arg)
01384     :Item_sum_num() {}
01385   Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
01386     :Item_sum_num() {}
01387   Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item)
01388     :Item_sum_num(thd, item) {}
01389   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
01390   double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
01391   my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; }
01392   void clear() {}
01393   bool add() { return 0; }
01394   void update_field() {}
01395 };
01396 
01397 
01398 class Item_sum_udf_str :public Item_sum_num
01399 {
01400 public:
01401   Item_sum_udf_str(udf_func *udf_arg)
01402     :Item_sum_num() {}
01403   Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
01404     :Item_sum_num() {}
01405   Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
01406     :Item_sum_num(thd, item) {}
01407   String *val_str(String *)
01408     { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
01409   double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; }
01410   longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
01411   enum Item_result result_type () const { return STRING_RESULT; }
01412   void fix_length_and_dec() { maybe_null=1; max_length=0; }
01413   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
01414   void clear() {}
01415   bool add() { return 0; }  
01416   void update_field() {}
01417 };
01418 
01419 #endif /* HAVE_DLOPEN */
01420 
01421 C_MODE_START
01422 int group_concat_key_cmp_with_distinct(const void* arg, const void* key1,
01423                                        const void* key2);
01424 int group_concat_key_cmp_with_order(const void* arg, const void* key1,
01425                                     const void* key2);
01426 int dump_leaf_key(void* key_arg,
01427                   element_count count __attribute__((unused)),
01428                   void* item_arg);
01429 C_MODE_END
01430 
01431 class Item_func_group_concat : public Item_sum
01432 {
01433   TMP_TABLE_PARAM *tmp_table_param;
01434   String result;
01435   String *separator;
01436   TREE tree_base;
01437   TREE *tree;
01438 
01446   Unique *unique_filter;
01447   TABLE *table;
01448   ORDER **order;
01449   Name_resolution_context *context;
01451   uint arg_count_order;
01453   uint arg_count_field;
01454   uint row_count;
01455   bool distinct;
01456   bool warning_for_row;
01457   bool always_null;
01458   bool force_copy_fields;
01459   bool no_appended;
01460   /*
01461     Following is 0 normal object and pointer to original one for copy
01462     (to correctly free resources)
01463   */
01464   Item_func_group_concat *original;
01465 
01466   friend int group_concat_key_cmp_with_distinct(const void* arg,
01467                                                 const void* key1,
01468                                                 const void* key2);
01469   friend int group_concat_key_cmp_with_order(const void* arg,
01470                                              const void* key1,
01471                                              const void* key2);
01472   friend int dump_leaf_key(void* key_arg,
01473                            element_count count __attribute__((unused)),
01474                            void* item_arg);
01475 
01476 public:
01477   Item_func_group_concat(Name_resolution_context *context_arg,
01478                          bool is_distinct, List<Item> *is_select,
01479                          const SQL_I_List<ORDER> &is_order, String *is_separator);
01480 
01481   Item_func_group_concat(THD *thd, Item_func_group_concat *item);
01482   ~Item_func_group_concat();
01483   void cleanup();
01484 
01485   enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
01486   const char *func_name() const { return "group_concat"; }
01487   virtual Item_result result_type () const { return STRING_RESULT; }
01488   virtual Field *make_string_field(TABLE *table);
01489   enum_field_types field_type() const
01490   {
01491     if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB )
01492       return MYSQL_TYPE_BLOB;
01493     else
01494       return MYSQL_TYPE_VARCHAR;
01495   }
01496   void clear();
01497   bool add();
01498   void reset_field() { DBUG_ASSERT(0); }        // not used
01499   void update_field() { DBUG_ASSERT(0); }       // not used
01500   bool fix_fields(THD *,Item **);
01501   bool setup(THD *thd);
01502   void make_unique();
01503   double val_real()
01504   {
01505     String *res;  res=val_str(&str_value);
01506     return res ? my_atof(res->c_ptr()) : 0.0;
01507   }
01508   longlong val_int()
01509   {
01510     String *res;
01511     char *end_ptr;
01512     int error;
01513     if (!(res= val_str(&str_value)))
01514       return (longlong) 0;
01515     end_ptr= (char*) res->ptr()+ res->length();
01516     return my_strtoll10(res->ptr(), &end_ptr, &error);
01517   }
01518   my_decimal *val_decimal(my_decimal *decimal_value)
01519   {
01520     return val_decimal_from_string(decimal_value);
01521   }
01522   bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
01523   {
01524     return get_date_from_string(ltime, fuzzydate);
01525   }
01526   bool get_time(MYSQL_TIME *ltime)
01527   {
01528     return get_time_from_string(ltime);
01529   }
01530   String* val_str(String* str);
01531   Item *copy_or_same(THD* thd);
01532   void no_rows_in_result() {}
01533   virtual void print(String *str, enum_query_type query_type);
01534   virtual bool change_context_processor(uchar *cntx)
01535     { context= (Name_resolution_context *)cntx; return FALSE; }
01536 };
01537 
01538 #endif /* ITEM_SUM_INCLUDED */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines