sql_analyse.h
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* Analyse database */
  14. #ifdef USE_PRAGMA_INTERFACE
  15. #pragma interface /* gcc class implementation */
  16. #endif
  17. #define my_thd_charset default_charset_info
  18. #define DEC_IN_AVG 4
  19. typedef struct st_number_info
  20. {
  21.   // if zerofill is true, the number must be zerofill, or string
  22.   bool     negative, is_float, zerofill, maybe_zerofill;
  23.   int8     integers;
  24.   int8     decimals;
  25.   double    dval;
  26.   ulonglong ullval;
  27. } NUM_INFO;
  28. typedef struct st_extreme_value_number_info
  29. {
  30.   ulonglong ullval;
  31.   longlong  llval;
  32.   double    max_dval, min_dval;
  33. } EV_NUM_INFO;
  34. typedef struct st_tree_info
  35. {
  36.   bool  found;
  37.   String *str;
  38.   Item  *item;
  39. } TREE_INFO;
  40. uint check_ulonglong(const char *str, uint length);
  41. bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num);
  42. bool test_if_number(NUM_INFO *info, const char *str, uint str_len);
  43. int compare_double(const double *s, const double *t);
  44. int compare_double2(void* cmp_arg __attribute__((unused)),
  45.     const double *s, const double *t);
  46. int compare_longlong(const longlong *s, const longlong *t);
  47. int compare_longlong2(void* cmp_arg __attribute__((unused)),
  48.       const longlong *s, const longlong *t);
  49. int compare_ulonglong(const ulonglong *s, const ulonglong *t);
  50. int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
  51.        const ulonglong *s, const ulonglong *t);
  52. Procedure *proc_analyse_init(THD *thd, ORDER *param, select_result *result,
  53.      List<Item> &field_list);
  54. void free_string(String*);
  55. class analyse;
  56. class field_info :public Sql_alloc
  57. {
  58. protected:
  59.   ulong   treemem, tree_elements, empty, nulls, min_length, max_length;
  60.   uint   room_in_tree;
  61.   my_bool found;
  62.   TREE   tree;
  63.   Item   *item;
  64.   analyse *pc;
  65. public:
  66.   field_info(Item* a, analyse* b) : treemem(0), tree_elements(0), empty(0),
  67.     nulls(0), min_length(0), max_length(0), room_in_tree(1),
  68.     found(0),item(a), pc(b) {};
  69.   virtual ~field_info() { delete_tree(&tree); }
  70.   virtual void  add() = 0;
  71.   virtual void  get_opt_type(String*, ha_rows) = 0;
  72.   virtual String *get_min_arg(String *) = 0;
  73.   virtual String *get_max_arg(String *) = 0;
  74.   virtual String *avg(String*, ha_rows) = 0;
  75.   virtual String *std(String*, ha_rows) = 0;
  76.   virtual tree_walk_action collect_enum() = 0;
  77.   virtual uint decimals() { return 0; }
  78.   friend  class analyse;
  79. };
  80. int collect_string(String *element, element_count count,
  81.    TREE_INFO *info);
  82. int sortcmp2(void* cmp_arg __attribute__((unused)),
  83.      const String *a,const String *b);
  84. class field_str :public field_info
  85. {
  86.   String      min_arg, max_arg;
  87.   ulonglong   sum;
  88.   bool       must_be_blob, was_zero_fill, was_maybe_zerofill,
  89.       can_be_still_num;
  90.   NUM_INFO    num_info;
  91.   EV_NUM_INFO ev_num_info;
  92. public:
  93.   field_str(Item* a, analyse* b) :field_info(a,b), 
  94.     min_arg("",default_charset_info),
  95.     max_arg("",default_charset_info), sum(0),
  96.     must_be_blob(0), was_zero_fill(0),
  97.     was_maybe_zerofill(0), can_be_still_num(1)
  98.     { init_tree(&tree, 0, 0, sizeof(String), (qsort_cmp2) sortcmp2,
  99. 0, (tree_element_free) free_string, NULL); };
  100.   void  add();
  101.   void  get_opt_type(String*, ha_rows);
  102.   String *get_min_arg(String *not_used __attribute__((unused)))
  103.   { return &min_arg; }
  104.   String *get_max_arg(String *not_used __attribute__((unused)))
  105.   { return &max_arg; }
  106.   String *avg(String *s, ha_rows rows)
  107.   {
  108.     if (!(rows - nulls))
  109.       s->set((double) 0.0, 1,my_thd_charset);
  110.     else
  111.       s->set((ulonglong2double(sum) / ulonglong2double(rows - nulls)),
  112.      DEC_IN_AVG,my_thd_charset);
  113.     return s;
  114.   }
  115.   friend int collect_string(String *element, element_count count,
  116.     TREE_INFO *info);
  117.   tree_walk_action collect_enum()
  118.   { return (tree_walk_action) collect_string; }
  119.   String *std(String *s __attribute__((unused)),
  120.       ha_rows rows __attribute__((unused)))
  121.   { return (String*) 0; }
  122. };
  123. int collect_real(double *element, element_count count, TREE_INFO *info);
  124. class field_real: public field_info
  125. {
  126.   double min_arg, max_arg;
  127.   double sum, sum_sqr;
  128.   uint  max_notzero_dec_len;
  129. public:
  130.   field_real(Item* a, analyse* b) :field_info(a,b),
  131.     min_arg(0), max_arg(0),  sum(0), sum_sqr(0), max_notzero_dec_len(0)
  132.     { init_tree(&tree, 0, 0, sizeof(double),
  133. (qsort_cmp2) compare_double2, 0, NULL, NULL); }
  134.   void  add();
  135.   void  get_opt_type(String*, ha_rows);
  136.   String *get_min_arg(String *s) 
  137.   { 
  138.     s->set(min_arg, item->decimals,my_thd_charset); 
  139.     return s; 
  140.   }
  141.   String *get_max_arg(String *s) 
  142.   { 
  143.     s->set(max_arg, item->decimals,my_thd_charset);
  144.     return s; 
  145.   }
  146.   String *avg(String *s, ha_rows rows)
  147.   {
  148.     if (!(rows - nulls))
  149.       s->set((double) 0.0, 1,my_thd_charset);
  150.     else
  151.       s->set(((double)sum / (double) (rows - nulls)), item->decimals,my_thd_charset);
  152.     return s;
  153.   }
  154.   String *std(String *s, ha_rows rows)
  155.   {
  156.     double tmp = ulonglong2double(rows);
  157.     if (!(tmp - nulls))
  158.       s->set((double) 0.0, 1,my_thd_charset);
  159.     else
  160.     {
  161.       double tmp2 = ((sum_sqr - sum * sum / (tmp - nulls)) /
  162.      (tmp - nulls));
  163.       s->set(((double) tmp2 <= 0.0 ? 0.0 : sqrt(tmp2)), item->decimals,my_thd_charset);
  164.     }
  165.     return s;
  166.   }
  167.   uint  decimals() { return item->decimals; }
  168.   friend int collect_real(double *element, element_count count,
  169.   TREE_INFO *info);
  170.   tree_walk_action collect_enum()
  171.   { return (tree_walk_action) collect_real;}
  172. };
  173. int collect_longlong(longlong *element, element_count count,
  174.      TREE_INFO *info);
  175. class field_longlong: public field_info
  176. {
  177.   longlong min_arg, max_arg;
  178.   longlong sum, sum_sqr;
  179. public:
  180.   field_longlong(Item* a, analyse* b) :field_info(a,b), 
  181.     min_arg(0), max_arg(0), sum(0), sum_sqr(0)
  182.     { init_tree(&tree, 0, 0, sizeof(longlong),
  183. (qsort_cmp2) compare_longlong2, 0, NULL, NULL); }
  184.   void  add();
  185.   void  get_opt_type(String*, ha_rows);
  186.   String *get_min_arg(String *s) { s->set(min_arg,my_thd_charset); return s; }
  187.   String *get_max_arg(String *s) { s->set(max_arg,my_thd_charset); return s; }
  188.   String *avg(String *s, ha_rows rows)
  189.   {
  190.     if (!(rows - nulls))
  191.       s->set((double) 0.0, 1,my_thd_charset);
  192.     else
  193.       s->set(((double) sum / (double) (rows - nulls)), DEC_IN_AVG,my_thd_charset);
  194.     return s;
  195.   }
  196.   String *std(String *s, ha_rows rows)
  197.   {
  198.     double tmp = ulonglong2double(rows);
  199.     if (!(tmp - nulls))
  200.       s->set((double) 0.0, 1,my_thd_charset);
  201.     else
  202.     {
  203.       double tmp2 = ((sum_sqr - sum * sum / (tmp - nulls)) /
  204.     (tmp - nulls));
  205.       s->set(((double) tmp2 <= 0.0 ? 0.0 : sqrt(tmp2)), DEC_IN_AVG,my_thd_charset);
  206.     }
  207.     return s;
  208.   }
  209.   friend int collect_longlong(longlong *element, element_count count,
  210.       TREE_INFO *info);
  211.   tree_walk_action collect_enum()
  212.   { return (tree_walk_action) collect_longlong;}
  213. };
  214. int collect_ulonglong(ulonglong *element, element_count count,
  215.       TREE_INFO *info);
  216. class field_ulonglong: public field_info
  217. {
  218.   ulonglong min_arg, max_arg;
  219.   ulonglong sum, sum_sqr;
  220. public:
  221.   field_ulonglong(Item* a, analyse * b) :field_info(a,b),
  222.     min_arg(0), max_arg(0), sum(0),sum_sqr(0)
  223.     { init_tree(&tree, 0, 0, sizeof(ulonglong),
  224. (qsort_cmp2) compare_ulonglong2, 0, NULL, NULL); }
  225.   void  add();
  226.   void  get_opt_type(String*, ha_rows);
  227.   String *get_min_arg(String *s) { s->set(min_arg,my_thd_charset); return s; }
  228.   String *get_max_arg(String *s) { s->set(max_arg,my_thd_charset); return s; }
  229.   String *avg(String *s, ha_rows rows)
  230.   {
  231.     if (!(rows - nulls))
  232.       s->set((double) 0.0, 1,my_thd_charset);
  233.     else
  234.       s->set((ulonglong2double(sum) / ulonglong2double(rows - nulls)),
  235.      DEC_IN_AVG,my_thd_charset);
  236.     return s;
  237.   }
  238.   String *std(String *s, ha_rows rows)
  239.   {
  240.     double tmp = ulonglong2double(rows);
  241.     if (!(tmp - nulls))
  242.       s->set((double) 0.0, 1,my_thd_charset);
  243.     else
  244.     {
  245.       double tmp2 = ((ulonglong2double(sum_sqr) - 
  246.      ulonglong2double(sum * sum) / (tmp - nulls)) /
  247.      (tmp - nulls));
  248.       s->set(((double) tmp2 <= 0.0 ? 0.0 : sqrt(tmp2)), DEC_IN_AVG,my_thd_charset);
  249.     }
  250.     return s;
  251.   }
  252.   friend int collect_ulonglong(ulonglong *element, element_count count,
  253.        TREE_INFO *info);
  254.   tree_walk_action collect_enum()
  255.   { return (tree_walk_action) collect_ulonglong; }
  256. };
  257. Procedure *proc_analyse_init(THD *thd, ORDER *param,
  258.      select_result *result,
  259.      List<Item> &field_list);
  260. class analyse: public Procedure
  261. {
  262. protected:
  263.   Item_proc    *func_items[10];
  264.   List<Item>   fields, result_fields;
  265.   field_info   **f_info, **f_end;
  266.   ha_rows      rows;
  267.   uint        output_str_length;
  268. public:
  269.   uint max_tree_elements, max_treemem;
  270.   analyse(select_result *res) :Procedure(res, PROC_NO_SORT), f_info(0),
  271.     rows(0), output_str_length(0) {}
  272.   ~analyse()
  273.   {
  274.     if (f_info)
  275.     {
  276.       for (field_info **f=f_info; f != f_end; f++)
  277. delete (*f);
  278.     }
  279.   }
  280.   virtual void add() {}
  281.   virtual bool change_columns(List<Item> &fields);
  282.   virtual int  send_row(List<Item> &fields);
  283.   virtual void end_group(void) {}
  284.   virtual bool end_of_records(void);
  285.   friend Procedure *proc_analyse_init(THD *thd, ORDER *param,
  286.       select_result *result,
  287.       List<Item> &field_list);
  288. };