item_sum.h
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:13k
源码类别:

MySQL数据库

开发平台:

Visual C++

  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. /* classes for sum functions */
  17. #ifdef __GNUC__
  18. #pragma interface /* gcc class implementation */
  19. #endif
  20. class Item_sum :public Item_result_field
  21. {
  22. public:
  23.   enum Sumfunctype {COUNT_FUNC,COUNT_DISTINCT_FUNC,SUM_FUNC,AVG_FUNC,MIN_FUNC,
  24.     MAX_FUNC, UNIQUE_USERS_FUNC,STD_FUNC,SUM_BIT_FUNC,
  25.     UDF_SUM_FUNC };
  26.   Item **args,*tmp_args[2];
  27.   uint arg_count;
  28.   bool quick_group; /* If incremental update of fields */
  29.   Item_sum() : arg_count(0),quick_group(1) { with_sum_func=1; }
  30.   Item_sum(Item *a) :quick_group(1)
  31.   {
  32.     arg_count=1;
  33.     args=tmp_args;
  34.     args[0]=a;
  35.     with_sum_func = 1;
  36.   }
  37.   Item_sum( Item *a, Item *b ) :quick_group(1)
  38.   {
  39.     arg_count=2;
  40.     args=tmp_args;
  41.     args[0]=a; args[1]=b;
  42.     with_sum_func=1;
  43.   }
  44.   Item_sum(List<Item> &list);
  45.   ~Item_sum() { result_field=0; }
  46.   enum Type type() const { return SUM_FUNC_ITEM; }
  47.   virtual enum Sumfunctype sum_func () const=0;
  48.   virtual void reset()=0;
  49.   virtual bool add()=0;
  50.   virtual void reset_field()=0;
  51.   virtual void update_field(int offset)=0;
  52.   virtual bool keep_field_type(void) const { return 0; }
  53.   virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
  54.   virtual const char *func_name() const { return "?"; }
  55.   virtual Item *result_item(Field *field)
  56.   { return new Item_field(field);}
  57.   table_map used_tables() const { return ~(table_map) 0; } /* Not used */
  58.   bool const_item() const { return 0; }
  59.   void update_used_tables() { }
  60.   void make_field(Send_field *field);
  61.   void print(String *str);
  62.   void fix_num_length_and_dec();
  63.   virtual bool setup(THD *thd) {return 0;}
  64. };
  65. class Item_sum_num :public Item_sum
  66. {
  67. public:
  68.   Item_sum_num() :Item_sum() {}
  69.   Item_sum_num(Item *item_par) :Item_sum(item_par) {}
  70.   Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
  71.   Item_sum_num(List<Item> &list) :Item_sum(list) {}
  72.   bool fix_fields(THD *,struct st_table_list *);
  73.   longlong val_int() { return (longlong) val(); } /* Real as default */
  74.   String *val_str(String*str);
  75.   void reset_field();
  76. };
  77. class Item_sum_int :public Item_sum_num
  78. {
  79.   void fix_length_and_dec()
  80.     { decimals=0; max_length=21; maybe_null=null_value=0; }
  81. public:
  82.   Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
  83.   Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
  84.   double val() { return (double) val_int(); }
  85.   String *val_str(String*str);
  86.   enum Item_result result_type () const { return INT_RESULT; }
  87. };
  88. class Item_sum_sum :public Item_sum_num
  89. {
  90.   double sum;
  91.   void fix_length_and_dec() { maybe_null=null_value=1; }
  92.   public:
  93.   Item_sum_sum(Item *item_par) :Item_sum_num(item_par),sum(0.0) {}
  94.   enum Sumfunctype sum_func () const {return SUM_FUNC;}
  95.   void reset();
  96.   bool add();
  97.   double val();
  98.   void reset_field();
  99.   void update_field(int offset);
  100.   const char *func_name() const { return "sum"; }
  101. };
  102. class Item_sum_count :public Item_sum_int
  103. {
  104.   longlong count;
  105.   table_map used_table_cache;
  106.   public:
  107.   Item_sum_count(Item *item_par)
  108.     :Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0)
  109.   {}
  110.   table_map used_tables() const { return used_table_cache; }
  111.   bool const_item() const { return !used_table_cache; }
  112.   enum Sumfunctype sum_func () const { return COUNT_FUNC; }
  113.   void reset();
  114.   bool add();
  115.   void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
  116.   longlong val_int();
  117.   void reset_field();
  118.   void update_field(int offset);
  119.   const char *func_name() const { return "count"; }
  120. };
  121. class TMP_TABLE_PARAM;
  122. class Item_sum_count_distinct :public Item_sum_int
  123. {
  124.   TABLE *table;
  125.   table_map used_table_cache;
  126.   bool fix_fields(THD *thd,TABLE_LIST *tables);
  127.   TMP_TABLE_PARAM *tmp_table_param;
  128.   public:
  129.   Item_sum_count_distinct(List<Item> &list)
  130.     :Item_sum_int(list),table(0),used_table_cache(~(table_map) 0),
  131.     tmp_table_param(0)
  132.   { quick_group=0; }
  133.   ~Item_sum_count_distinct();
  134.   table_map used_tables() const { return used_table_cache; }
  135.   enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
  136.   void reset();
  137.   bool add();
  138.   longlong val_int();
  139.   void reset_field() { return ;} // Never called
  140.   void update_field(int offset) { return ; } // Never called
  141.   const char *func_name() const { return "count_distinct"; }
  142.   bool setup(THD *thd);
  143. };
  144. /* Item to get the value of a stored sum function */
  145. class Item_sum_avg;
  146. class Item_avg_field :public Item_result_field
  147. {
  148. public:
  149.   Field *field;
  150.   Item_avg_field(Item_sum_avg *item);
  151.   enum Type type() const { return FIELD_AVG_ITEM; }
  152.   double val();
  153.   longlong val_int() { return (longlong) val(); }
  154.   String *val_str(String*);
  155.   void make_field(Send_field *field);
  156.   void fix_length_and_dec() {}
  157. };
  158. class Item_sum_avg :public Item_sum_num
  159. {
  160.   void fix_length_and_dec() { decimals+=4; maybe_null=1; }
  161.   double sum;
  162.   ulonglong count;
  163.   public:
  164.   Item_sum_avg(Item *item_par) :Item_sum_num(item_par),count(0) {}
  165.   enum Sumfunctype sum_func () const {return AVG_FUNC;}
  166.   void reset();
  167.   bool add();
  168.   double val();
  169.   void reset_field();
  170.   void update_field(int offset);
  171.   Item *result_item(Field *field)
  172.   { return new Item_avg_field(this); }
  173.   const char *func_name() const { return "avg"; }
  174. };
  175. class Item_sum_std;
  176. class Item_std_field :public Item_result_field
  177. {
  178. public:
  179.   Field *field;
  180.   Item_std_field(Item_sum_std *item);
  181.   enum Type type() const { return FIELD_STD_ITEM; }
  182.   double val();
  183.   longlong val_int() { return (longlong) val(); }
  184.   String *val_str(String*);
  185.   void make_field(Send_field *field);
  186.   void fix_length_and_dec() {}
  187. };
  188. class Item_sum_std :public Item_sum_num
  189. {
  190.   double sum;
  191.   double sum_sqr;
  192.   ulonglong count;
  193.   void fix_length_and_dec() { decimals+=4; maybe_null=1; }
  194.   public:
  195.   Item_sum_std(Item *item_par) :Item_sum_num(item_par),count(0) {}
  196.   enum Sumfunctype sum_func () const { return STD_FUNC; }
  197.   void reset();
  198.   bool add();
  199.   double val();
  200.   void reset_field();
  201.   void update_field(int offset);
  202.   Item *result_item(Field *field)
  203.   { return new Item_std_field(this); }
  204.   const char *func_name() const { return "std"; }
  205. };
  206. // This class is a string or number function depending on num_func
  207. class Item_sum_hybrid :public Item_sum
  208. {
  209.  protected:
  210.   String value,tmp_value;
  211.   double sum;
  212.   Item_result hybrid_type;
  213.   int cmp_sign;
  214.   table_map used_table_cache;
  215.   public:
  216.   Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign),
  217.     used_table_cache(~(table_map) 0)
  218.   {}
  219.   bool fix_fields(THD *,struct st_table_list *);
  220.   table_map used_tables() const { return used_table_cache; }
  221.   bool const_item() const { return !used_table_cache; }
  222.   void reset()
  223.   {
  224.     sum=0.0;
  225.     value.length(0);
  226.     null_value=1;
  227.     add();
  228.   }
  229.   double val();
  230.   longlong val_int() { return (longlong) val(); } /* Real as default */
  231.   void reset_field();
  232.   String *val_str(String *);
  233.   void make_const() { used_table_cache=0; }
  234.   bool keep_field_type(void) const { return 1; }
  235.   enum Item_result result_type () const { return hybrid_type; }
  236.   void update_field(int offset);
  237.   void min_max_update_str_field(int offset);
  238.   void min_max_update_real_field(int offset);
  239.   void min_max_update_int_field(int offset);
  240. };
  241. class Item_sum_min :public Item_sum_hybrid
  242. {
  243. public:
  244.   Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
  245.   enum Sumfunctype sum_func () const {return MIN_FUNC;}
  246.   bool add();
  247.   const char *func_name() const { return "min"; }
  248. };
  249. class Item_sum_max :public Item_sum_hybrid
  250. {
  251. public:
  252.   Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
  253.   enum Sumfunctype sum_func () const {return MAX_FUNC;}
  254.   bool add();
  255.   const char *func_name() const { return "max"; }
  256. };
  257. class Item_sum_bit :public Item_sum_int
  258. {
  259.  protected:
  260.   ulonglong reset_bits,bits;
  261.   public:
  262.   Item_sum_bit(Item *item_par,ulonglong reset_arg)
  263.     :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
  264.   enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
  265.   void reset();
  266.   longlong val_int();
  267.   void reset_field();
  268. };
  269. class Item_sum_or :public Item_sum_bit
  270. {
  271.   public:
  272.   Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
  273.   bool add();
  274.   void update_field(int offset);
  275.   const char *func_name() const { return "bit_or"; }
  276. };
  277. class Item_sum_and :public Item_sum_bit
  278. {
  279.   public:
  280.   Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
  281.   bool add();
  282.   void update_field(int offset);
  283.   const char *func_name() const { return "bit_and"; }
  284. };
  285. /*
  286. ** user defined aggregates
  287. */
  288. #ifdef HAVE_DLOPEN
  289. class Item_udf_sum : public Item_sum
  290. {
  291. protected:
  292.   udf_handler udf;
  293. public:
  294.   Item_udf_sum(udf_func *udf_arg) :Item_sum(), udf(udf_arg) { quick_group=0;}
  295.   Item_udf_sum( udf_func *udf_arg, List<Item> &list )
  296.     :Item_sum( list ), udf(udf_arg)
  297.   { quick_group=0;}
  298.   ~Item_udf_sum() {}
  299.   const char *func_name() const { return udf.name(); }
  300.   bool fix_fields(THD *thd,struct st_table_list *tables)
  301.   {
  302.     return udf.fix_fields(thd,tables,this,this->arg_count,this->args);
  303.   }
  304.   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  305.   virtual bool have_field_update(void) const { return 0; }
  306.   void reset();
  307.   bool add();
  308.   void reset_field() {};
  309.   void update_field(int offset_arg) {};
  310. };
  311. class Item_sum_udf_float :public Item_udf_sum
  312. {
  313.  public:
  314.   Item_sum_udf_float(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  315.   Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
  316.     :Item_udf_sum(udf_arg,list) {}
  317.   ~Item_sum_udf_float() {}
  318.   longlong val_int() { return (longlong) Item_sum_udf_float::val(); }
  319.   double val();
  320.   String *val_str(String*str);
  321.   void fix_length_and_dec() { fix_num_length_and_dec(); }
  322. };
  323. class Item_sum_udf_int :public Item_udf_sum
  324. {
  325. public:
  326.   Item_sum_udf_int(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  327.   Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
  328.     :Item_udf_sum(udf_arg,list) {}
  329.   ~Item_sum_udf_int() {}
  330.   longlong val_int();
  331.   double val() { return (double) Item_sum_udf_int::val_int(); }
  332.   String *val_str(String*str);
  333.   enum Item_result result_type () const { return INT_RESULT; }
  334.   void fix_length_and_dec() { decimals=0; max_length=21; }
  335. };
  336. class Item_sum_udf_str :public Item_udf_sum
  337. {
  338. public:
  339.   Item_sum_udf_str(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
  340.   Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
  341.     :Item_udf_sum(udf_arg,list) {}
  342.   ~Item_sum_udf_str() {}
  343.   String *val_str(String *);
  344.   double val()
  345.   {
  346.     String *res;  res=val_str(&str_value);
  347.     return res ? atof(res->c_ptr()) : 0.0;
  348.   }
  349.   longlong val_int()
  350.   {
  351.     String *res;  res=val_str(&str_value);
  352.     return res ? strtoll(res->c_ptr(),(char**) 0,10) : (longlong) 0;
  353.   }
  354.   enum Item_result result_type () const { return STRING_RESULT; }
  355.   void fix_length_and_dec();
  356. };
  357. #else /* Dummy functions to get sql_yacc.cc compiled */
  358. class Item_sum_udf_float :public Item_sum_num
  359. {
  360.  public:
  361.   Item_sum_udf_float(udf_func *udf_arg) :Item_sum_num() {}
  362.   Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
  363.   ~Item_sum_udf_float() {}
  364.   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  365.   double val() { return 0.0; }
  366.   void reset() {}
  367.   bool add() { return 0; }  
  368.   void update_field(int offset) {}
  369. };
  370. class Item_sum_udf_int :public Item_sum_num
  371. {
  372. public:
  373.   Item_sum_udf_int(udf_func *udf_arg) :Item_sum_num() {}
  374.   Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
  375.   ~Item_sum_udf_int() {}
  376.   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  377.   longlong val_int() { return 0; }
  378.   double val() { return 0; }
  379.   void reset() {}
  380.   bool add() { return 0; }  
  381.   void update_field(int offset) {}
  382. };
  383. class Item_sum_udf_str :public Item_sum_num
  384. {
  385. public:
  386.   Item_sum_udf_str(udf_func *udf_arg) :Item_sum_num() {}
  387.   Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)  :Item_sum_num() {}
  388.   ~Item_sum_udf_str() {}
  389.   String *val_str(String *) { null_value=1; return 0; }
  390.   double val() { null_value=1; return 0.0; }
  391.   longlong val_int() { null_value=1; return 0; }
  392.   enum Item_result result_type () const { return STRING_RESULT; }
  393.   void fix_length_and_dec() { maybe_null=1; max_length=0; }
  394.   enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
  395.   void reset() {}
  396.   bool add() { return 0; }  
  397.   void update_field(int offset) {}
  398. };
  399. #endif /* HAVE_DLOPEN */