home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / sql / item_sum.h < prev    next >
C/C++ Source or Header  |  2000-08-31  |  13KB  |  465 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17.  
  18. /* classes for sum functions */
  19.  
  20. #ifdef __GNUC__
  21. #pragma interface            /* gcc class implementation */
  22. #endif
  23.  
  24. class Item_sum :public Item_result_field
  25. {
  26. public:
  27.   enum Sumfunctype {COUNT_FUNC,COUNT_DISTINCT_FUNC,SUM_FUNC,AVG_FUNC,MIN_FUNC,
  28.             MAX_FUNC, UNIQUE_USERS_FUNC,STD_FUNC,SUM_BIT_FUNC,
  29.             UDF_SUM_FUNC };
  30.  
  31.   Item **args,*tmp_args[2];
  32.   uint arg_count;
  33.   bool quick_group;            /* If incremental update of fields */
  34.  
  35.   Item_sum() : arg_count(0),quick_group(1) { with_sum_func=1; }
  36.   Item_sum(Item *a) :quick_group(1)
  37.   {
  38.     arg_count=1;
  39.     args=tmp_args;
  40.     args[0]=a;
  41.     with_sum_func = 1;
  42.   }
  43.   Item_sum( Item *a, Item *b ) :quick_group(1)
  44.   {
  45.     arg_count=2;
  46.     args=tmp_args;
  47.     args[0]=a; args[1]=b;
  48.     with_sum_func=1;
  49.   }
  50.   Item_sum(List<Item> &list);
  51.   ~Item_sum() { result_field=0; }
  52.   enum Type type() const { return SUM_FUNC_ITEM; }
  53.   virtual enum Sumfunctype sum_func () const=0;
  54.   virtual void reset()=0;
  55.   virtual bool add()=0;
  56.   virtual void reset_field()=0;
  57.   virtual void update_field(int offset)=0;
  58.   virtual bool keep_field_type(void) const { return 0; }
  59.   virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
  60.   virtual const char *func_name() const { return "?"; }
  61.   virtual Item *result_item(Field *field)
  62.   { return new Item_field(field);}
  63.   table_map used_tables() const { return ~(table_map) 0; } /* Not used */
  64.   bool const_item() const { return 0; }
  65.   void update_used_tables() { }
  66.   void make_field(Send_field *field);
  67.   void print(String *str);
  68.   void fix_num_length_and_dec();
  69.   virtual bool setup(THD *thd) {return 0;}
  70. };
  71.  
  72.  
  73. class Item_sum_num :public Item_sum
  74. {
  75. public:
  76.   Item_sum_num() :Item_sum() {}
  77.   Item_sum_num(Item *item_par) :Item_sum(item_par) {}
  78.   Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
  79.   Item_sum_num(List<Item> &list) :Item_sum(list) {}
  80.   bool fix_fields(THD *,struct st_table_list *);
  81.   longlong val_int() { return (longlong) val(); } /* Real as default */
  82.   String *val_str(String*str);
  83.   void reset_field();
  84. };
  85.  
  86.  
  87. class Item_sum_int :public Item_sum_num
  88. {
  89.   void fix_length_and_dec()
  90.     { decimals=0; max_length=21; maybe_null=null_value=0; }
  91.  
  92. public:
  93.   Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
  94.   Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
  95.   double val() { return (double) val_int(); }
  96.   String *val_str(String*str);
  97.   enum Item_result result_type () const { return INT_RESULT; }
  98. };
  99.  
  100.  
  101. class Item_sum_sum :public Item_sum_num
  102. {
  103.   double sum;
  104.   void fix_length_and_dec() { maybe_null=null_value=1; }
  105.  
  106.   public:
  107.   Item_sum_sum(Item *item_par) :Item_sum_num(item_par),sum(0.0) {}
  108.   enum Sumfunctype sum_func () const {return SUM_FUNC;}
  109.   void reset();
  110.   bool add();
  111.   double val();
  112.   void reset_field();
  113.   void update_field(int offset);
  114.   const char *func_name() const { return "sum"; }
  115. };
  116.  
  117.  
  118. class Item_sum_count :public Item_sum_int
  119. {
  120.   longlong count;
  121.   table_map used_table_cache;
  122.  
  123.   public:
  124.   Item_sum_count(Item *item_par)
  125.     :Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0)
  126.   {}
  127.   table_map used_tables() const { return used_table_cache; }
  128.   bool const_item() const { return !used_table_cache; }
  129.   enum Sumfunctype sum_func () const { return COUNT_FUNC; }
  130.   void reset();
  131.   bool add();
  132.   void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
  133.   longlong val_int();
  134.   void reset_field();
  135.   void update_field(int offset);
  136.   const char *func_name() const { return "count"; }
  137. };
  138.  
  139.  
  140. class TMP_TABLE_PARAM;
  141.  
  142. class Item_sum_count_distinct :public Item_sum_int
  143. {
  144.   TABLE *table;
  145.   table_map used_table_cache;
  146.   bool fix_fields(THD *thd,TABLE_LIST *tables);
  147.   TMP_TABLE_PARAM *tmp_table_param;
  148.  
  149.   public:
  150.   Item_sum_count_distinct(List<Item> &list)
  151.     :Item_sum_int(list),table(0),used_table_cache(~(table_map) 0),
  152.     tmp_table_param(0)
  153.   { quick_group=0; }
  154.   ~Item_sum_count_distinct();
  155.   table_map used_tables() const { return used_table_cache; }
  156.   enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
  157.   void reset();
  158.   bool add();
  159.   longlong val_int();
  160.   void reset_field() { return ;}        // Never called
  161.   void update_field(int offset) { return ; }    // Never called
  162.   const char *func_name() const { return "count_distinct"; }
  163.   bool setup(THD *thd);
  164. };
  165.  
  166.  
  167. /* Item to get the value of a stored sum function */
  168.  
  169. class Item_avg_field :public Item_result_field
  170. {
  171. public:
  172.   Field *field;
  173.   Item_avg_field(Item_sum_avg *item);
  174.   enum Type type() const { return FIELD_AVG_ITEM; }
  175.   double val();
  176.   longlong val_int() { return (longlong) val(); }
  177.   String *val_str(String*);
  178.   void make_field(Send_field *field);
  179.   void fix_length_and_dec() {}
  180. };
  181.  
  182.  
  183. class Item_sum_avg :public Item_sum_num
  184. {
  185.   void fix_length_and_dec() { decimals+=4; maybe_null=1; }
  186.  
  187.   double sum;
  188.   ulonglong count;
  189.  
  190.   public:
  191.   Item_sum_avg(Item *item_par) :Item_sum_num(item_par),count(0) {}
  192.   enum Sumfunctype sum_func () const {return AVG_FUNC;}
  193.   void reset();
  194.   bool add();
  195.   double val();
  196.   void reset_field();
  197.   void update_field(int offset);
  198.   Item *result_item(Field *field)
  199.   { return new Item_avg_field(this); }
  200.   const char *func_name() const { return "avg"; }
  201. };
  202.  
  203.  
  204. class Item_std_field :public Item_result_field
  205. {
  206. public:
  207.   Field *field;
  208.   Item_std_field(Item_sum_std *item);
  209.   enum Type type() const { return FIELD_STD_ITEM; }
  210.   double val();
  211.   longlong val_int() { return (longlong) val(); }
  212.   String *val_str(String*);
  213.   void make_field(Send_field *field);
  214.   void fix_length_and_dec() {}
  215. };
  216.  
  217. class Item_sum_std :public Item_sum_num
  218. {
  219.   double sum;
  220.   double sum_sqr;
  221.   ulonglong count;
  222.   void fix_length_and_dec() { decimals+=4; maybe_null=1; }
  223.  
  224.   public:
  225.   Item_sum_std(Item *item_par) :Item_sum_num(item_par),count(0) {}
  226.   enum Sumfunctype sum_func () const { return STD_FUNC; }
  227.   void reset();
  228.   bool add();
  229.   double val();
  230.   void reset_field();
  231.   void update_field(int offset);
  232.   Item *result_item(Field *field)
  233.   { return new Item_std_field(this); }
  234.   const char *func_name() const { return "std"; }
  235. };
  236.  
  237.  
  238. // This class is a string or number function depending on num_func
  239.  
  240. class Item_sum_hybrid :public Item_sum
  241. {
  242.  protected:
  243.   String value,tmp_value;
  244.   double sum;
  245.   Item_result hybrid_type;
  246.   int cmp_sign;
  247.   table_map used_table_cache;
  248.  
  249.   public:
  250.   Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign),
  251.     used_table_cache(~(table_map) 0)
  252.   {}
  253.   bool fix_fields(THD *,struct st_table_list *);
  254.   table_map used_tables() const { return used_table_cache; }
  255.   bool const_item() const { return !used_table_cache; }
  256.  
  257.   void reset()
  258.   {
  259.     sum=0.0;
  260.     value.length(0);
  261.     null_value=1;
  262.     add();
  263.   }
  264.   double val();
  265.   longlong val_int() { return (longlong) val(); } /* Real as default */
  266.   void reset_field();
  267.   String *val_str(String *);
  268.   void make_const() { used_table_cache=0; }
  269.   bool keep_field_type(void) const { return 1; }
  270.   enum Item_result result_type () const { return hybrid_type; }
  271.   void update_field(int offset);
  272.   void min_max_update_str_field(int offset);
  273.   void min_max_update_real_field(int offset);
  274.   void min_max_update_int_field(int offset);
  275. };
  276.  
  277.  
  278. class Item_sum_min :public Item_sum_hybrid
  279. {
  280. public:
  281.   Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
  282.   enum Sumfunctype sum_func () const {return MIN_FUNC;}
  283.  
  284.   bool add();
  285.   const char *func_name() const { return "min"; }
  286. };
  287.  
  288.  
  289. class Item_sum_max :public Item_sum_hybrid
  290. {
  291. public:
  292.   Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
  293.   enum Sumfunctype sum_func () const {return MAX_FUNC;}
  294.  
  295.   bool add();
  296.   const char *func_name() const { return "max"; }
  297. };
  298.  
  299.  
  300. class Item_sum_bit :public Item_sum_int
  301. {
  302.  protected:
  303.   ulonglong reset_bits,bits;
  304.  
  305.   public:
  306.   Item_sum_bit(Item *item_par,ulonglong reset_arg)
  307.     :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
  308.   enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
  309.   void reset();
  310.   longlong val_int();
  311.   void reset_field();
  312. };
  313.  
  314.  
  315. class Item_sum_or :public Item_sum_bit
  316. {
  317.   public:
  318.   Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
  319.   bool add();
  320.   void update_field(int offset);
  321.   const char *func_name() const { return "bit_or"; }
  322. };
  323.  
  324.  
  325. class Item_sum_and :public Item_sum_bit
  326. {
  327.   public:
  328.   Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
  329.   bool add();
  330.   void update_field(int offset);
  331.   const char *func_name() const { return "bit_and"; }
  332. };
  333.  
  334. /*
  335. **    user defined aggregates
  336. */
  337. #ifdef HAVE_DLOPEN
  338.  
  339. class Item_udf_sum : public Item_sum
  340. {
  341. protected:
  342.   udf_handler udf;
  343.  
  344. public:
  345.   Item_udf_sum(udf_func *udf_arg) :Item_sum(), udf(udf_arg) { quick_group=0;}
  346.   Item_udf_sum( udf_func *udf_arg, List<Item> &list )
  347.     :Item_sum( list ), udf(udf_arg)
  348.   { quick_group=0;}
  349.   ~Item_udf_sum() {}
  350.   const char *func_name() const { return udf.name(); }
  351.   bool fix_fields(THD *thd,struct st_table_list *tables)
  352.   {
  353.     return udf.fix_fields(thd,tables,this,this->arg_count,this->args);
  354.   }
  355.   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  356.   virtual bool have_field_update(void) const { return 0; }
  357.  
  358.   void reset();
  359.   bool add();
  360.   void reset_field() {};
  361.   void update_field(int offset_arg) {};
  362. };
  363.  
  364.  
  365. class Item_sum_udf_float :public Item_udf_sum
  366. {
  367.  public:
  368.   Item_sum_udf_float(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  369.   Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
  370.     :Item_udf_sum(udf_arg,list) {}
  371.   ~Item_sum_udf_float() {}
  372.   longlong val_int() { return (longlong) Item_sum_udf_float::val(); }
  373.   double val();
  374.   String *val_str(String*str);
  375.   void fix_length_and_dec() { fix_num_length_and_dec(); }
  376. };
  377.  
  378.  
  379. class Item_sum_udf_int :public Item_udf_sum
  380. {
  381. public:
  382.   Item_sum_udf_int(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  383.   Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
  384.     :Item_udf_sum(udf_arg,list) {}
  385.   ~Item_sum_udf_int() {}
  386.   longlong val_int();
  387.   double val() { return (double) Item_sum_udf_int::val_int(); }
  388.   String *val_str(String*str);
  389.   enum Item_result result_type () const { return INT_RESULT; }
  390.   void fix_length_and_dec() { decimals=0; max_length=21; }
  391. };
  392.  
  393.  
  394. class Item_sum_udf_str :public Item_udf_sum
  395. {
  396. public:
  397.   Item_sum_udf_str(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  398.   Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
  399.     :Item_udf_sum(udf_arg,list) {}
  400.   ~Item_sum_udf_str() {}
  401.   String *val_str(String *);
  402.   double val()
  403.   {
  404.     String *res;  res=val_str(&str_value);
  405.     return res ? atof(res->c_ptr()) : 0.0;
  406.   }
  407.   longlong val_int()
  408.   {
  409.     String *res;  res=val_str(&str_value);
  410.     return res ? strtoll(res->c_ptr(),(char**) 0,10) : (longlong) 0;
  411.   }
  412.   enum Item_result result_type () const { return STRING_RESULT; }
  413.   void fix_length_and_dec();
  414. };
  415.  
  416. #else /* Dummy functions to get sql_yacc.cc compiled */
  417.  
  418. class Item_sum_udf_float :public Item_sum_num
  419. {
  420.  public:
  421.   Item_sum_udf_float(udf_func *udf_arg) :Item_sum_num() {}
  422.   Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
  423.   ~Item_sum_udf_float() {}
  424.   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  425.   double val() { return 0.0; }
  426.   void reset() {}
  427.   bool add() { return 0; }  
  428.   void update_field(int offset) {}
  429. };
  430.  
  431.  
  432. class Item_sum_udf_int :public Item_sum_num
  433. {
  434. public:
  435.   Item_sum_udf_int(udf_func *udf_arg) :Item_sum_num() {}
  436.   Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
  437.   ~Item_sum_udf_int() {}
  438.   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  439.   longlong val_int() { return 0; }
  440.   double val() { return 0; }
  441.   void reset() {}
  442.   bool add() { return 0; }  
  443.   void update_field(int offset) {}
  444. };
  445.  
  446.  
  447. class Item_sum_udf_str :public Item_sum_num
  448. {
  449. public:
  450.   Item_sum_udf_str(udf_func *udf_arg) :Item_sum_num() {}
  451.   Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)  :Item_sum_num() {}
  452.   ~Item_sum_udf_str() {}
  453.   String *val_str(String *) { null_value=1; return 0; }
  454.   double val() { null_value=1; return 0.0; }
  455.   longlong val_int() { null_value=1; return 0; }
  456.   enum Item_result result_type () const { return STRING_RESULT; }
  457.   void fix_length_and_dec() { maybe_null=1; max_length=0; }
  458.   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  459.   void reset() {}
  460.   bool add() { return 0; }  
  461.   void update_field(int offset) {}
  462. };
  463.  
  464. #endif /* HAVE_DLOPEN */
  465.