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