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

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. /* Analyse database */
  17. #ifdef __GNUC__
  18. #pragma interface /* gcc class implementation */
  19. #endif
  20. #include <my_tree.h>
  21. #define DEC_IN_AVG 4
  22. typedef struct st_number_info
  23. {
  24.   // if zerofill is true, the number must be zerofill, or string
  25.   bool     negative, is_float, zerofill, maybe_zerofill;
  26.   int8     integers;
  27.   int8     decimals;
  28.   double    dval;
  29.   ulonglong ullval;
  30. } NUM_INFO;
  31. typedef struct st_extreme_value_number_info
  32. {
  33.   ulonglong ullval;
  34.   longlong  llval;
  35.   double    max_dval, min_dval;
  36. } EV_NUM_INFO;
  37. typedef struct st_tree_info
  38. {
  39.   bool  found;
  40.   String *str;
  41.   Item  *item;
  42. } TREE_INFO;
  43. uint check_ulonglong(const char *str, uint length);
  44. bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num);
  45. bool test_if_number(NUM_INFO *info, const char *str, uint str_len);
  46. int compare_double(const double *s, const double *t);
  47. int compare_longlong(const longlong *s, const longlong *t);
  48. int compare_ulonglong(const ulonglong *s, const ulonglong *t);
  49. Procedure *proc_analyse_init(THD *thd, ORDER *param, select_result *result,
  50.      List<Item> &field_list);
  51. void free_string(String*);
  52. class analyse;
  53. class field_info :public Sql_alloc
  54. {
  55. protected:
  56.   ulong   treemem, tree_elements, empty, nulls, min_length, max_length;
  57.   uint   room_in_tree;
  58.   my_bool found;
  59.   TREE   tree;
  60.   Item   *item;
  61.   analyse *pc;
  62. public:
  63.   field_info(Item* a, analyse* b) : treemem(0), tree_elements(0), empty(0),
  64.     nulls(0), min_length(0), max_length(0), room_in_tree(1),
  65.     found(0),item(a), pc(b) {};
  66.   virtual ~field_info() { delete_tree(&tree); }
  67.   virtual void  add() = 0;
  68.   virtual void  get_opt_type(String*, ha_rows) = 0;
  69.   virtual String *get_min_arg(String *) = 0;
  70.   virtual String *get_max_arg(String *) = 0;
  71.   virtual String *avg(String*, ha_rows) = 0;
  72.   virtual String *std(String*, ha_rows) = 0;
  73.   virtual tree_walk_action collect_enum() = 0;
  74.   virtual uint decimals() { return 0; }
  75.   friend  class analyse;
  76. };
  77. int collect_string(String *element, element_count count,
  78.    TREE_INFO *info);
  79. class field_str :public field_info
  80. {
  81.   String      min_arg, max_arg;
  82.   ulonglong   sum;
  83.   bool       must_be_blob, was_zero_fill, was_maybe_zerofill,
  84.       can_be_still_num;
  85.   NUM_INFO    num_info;
  86.   EV_NUM_INFO ev_num_info;
  87. public:
  88.   field_str(Item* a, analyse* b) :field_info(a,b), min_arg(""),
  89.     max_arg(""), sum(0),
  90.     must_be_blob(0), was_zero_fill(0),
  91.     was_maybe_zerofill(0), can_be_still_num(1)
  92.     { init_tree(&tree, 0, sizeof(String), a->binary ?
  93. (qsort_cmp) stringcmp : (qsort_cmp) sortcmp,
  94. 0, (void (*)(void*)) free_string); };
  95.   void  add();
  96.   void  get_opt_type(String*, ha_rows);
  97.   String *get_min_arg(String *not_used __attribute__((unused)))
  98.   { return &min_arg; }
  99.   String *get_max_arg(String *not_used __attribute__((unused)))
  100.   { return &max_arg; }
  101.   String *avg(String *s, ha_rows rows)
  102.   {
  103.     if (!(rows - nulls))
  104.       s->set((double) 0.0, 1);
  105.     else
  106.       s->set((ulonglong2double(sum) / ulonglong2double(rows - nulls)),
  107.      DEC_IN_AVG);
  108.     return s;
  109.   }
  110.   friend int collect_string(String *element, element_count count,
  111.     TREE_INFO *info);
  112.   tree_walk_action collect_enum()
  113.   { return (tree_walk_action) collect_string; }
  114.   String *std(String *s __attribute__((unused)),
  115.       ha_rows rows __attribute__((unused)))
  116.   { return (String*) 0; }
  117. };
  118. int collect_real(double *element, element_count count, TREE_INFO *info);
  119. class field_real: public field_info
  120. {
  121.   double min_arg, max_arg;
  122.   double sum, sum_sqr;
  123.   uint  max_notzero_dec_len;
  124. public:
  125.   field_real(Item* a, analyse* b) :field_info(a,b),
  126.     min_arg(0), max_arg(0),  sum(0), sum_sqr(0), max_notzero_dec_len(0)
  127.     { init_tree(&tree, 0, sizeof(double),
  128. (qsort_cmp) compare_double, 0, NULL); }
  129.   void  add();
  130.   void  get_opt_type(String*, ha_rows);
  131.   String *get_min_arg(String *s) { s->set(min_arg, item->decimals); return s; }
  132.   String *get_max_arg(String *s) { s->set(max_arg, item->decimals); return s; }
  133.   String *avg(String *s, ha_rows rows)
  134.   {
  135.     if (!(rows - nulls))
  136.       s->set((double) 0.0, 1);
  137.     else
  138.       s->set(((double)sum / (double) (rows - nulls)), item->decimals);
  139.     return s;
  140.   }
  141.   String *std(String *s, ha_rows rows)
  142.   {
  143.     double tmp = ulonglong2double(rows);
  144.     if (!(tmp - nulls))
  145.       s->set((double) 0.0, 1);
  146.     else
  147.     {
  148.       double tmp2 = ((sum_sqr - sum * sum / (tmp - nulls)) /
  149.      (tmp - nulls));
  150.       s->set(((double) tmp2 <= 0.0 ? 0.0 : sqrt(tmp2)), item->decimals);
  151.     }
  152.     return s;
  153.   }
  154.   uint  decimals() { return item->decimals; }
  155.   friend int collect_real(double *element, element_count count,
  156.   TREE_INFO *info);
  157.   tree_walk_action collect_enum()
  158.   { return (tree_walk_action) collect_real;}
  159. };
  160. int collect_longlong(longlong *element, element_count count,
  161.      TREE_INFO *info);
  162. class field_longlong: public field_info
  163. {
  164.   longlong min_arg, max_arg;
  165.   longlong sum, sum_sqr;
  166. public:
  167.   field_longlong(Item* a, analyse* b) :field_info(a,b), 
  168.     min_arg(0), max_arg(0), sum(0), sum_sqr(0)
  169.     { init_tree(&tree, 0, sizeof(longlong),
  170. (qsort_cmp) compare_longlong, 0, NULL); }
  171.   void  add();
  172.   void  get_opt_type(String*, ha_rows);
  173.   String *get_min_arg(String *s) { s->set(min_arg); return s; }
  174.   String *get_max_arg(String *s) { s->set(max_arg); return s; }
  175.   String *avg(String *s, ha_rows rows)
  176.   {
  177.     if (!(rows - nulls))
  178.       s->set((double) 0.0, 1);
  179.     else
  180.       s->set(((double) sum / (double) (rows - nulls)), DEC_IN_AVG);
  181.     return s;
  182.   }
  183.   String *std(String *s, ha_rows rows)
  184.   {
  185.     double tmp = ulonglong2double(rows);
  186.     if (!(tmp - nulls))
  187.       s->set((double) 0.0, 1);
  188.     else
  189.     {
  190.       double tmp2 = ((sum_sqr - sum * sum / (tmp - nulls)) /
  191.     (tmp - nulls));
  192.       s->set(((double) tmp2 <= 0.0 ? 0.0 : sqrt(tmp2)), DEC_IN_AVG);
  193.     }
  194.     return s;
  195.   }
  196.   friend int collect_longlong(longlong *element, element_count count,
  197.       TREE_INFO *info);
  198.   tree_walk_action collect_enum()
  199.   { return (tree_walk_action) collect_longlong;}
  200. };
  201. int collect_ulonglong(ulonglong *element, element_count count,
  202.       TREE_INFO *info);
  203. class field_ulonglong: public field_info
  204. {
  205.   ulonglong min_arg, max_arg;
  206.   ulonglong sum, sum_sqr;
  207. public:
  208.   field_ulonglong(Item* a, analyse * b) :field_info(a,b),
  209.     min_arg(0), max_arg(0), sum(0),sum_sqr(0)
  210.     { init_tree(&tree, 0, sizeof(ulonglong),
  211. (qsort_cmp) compare_ulonglong, 0, NULL); }
  212.   void  add();
  213.   void  get_opt_type(String*, ha_rows);
  214.   String *get_min_arg(String *s) { s->set(min_arg); return s; }
  215.   String *get_max_arg(String *s) { s->set(max_arg); return s; }
  216.   String *avg(String *s, ha_rows rows)
  217.   {
  218.     if (!(rows - nulls))
  219.       s->set((double) 0.0, 1);
  220.     else
  221.       s->set((ulonglong2double(sum) / ulonglong2double(rows - nulls)),
  222.      DEC_IN_AVG);
  223.     return s;
  224.   }
  225.   String *std(String *s, ha_rows rows)
  226.   {
  227.     double tmp = ulonglong2double(rows);
  228.     if (!(tmp - nulls))
  229.       s->set((double) 0.0, 1);
  230.     else
  231.     {
  232.       double tmp2 = ((ulonglong2double(sum_sqr) - 
  233.      ulonglong2double(sum * sum) / (tmp - nulls)) /
  234.      (tmp - nulls));
  235.       s->set(((double) tmp2 <= 0.0 ? 0.0 : sqrt(tmp2)), DEC_IN_AVG);
  236.     }
  237.     return s;
  238.   }
  239.   friend int collect_ulonglong(ulonglong *element, element_count count,
  240.        TREE_INFO *info);
  241.   tree_walk_action collect_enum()
  242.   { return (tree_walk_action) collect_ulonglong; }
  243. };
  244. Procedure *proc_analyse_init(THD *thd, ORDER *param,
  245.      select_result *result,
  246.      List<Item> &field_list);
  247. class analyse: public Procedure
  248. {
  249. protected:
  250.   Item_proc    *func_items[10];
  251.   List<Item>   fields, result_fields;
  252.   field_info   **f_info, **f_end;
  253.   ha_rows      rows;
  254.   uint        output_str_length;
  255. public:
  256.   uint max_tree_elements, max_treemem;
  257.   analyse(select_result *res) :Procedure(res, PROC_NO_SORT), rows(0),
  258.     output_str_length(0) {}
  259.   ~analyse()
  260.   { 
  261.     for (field_info **f=f_info; f != f_end; f++)
  262.       delete (*f);
  263.   }
  264.   virtual void add() {}
  265.   virtual bool change_columns(List<Item> &fields);
  266.   virtual int  send_row(List<Item> &fields);
  267.   virtual void end_group(void) {}
  268.   virtual bool end_of_records(void);
  269.   friend Procedure *proc_analyse_init(THD *thd, ORDER *param,
  270.       select_result *result,
  271.       List<Item> &field_list);
  272. };