MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
item_sum.h
1 #ifndef ITEM_SUM_INCLUDED
2 #define ITEM_SUM_INCLUDED
3 
4 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights
5  reserved.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; version 2 of the License.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
19 
20 
21 /* classes for sum functions */
22 
23 #include <my_tree.h>
24 #include "sql_udf.h" /* udf_handler */
25 
26 class Item_sum;
28 class Aggregator_simple;
29 
42 class Aggregator : public Sql_alloc
43 {
44  friend class Item_sum;
45  friend class Item_sum_sum;
46  friend class Item_sum_count;
47  friend class Item_sum_avg;
48 
49  /*
50  All members are protected as this class is not usable outside of an
51  Item_sum descendant.
52  */
53 protected:
54  /* the aggregate function class to act on */
55  Item_sum *item_sum;
56 
67 
68 public:
69  Aggregator (Item_sum *arg): item_sum(arg), use_distinct_values(FALSE) {}
70  virtual ~Aggregator () {} /* Keep gcc happy */
71 
72  enum Aggregator_type { SIMPLE_AGGREGATOR, DISTINCT_AGGREGATOR };
73  virtual Aggregator_type Aggrtype() = 0;
74 
80  virtual bool setup(THD *) = 0;
81 
87  virtual void clear() = 0;
88 
93  virtual bool add() = 0;
94 
99  virtual void endup() = 0;
100 
102  virtual my_decimal *arg_val_decimal(my_decimal * value) = 0;
104  virtual double arg_val_real() = 0;
109  virtual bool arg_is_null() = 0;
110 };
111 
112 
113 class st_select_lex;
114 
311 {
312  friend class Aggregator_distinct;
313  friend class Aggregator_simple;
314 
315 protected:
321 
322 private:
329  bool force_copy_fields;
330 
336  bool with_distinct;
337 
338 public:
339 
340  bool has_force_copy_fields() const { return force_copy_fields; }
341  bool has_with_distinct() const { return with_distinct; }
342 
343  enum Sumfunctype
344  { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC,
345  AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC,
346  VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC
347  };
348 
349  Item **ref_by; /* pointer to a ref to the object used to register it */
350  Item_sum *next; /* next in the circular chain of registered objects */
351  Item_sum *in_sum_func; /* embedding set function if any */
352  st_select_lex * aggr_sel; /* select where the function is aggregated */
353  int8 nest_level; /* number of the nesting level of the set function */
354  int8 aggr_level; /* nesting level of the aggregating subquery */
355  int8 max_arg_level; /* max level of unbound column references */
356  int8 max_sum_func_level;/* max level of aggregation for embedded functions */
357  bool quick_group; /* If incremental update of fields */
358  /*
359  This list is used by the check for mixing non aggregated fields and
360  sum functions in the ONLY_FULL_GROUP_BY_MODE. We save all outer fields
361  directly or indirectly used under this function it as it's unclear
362  at the moment of fixing outer field whether it's aggregated or not.
363  */
364  List<Item_field> outer_fields;
365 
366 protected:
367  uint arg_count;
368  Item **args, *tmp_args[2];
369  /*
370  Copy of the arguments list to hold the original set of arguments.
371  Used in EXPLAIN EXTENDED instead of the current argument list because
372  the current argument list can be altered by usage of temporary tables.
373  */
374  Item **orig_args, *tmp_orig_args[2];
375  table_map used_tables_cache;
376  bool forced_const;
377  static ulonglong ram_limitation(THD *thd);
378 
379 public:
380 
381  void mark_as_sum_func();
382  Item_sum() :next(NULL), quick_group(1), arg_count(0), forced_const(FALSE)
383  {
384  mark_as_sum_func();
385  init_aggregator();
386  }
387  Item_sum(Item *a) :next(NULL), quick_group(1), arg_count(1), args(tmp_args),
388  orig_args(tmp_orig_args), forced_const(FALSE)
389  {
390  args[0]=a;
391  mark_as_sum_func();
392  init_aggregator();
393  }
394  Item_sum( Item *a, Item *b ) :next(NULL), quick_group(1), arg_count(2), args(tmp_args),
395  orig_args(tmp_orig_args), forced_const(FALSE)
396  {
397  args[0]=a; args[1]=b;
398  mark_as_sum_func();
399  init_aggregator();
400  }
401  Item_sum(List<Item> &list);
402  //Copy constructor, need to perform subselects with temporary tables
403  Item_sum(THD *thd, Item_sum *item);
404  enum Type type() const { return SUM_FUNC_ITEM; }
405  virtual enum Sumfunctype sum_func () const=0;
410  inline bool reset_and_add()
411  {
412  aggregator_clear();
413  return aggregator_add();
414  };
415 
416  /*
417  Called when new group is started and results are being saved in
418  a temporary table. Similarly to reset_and_add() it resets the
419  value to its default and aggregates the value of its
420  attribute(s), but must also store it in result_field.
421  This set of methods (result_item(), reset_field, update_field()) of
422  Item_sum is used only if quick_group is not null. Otherwise
423  copy_or_same() is used to obtain a copy of this item.
424  */
425  virtual void reset_field()=0;
426  /*
427  Called for each new value in the group, when temporary table is in use.
428  Similar to add(), but uses temporary table field to obtain current value,
429  Updated value is then saved in the field.
430  */
431  virtual void update_field()=0;
432  virtual bool keep_field_type(void) const { return 0; }
433  virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
434  virtual Item *result_item(Field *field)
435  { return new Item_field(field); }
436  table_map used_tables() const { return used_tables_cache; }
437  void update_used_tables ();
438  bool is_null() { return null_value; }
439  void make_const ()
440  {
441  used_tables_cache= 0;
442  forced_const= TRUE;
443  }
444  virtual bool const_item() const { return forced_const; }
445  virtual bool const_during_execution() const { return false; }
446  virtual void print(String *str, enum_query_type query_type);
447  void fix_num_length_and_dec();
448 
459  virtual void no_rows_in_result()
460  {
461  set_aggregator(with_distinct ?
462  Aggregator::DISTINCT_AGGREGATOR :
463  Aggregator::SIMPLE_AGGREGATOR);
465  }
466  virtual void make_unique() { force_copy_fields= TRUE; }
467  Item *get_tmp_table_item(THD *thd);
468  virtual Field *create_tmp_field(bool group, TABLE *table);
469  bool walk(Item_processor processor, bool walk_subquery, uchar *argument);
470  virtual bool clean_up_after_removal(uchar *arg);
471  bool init_sum_func_check(THD *thd);
472  bool check_sum_func(THD *thd, Item **ref);
473  bool register_sum_func(THD *thd, Item **ref);
474  st_select_lex *depended_from()
475  { return (nest_level == aggr_level ? 0 : aggr_sel); }
476 
477  Item *get_arg(uint i) { return args[i]; }
478  Item *set_arg(uint i, THD *thd, Item *new_val);
479  uint get_arg_count() { return arg_count; }
480 
481  /* Initialization of distinct related members */
482  void init_aggregator()
483  {
484  aggr= NULL;
485  with_distinct= FALSE;
486  force_copy_fields= FALSE;
487  }
488 
493  inline bool aggregator_setup(THD *thd) { return aggr->setup(thd); };
494 
499  inline void aggregator_clear() { aggr->clear(); }
500 
505  inline bool aggregator_add() { return aggr->add(); };
506 
507  /* stores the declared DISTINCT flag (from the parser) */
508  void set_distinct(bool distinct)
509  {
510  with_distinct= distinct;
511  quick_group= with_distinct ? 0 : 1;
512  }
513 
514  /*
515  Set the type of aggregation : DISTINCT or not.
516 
517  May be called multiple times.
518  */
519 
520  int set_aggregator(Aggregator::Aggregator_type aggregator);
521 
522  virtual void clear()= 0;
523  virtual bool add()= 0;
524  virtual bool setup(THD *thd) { return false; }
525 
526  virtual void cleanup();
527 };
528 
529 
530 class Unique;
531 
532 
542 {
543  friend class Item_sum_sum;
544 
545  /*
546  flag to prevent consecutive runs of endup(). Normally in endup there are
547  expensive calculations (like walking the distinct tree for example)
548  which we must do only once if there are no data changes.
549  We can re-use the data for the second and subsequent val_xxx() calls.
550  endup_done set to TRUE also means that the calculated values for
551  the aggregate functions are correct and don't need recalculation.
552  */
553  bool endup_done;
554 
555  /*
556  Used depending on the type of the aggregate function and the presence of
557  blob columns in it:
558  - For COUNT(DISTINCT) and no blob fields this points to a real temporary
559  table. It's used as a hash table.
560  - For AVG/SUM(DISTINCT) or COUNT(DISTINCT) with blob fields only the
561  in-memory data structure of a temporary table is constructed.
562  It's used by the Field classes to transform data into row format.
563  */
564  TABLE *table;
565 
566  /*
567  An array of field lengths on row allocated and used only for
568  COUNT(DISTINCT) with multiple columns and no blobs. Used in
569  Aggregator_distinct::composite_key_cmp (called from Unique to compare
570  nodes
571  */
572  uint32 *field_lengths;
573 
574  /*
575  Used in conjunction with 'table' to support the access to Field classes
576  for COUNT(DISTINCT). Needed by copy_fields()/copy_funcs().
577  */
578  TMP_TABLE_PARAM *tmp_table_param;
579 
580  /*
581  If there are no blobs in the COUNT(DISTINCT) arguments, we can use a tree,
582  which is faster than heap table. In that case, we still use the table
583  to help get things set up, but we insert nothing in it.
584  For AVG/SUM(DISTINCT) we always use this tree (as it takes a single
585  argument) to get the distinct rows.
586  */
587  Unique *tree;
588 
589  /*
590  The length of the temp table row. Must be a member of the class as it
591  gets passed down to simple_raw_key_cmp () as a compare function argument
592  to Unique. simple_raw_key_cmp () is used as a fast comparison function
593  when the entire row can be binary compared.
594  */
595  uint tree_key_length;
596 
597  /*
598  Set to true if the result is known to be always NULL.
599  If set deactivates creation and usage of the temporary table (in the
600  'table' member) and the Unique instance (in the 'tree' member) as well as
601  the calculation of the final value on the first call to
602  Item_[sum|avg|count]::val_xxx().
603  */
604  bool always_null;
605 
606 public:
608  Aggregator(sum), table(NULL), tmp_table_param(NULL), tree(NULL),
609  always_null(FALSE) {}
610  virtual ~Aggregator_distinct ();
611  Aggregator_type Aggrtype() { return DISTINCT_AGGREGATOR; }
612 
613  bool setup(THD *);
614  void clear();
615  bool add();
616  void endup();
617  virtual my_decimal *arg_val_decimal(my_decimal * value);
618  virtual double arg_val_real();
619  virtual bool arg_is_null();
620 
621  bool unique_walk_function(void *element);
622  static int composite_key_cmp(void* arg, uchar* key1, uchar* key2);
623 };
624 
625 
632 {
633 public:
634 
635  Aggregator_simple (Item_sum *sum) :
636  Aggregator(sum) {}
637  Aggregator_type Aggrtype() { return Aggregator::SIMPLE_AGGREGATOR; }
638 
639  bool setup(THD * thd) { return item_sum->setup(thd); }
640  void clear() { item_sum->clear(); }
641  bool add() { return item_sum->add(); }
642  void endup() {};
643  virtual my_decimal *arg_val_decimal(my_decimal * value);
644  virtual double arg_val_real();
645  virtual bool arg_is_null();
646 };
647 
648 
649 class Item_sum_num :public Item_sum
650 {
651 protected:
652  /*
653  val_xxx() functions may be called several times during the execution of a
654  query. Derived classes that require extensive calculation in val_xxx()
655  maintain cache of aggregate value. This variable governs the validity of
656  that cache.
657  */
658  bool is_evaluated;
659 public:
660  Item_sum_num() :Item_sum(),is_evaluated(FALSE) {}
661  Item_sum_num(Item *item_par)
662  :Item_sum(item_par), is_evaluated(FALSE) {}
663  Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(FALSE) {}
664  Item_sum_num(List<Item> &list)
665  :Item_sum(list), is_evaluated(FALSE) {}
666  Item_sum_num(THD *thd, Item_sum_num *item)
667  :Item_sum(thd, item),is_evaluated(item->is_evaluated) {}
668  bool fix_fields(THD *, Item **);
669  longlong val_int()
670  {
671  DBUG_ASSERT(fixed == 1);
672  return (longlong) rint(val_real()); /* Real as default */
673  }
674  String *val_str(String*str);
675  my_decimal *val_decimal(my_decimal *);
676  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
677  {
678  return get_date_from_numeric(ltime, fuzzydate); /* Decimal or real */
679  }
680  bool get_time(MYSQL_TIME *ltime)
681  {
682  return get_time_from_numeric(ltime); /* Decimal or real */
683  }
684  void reset_field();
685 };
686 
687 
689 {
690 public:
691  Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
692  Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
693  Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {}
694  double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
695  String *val_str(String*str);
696  my_decimal *val_decimal(my_decimal *);
697  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
698  {
699  return get_date_from_int(ltime, fuzzydate);
700  }
701  bool get_time(MYSQL_TIME *ltime)
702  {
703  return get_time_from_int(ltime);
704  }
705  enum Item_result result_type () const { return INT_RESULT; }
706  void fix_length_and_dec()
707  { decimals=0; max_length=21; maybe_null=null_value=0; }
708 };
709 
710 
712 {
713 protected:
714  Item_result hybrid_type;
715  double sum;
716  my_decimal dec_buffs[2];
717  uint curr_dec_buff;
718  void fix_length_and_dec();
719 
720 public:
721  Item_sum_sum(Item *item_par, bool distinct) :Item_sum_num(item_par)
722  {
723  set_distinct(distinct);
724  }
725  Item_sum_sum(THD *thd, Item_sum_sum *item);
726  enum Sumfunctype sum_func () const
727  {
728  return has_with_distinct() ? SUM_DISTINCT_FUNC : SUM_FUNC;
729  }
730  void clear();
731  bool add();
732  double val_real();
733  longlong val_int();
734  String *val_str(String*str);
735  my_decimal *val_decimal(my_decimal *);
736  enum Item_result result_type () const { return hybrid_type; }
737  void reset_field();
738  void update_field();
740  const char *func_name() const
741  {
742  return has_with_distinct() ? "sum(distinct " : "sum(";
743  }
744  Item *copy_or_same(THD* thd);
745 };
746 
747 
749 {
750  longlong count;
751 
752  friend class Aggregator_distinct;
753 
754  void clear();
755  bool add();
756  void cleanup();
757 
758  public:
759  Item_sum_count(Item *item_par)
760  :Item_sum_int(item_par),count(0)
761  {}
762 
772  :Item_sum_int(list),count(0)
773  {
774  set_distinct(TRUE);
775  }
776  Item_sum_count(THD *thd, Item_sum_count *item)
777  :Item_sum_int(thd, item), count(item->count)
778  {}
779  enum Sumfunctype sum_func () const
780  {
781  return has_with_distinct() ? COUNT_DISTINCT_FUNC : COUNT_FUNC;
782  }
783  void no_rows_in_result() { count=0; }
784  void make_const(longlong count_arg)
785  {
786  count=count_arg;
787  Item_sum::make_const();
788  }
789  longlong val_int();
790  void reset_field();
791  void update_field();
792  const char *func_name() const
793  {
794  return has_with_distinct() ? "count(distinct " : "count(";
795  }
796  Item *copy_or_same(THD* thd);
797 };
798 
799 
800 /* Item to get the value of a stored sum function */
801 
802 class Item_sum_avg;
803 
810 {
811 protected:
812  Field *field;
813  Item_result hybrid_type;
814 public:
815  longlong val_int()
816  {
817  /* can't be fix_fields()ed */
818  return (longlong) rint(val_real());
819  }
820  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
821  {
822  return get_date_from_numeric(ltime, fuzzydate); /* Decimal or real */
823  }
824  bool get_time(MYSQL_TIME *ltime)
825  {
826  return get_time_from_numeric(ltime); /* Decimal or real */
827  }
828  enum_field_types field_type() const
829  {
830  return hybrid_type == DECIMAL_RESULT ?
831  MYSQL_TYPE_NEWDECIMAL : MYSQL_TYPE_DOUBLE;
832  }
833  enum Item_result result_type () const { return hybrid_type; }
834  bool is_null() { update_null_value(); return null_value; }
835 };
836 
837 
839 {
840 public:
841  uint f_precision, f_scale, dec_bin_size;
842  uint prec_increment;
843  Item_avg_field(Item_result res_type, Item_sum_avg *item);
844  enum Type type() const { return FIELD_AVG_ITEM; }
845  double val_real();
846  my_decimal *val_decimal(my_decimal *);
847  String *val_str(String*);
848  void fix_length_and_dec() {}
849  const char *func_name() const { DBUG_ASSERT(0); return "avg_field"; }
850 };
851 
852 
854 {
855 public:
856  ulonglong count;
857  uint prec_increment;
858  uint f_precision, f_scale, dec_bin_size;
859  Item_sum_avg(Item *item_par, bool distinct)
860  :Item_sum_sum(item_par, distinct), count(0)
861  {}
862  Item_sum_avg(THD *thd, Item_sum_avg *item)
863  :Item_sum_sum(thd, item), count(item->count),
864  prec_increment(item->prec_increment) {}
865 
866  void fix_length_and_dec();
867  enum Sumfunctype sum_func () const
868  {
869  return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC;
870  }
871  void clear();
872  bool add();
873  double val_real();
874  // In SPs we might force the "wrong" type with select into a declare variable
875  longlong val_int() { return (longlong) rint(val_real()); }
876  my_decimal *val_decimal(my_decimal *);
877  String *val_str(String *str);
878  void reset_field();
879  void update_field();
880  Item *result_item(Field *field)
881  { return new Item_avg_field(hybrid_type, this); }
883  const char *func_name() const
884  {
885  return has_with_distinct() ? "avg(distinct " : "avg(";
886  }
887  Item *copy_or_same(THD* thd);
888  Field *create_tmp_field(bool group, TABLE *table);
889  void cleanup()
890  {
891  count= 0;
892  Item_sum_sum::cleanup();
893  }
894 };
895 
896 class Item_sum_variance;
897 
899 {
900 protected:
901  uint f_precision0, f_scale0;
902  uint f_precision1, f_scale1;
903  uint dec_bin_size0, dec_bin_size1;
904  uint sample;
905  uint prec_increment;
906 public:
908  enum Type type() const {return FIELD_VARIANCE_ITEM; }
909  double val_real();
910  String *val_str(String *str)
911  { return val_string_from_real(str); }
912  my_decimal *val_decimal(my_decimal *dec_buf)
913  { return val_decimal_from_real(dec_buf); }
914  void fix_length_and_dec() {}
915  const char *func_name() const { DBUG_ASSERT(0); return "variance_field"; }
916 };
917 
918 
919 /*
920  variance(a) =
921 
922  = sum (ai - avg(a))^2 / count(a) )
923  = sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a)
924  = (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) =
925  = (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) =
926  = (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
927  = (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
928  = (sum(ai^2) - sum(a)^2/count(a))/count(a)
929 
930 But, this falls prey to catastrophic cancellation. Instead, use the recurrence formulas
931 
932  M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline
933  S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline
934  for 2 <= k <= n newline
935  ital variance = S_{n} / (n-1)
936 
937 */
938 
940 {
941  void fix_length_and_dec();
942 
943 public:
944  Item_result hybrid_type;
945  int cur_dec;
946  double recurrence_m, recurrence_s; /* Used in recurrence relation. */
947  ulonglong count;
948  uint f_precision0, f_scale0;
949  uint f_precision1, f_scale1;
950  uint dec_bin_size0, dec_bin_size1;
951  uint sample;
952  uint prec_increment;
953 
954  Item_sum_variance(Item *item_par, uint sample_arg) :Item_sum_num(item_par),
955  hybrid_type(REAL_RESULT), count(0), sample(sample_arg)
956  {}
957  Item_sum_variance(THD *thd, Item_sum_variance *item);
958  enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
959  void clear();
960  bool add();
961  double val_real();
962  my_decimal *val_decimal(my_decimal *);
963  void reset_field();
964  void update_field();
965  Item *result_item(Field *field)
966  { return new Item_variance_field(this); }
968  const char *func_name() const
969  { return sample ? "var_samp(" : "variance("; }
970  Item *copy_or_same(THD* thd);
972  enum Item_result result_type () const { return REAL_RESULT; }
973  void cleanup()
974  {
975  count= 0;
976  Item_sum_num::cleanup();
977  }
978 };
979 
980 class Item_sum_std;
981 
983 {
984 public:
986  enum Type type() const { return FIELD_STD_ITEM; }
987  double val_real();
988  my_decimal *val_decimal(my_decimal *);
989  enum Item_result result_type () const { return REAL_RESULT; }
990  enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
991  const char *func_name() const { DBUG_ASSERT(0); return "std_field"; }
992 };
993 
994 /*
995  standard_deviation(a) = sqrt(variance(a))
996 */
997 
999 {
1000  public:
1001  Item_sum_std(Item *item_par, uint sample_arg)
1002  :Item_sum_variance(item_par, sample_arg) {}
1003  Item_sum_std(THD *thd, Item_sum_std *item)
1004  :Item_sum_variance(thd, item)
1005  {}
1006  enum Sumfunctype sum_func () const { return STD_FUNC; }
1007  double val_real();
1008  Item *result_item(Field *field)
1009  { return new Item_std_field(this); }
1010  const char *func_name() const { return "std("; }
1011  Item *copy_or_same(THD* thd);
1012  enum Item_result result_type () const { return REAL_RESULT; }
1013  enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
1014 };
1015 
1016 // This class is a string or number function depending on num_func
1017 class Arg_comparator;
1018 class Item_cache;
1020 {
1021 protected:
1022  Item_cache *value, *arg_cache;
1023  Arg_comparator *cmp;
1024  Item_result hybrid_type;
1025  enum_field_types hybrid_field_type;
1026  int cmp_sign;
1027  bool was_values; // Set if we have found at least one row (for max/min only)
1028 
1029  public:
1030  Item_sum_hybrid(Item *item_par,int sign)
1031  :Item_sum(item_par), value(0), arg_cache(0), cmp(0),
1032  hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG),
1033  cmp_sign(sign), was_values(TRUE)
1034  { collation.set(&my_charset_bin); }
1035  Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
1036  :Item_sum(thd, item), value(item->value), arg_cache(0),
1037  hybrid_type(item->hybrid_type), hybrid_field_type(item->hybrid_field_type),
1038  cmp_sign(item->cmp_sign), was_values(item->was_values)
1039  { }
1040  bool fix_fields(THD *, Item **);
1041  void setup_hybrid(Item *item, Item *value_arg);
1042  void clear();
1043  double val_real();
1044  longlong val_int();
1045  longlong val_time_temporal();
1046  longlong val_date_temporal();
1047  my_decimal *val_decimal(my_decimal *);
1048  bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
1049  bool get_time(MYSQL_TIME *ltime);
1050  void reset_field();
1051  String *val_str(String *);
1052  bool keep_field_type(void) const { return 1; }
1053  enum Item_result result_type () const { return hybrid_type; }
1054  enum enum_field_types field_type() const { return hybrid_field_type; }
1055  void update_field();
1056  void min_max_update_str_field();
1057  void min_max_update_temporal_field();
1058  void min_max_update_real_field();
1059  void min_max_update_int_field();
1061  void cleanup();
1062  bool any_value() { return was_values; }
1063  void no_rows_in_result();
1064  Field *create_tmp_field(bool group, TABLE *table);
1065 };
1066 
1067 
1069 {
1070 public:
1071  Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
1072  Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {}
1073  enum Sumfunctype sum_func () const {return MIN_FUNC;}
1074 
1075  bool add();
1076  const char *func_name() const { return "min("; }
1077  Item *copy_or_same(THD* thd);
1078 };
1079 
1080 
1082 {
1083 public:
1084  Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
1085  Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {}
1086  enum Sumfunctype sum_func () const {return MAX_FUNC;}
1087 
1088  bool add();
1089  const char *func_name() const { return "max("; }
1090  Item *copy_or_same(THD* thd);
1091 };
1092 
1093 
1095 {
1096 protected:
1097  ulonglong reset_bits,bits;
1098 
1099 public:
1100  Item_sum_bit(Item *item_par,ulonglong reset_arg)
1101  :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
1102  Item_sum_bit(THD *thd, Item_sum_bit *item):
1103  Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits) {}
1104  enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
1105  void clear();
1106  longlong val_int();
1107  void reset_field();
1108  void update_field();
1109  void fix_length_and_dec()
1110  { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
1111  void cleanup()
1112  {
1113  bits= reset_bits;
1114  Item_sum_int::cleanup();
1115  }
1116 };
1117 
1118 
1120 {
1121 public:
1122  Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
1123  Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {}
1124  bool add();
1125  const char *func_name() const { return "bit_or("; }
1126  Item *copy_or_same(THD* thd);
1127 };
1128 
1129 
1131 {
1132  public:
1133  Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {}
1134  Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {}
1135  bool add();
1136  const char *func_name() const { return "bit_and("; }
1137  Item *copy_or_same(THD* thd);
1138 };
1139 
1141 {
1142  public:
1143  Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
1144  Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {}
1145  bool add();
1146  const char *func_name() const { return "bit_xor("; }
1147  Item *copy_or_same(THD* thd);
1148 };
1149 
1150 
1151 /*
1152  User defined aggregates
1153 */
1154 
1155 #ifdef HAVE_DLOPEN
1156 
1157 class Item_udf_sum : public Item_sum
1158 {
1159 protected:
1160  udf_handler udf;
1161 
1162 public:
1163  Item_udf_sum(udf_func *udf_arg)
1164  :Item_sum(), udf(udf_arg)
1165  { quick_group=0; }
1166  Item_udf_sum(udf_func *udf_arg, List<Item> &list)
1167  :Item_sum(list), udf(udf_arg)
1168  { quick_group=0;}
1169  Item_udf_sum(THD *thd, Item_udf_sum *item)
1170  :Item_sum(thd, item), udf(item->udf)
1171  { udf.not_original= TRUE; }
1172  const char *func_name() const { return udf.name(); }
1173  bool fix_fields(THD *thd, Item **ref)
1174  {
1175  DBUG_ASSERT(fixed == 0);
1176 
1177  if (init_sum_func_check(thd))
1178  return TRUE;
1179 
1180  fixed= 1;
1181  if (udf.fix_fields(thd, this, this->arg_count, this->args))
1182  return TRUE;
1183 
1184  memcpy (orig_args, args, sizeof (Item *) * arg_count);
1185  return check_sum_func(thd, ref);
1186  }
1187  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
1188  virtual bool have_field_update(void) const { return 0; }
1189 
1190  void clear();
1191  bool add();
1192  void reset_field() {};
1193  void update_field() {};
1194  void cleanup();
1195  virtual void print(String *str, enum_query_type query_type);
1196 };
1197 
1198 
1199 class Item_sum_udf_float :public Item_udf_sum
1200 {
1201  public:
1202  Item_sum_udf_float(udf_func *udf_arg)
1203  :Item_udf_sum(udf_arg) {}
1204  Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
1205  :Item_udf_sum(udf_arg, list) {}
1206  Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
1207  :Item_udf_sum(thd, item) {}
1208  longlong val_int()
1209  {
1210  DBUG_ASSERT(fixed == 1);
1211  return (longlong) rint(Item_sum_udf_float::val_real());
1212  }
1213  double val_real();
1214  String *val_str(String*str);
1215  my_decimal *val_decimal(my_decimal *);
1216  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
1217  {
1218  return get_date_from_real(ltime, fuzzydate);
1219  }
1220  bool get_time(MYSQL_TIME *ltime)
1221  {
1222  return get_time_from_real(ltime);
1223  }
1224  void fix_length_and_dec() { fix_num_length_and_dec(); }
1225  Item *copy_or_same(THD* thd);
1226 };
1227 
1228 
1229 class Item_sum_udf_int :public Item_udf_sum
1230 {
1231 public:
1232  Item_sum_udf_int(udf_func *udf_arg)
1233  :Item_udf_sum(udf_arg) {}
1234  Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
1235  :Item_udf_sum(udf_arg, list) {}
1236  Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
1237  :Item_udf_sum(thd, item) {}
1238  longlong val_int();
1239  double val_real()
1240  { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); }
1241  String *val_str(String*str);
1242  my_decimal *val_decimal(my_decimal *);
1243  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
1244  {
1245  return get_date_from_int(ltime, fuzzydate);
1246  }
1247  bool get_time(MYSQL_TIME *ltime)
1248  {
1249  return get_time_from_int(ltime);
1250  }
1251  enum Item_result result_type () const { return INT_RESULT; }
1252  void fix_length_and_dec() { decimals=0; max_length=21; }
1253  Item *copy_or_same(THD* thd);
1254 };
1255 
1256 
1257 class Item_sum_udf_str :public Item_udf_sum
1258 {
1259 public:
1260  Item_sum_udf_str(udf_func *udf_arg)
1261  :Item_udf_sum(udf_arg) {}
1262  Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
1263  :Item_udf_sum(udf_arg,list) {}
1264  Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
1265  :Item_udf_sum(thd, item) {}
1266  String *val_str(String *);
1267  double val_real()
1268  {
1269  int err_not_used;
1270  char *end_not_used;
1271  String *res;
1272  res=val_str(&str_value);
1273  return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
1274  &end_not_used, &err_not_used) : 0.0;
1275  }
1276  longlong val_int()
1277  {
1278  int err_not_used;
1279  char *end;
1280  String *res;
1281  const CHARSET_INFO *cs;
1282 
1283  if (!(res= val_str(&str_value)))
1284  return 0; /* Null value */
1285  cs= res->charset();
1286  end= (char*) res->ptr()+res->length();
1287  return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used);
1288  }
1289  my_decimal *val_decimal(my_decimal *dec);
1290  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
1291  {
1292  return get_date_from_string(ltime, fuzzydate);
1293  }
1294  bool get_time(MYSQL_TIME *ltime)
1295  {
1296  return get_time_from_string(ltime);
1297  }
1298  enum Item_result result_type () const { return STRING_RESULT; }
1299  void fix_length_and_dec();
1300  Item *copy_or_same(THD* thd);
1301 };
1302 
1303 
1304 class Item_sum_udf_decimal :public Item_udf_sum
1305 {
1306 public:
1307  Item_sum_udf_decimal(udf_func *udf_arg)
1308  :Item_udf_sum(udf_arg) {}
1309  Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
1310  :Item_udf_sum(udf_arg, list) {}
1312  :Item_udf_sum(thd, item) {}
1313  String *val_str(String *);
1314  double val_real();
1315  longlong val_int();
1316  my_decimal *val_decimal(my_decimal *);
1317  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
1318  {
1319  return get_date_from_decimal(ltime, fuzzydate);
1320  }
1321  bool get_time(MYSQL_TIME *ltime)
1322  {
1323  return get_time_from_decimal(ltime);
1324  }
1325  enum Item_result result_type () const { return DECIMAL_RESULT; }
1326  void fix_length_and_dec() { fix_num_length_and_dec(); }
1327  Item *copy_or_same(THD* thd);
1328 };
1329 
1330 #else /* Dummy functions to get sql_yacc.cc compiled */
1331 
1333 {
1334  public:
1335  Item_sum_udf_float(udf_func *udf_arg)
1336  :Item_sum_num() {}
1337  Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
1338  Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
1339  :Item_sum_num(thd, item) {}
1340  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
1341  double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
1342  void clear() {}
1343  bool add() { return 0; }
1344  void update_field() {}
1345 };
1346 
1347 
1349 {
1350 public:
1351  Item_sum_udf_int(udf_func *udf_arg)
1352  :Item_sum_num() {}
1353  Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
1354  Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
1355  :Item_sum_num(thd, item) {}
1356  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
1357  longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; }
1358  double val_real() { DBUG_ASSERT(fixed == 1); return 0; }
1359  void clear() {}
1360  bool add() { return 0; }
1361  void update_field() {}
1362 };
1363 
1364 
1366 {
1367  public:
1368  Item_sum_udf_decimal(udf_func *udf_arg)
1369  :Item_sum_num() {}
1370  Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
1371  :Item_sum_num() {}
1372  Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item)
1373  :Item_sum_num(thd, item) {}
1374  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
1375  double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
1376  my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; }
1377  void clear() {}
1378  bool add() { return 0; }
1379  void update_field() {}
1380 };
1381 
1382 
1384 {
1385 public:
1386  Item_sum_udf_str(udf_func *udf_arg)
1387  :Item_sum_num() {}
1388  Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
1389  :Item_sum_num() {}
1390  Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
1391  :Item_sum_num(thd, item) {}
1392  String *val_str(String *)
1393  { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
1394  double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; }
1395  longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
1396  enum Item_result result_type () const { return STRING_RESULT; }
1397  void fix_length_and_dec() { maybe_null=1; max_length=0; }
1398  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
1399  void clear() {}
1400  bool add() { return 0; }
1401  void update_field() {}
1402 };
1403 
1404 #endif /* HAVE_DLOPEN */
1405 
1406 C_MODE_START
1407 int group_concat_key_cmp_with_distinct(const void* arg, const void* key1,
1408  const void* key2);
1409 int group_concat_key_cmp_with_order(const void* arg, const void* key1,
1410  const void* key2);
1411 int dump_leaf_key(void* key_arg,
1412  element_count count __attribute__((unused)),
1413  void* item_arg);
1414 C_MODE_END
1415 
1417 {
1418  TMP_TABLE_PARAM *tmp_table_param;
1419  String result;
1420  String *separator;
1421  TREE tree_base;
1422  TREE *tree;
1423 
1431  Unique *unique_filter;
1432  TABLE *table;
1433  ORDER **order;
1434  Name_resolution_context *context;
1436  uint arg_count_order;
1438  uint arg_count_field;
1439  uint row_count;
1440  bool distinct;
1441  bool warning_for_row;
1442  bool always_null;
1443  bool force_copy_fields;
1444  bool no_appended;
1445  /*
1446  Following is 0 normal object and pointer to original one for copy
1447  (to correctly free resources)
1448  */
1449  Item_func_group_concat *original;
1450 
1451  friend int group_concat_key_cmp_with_distinct(const void* arg,
1452  const void* key1,
1453  const void* key2);
1454  friend int group_concat_key_cmp_with_order(const void* arg,
1455  const void* key1,
1456  const void* key2);
1457  friend int dump_leaf_key(void* key_arg,
1458  element_count count __attribute__((unused)),
1459  void* item_arg);
1460 
1461 public:
1463  bool is_distinct, List<Item> *is_select,
1464  const SQL_I_List<ORDER> &is_order, String *is_separator);
1465 
1468  void cleanup();
1469 
1470  enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
1471  const char *func_name() const { return "group_concat"; }
1472  virtual Item_result result_type () const { return STRING_RESULT; }
1473  virtual Field *make_string_field(TABLE *table);
1474  enum_field_types field_type() const
1475  {
1476  if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB )
1477  return MYSQL_TYPE_BLOB;
1478  else
1479  return MYSQL_TYPE_VARCHAR;
1480  }
1481  void clear();
1482  bool add();
1483  void reset_field() { DBUG_ASSERT(0); } // not used
1484  void update_field() { DBUG_ASSERT(0); } // not used
1485  bool fix_fields(THD *,Item **);
1486  bool setup(THD *thd);
1487  void make_unique();
1488  double val_real()
1489  {
1490  String *res; res=val_str(&str_value);
1491  return res ? my_atof(res->c_ptr()) : 0.0;
1492  }
1493  longlong val_int()
1494  {
1495  String *res;
1496  char *end_ptr;
1497  int error;
1498  if (!(res= val_str(&str_value)))
1499  return (longlong) 0;
1500  end_ptr= (char*) res->ptr()+ res->length();
1501  return my_strtoll10(res->ptr(), &end_ptr, &error);
1502  }
1503  my_decimal *val_decimal(my_decimal *decimal_value)
1504  {
1505  return val_decimal_from_string(decimal_value);
1506  }
1507  bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
1508  {
1509  return get_date_from_string(ltime, fuzzydate);
1510  }
1511  bool get_time(MYSQL_TIME *ltime)
1512  {
1513  return get_time_from_string(ltime);
1514  }
1515  String* val_str(String* str);
1516  Item *copy_or_same(THD* thd);
1518  virtual void print(String *str, enum_query_type query_type);
1519  virtual bool change_context_processor(uchar *cntx)
1520  { context= (Name_resolution_context *)cntx; return FALSE; }
1521 };
1522 
1523 #endif /* ITEM_SUM_INCLUDED */