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_cmpfunc.h < prev    next >
C/C++ Source or Header  |  2000-08-31  |  15KB  |  568 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. /* compare and test functions */
  19.  
  20. #ifdef __GNUC__
  21. #pragma interface            /* gcc class implementation */
  22. #endif
  23.  
  24. class Item_bool_func :public Item_int_func
  25. {
  26. public:
  27.   Item_bool_func() :Item_int_func() {}
  28.   Item_bool_func(Item *a) :Item_int_func(a) {}
  29.   Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
  30.   void fix_length_and_dec() { decimals=0; max_length=1; }
  31. };
  32.  
  33. class Item_bool_func2 :public Item_int_func
  34. {                        /* Bool with 2 string args */
  35. protected:
  36.   String tmp_value1,tmp_value2;
  37. public:
  38.   Item_bool_func2(Item *a,Item *b) :Item_int_func(a,b) {}
  39.   void fix_length_and_dec();
  40.   void set_cmp_func(Item_result type);
  41.   int (Item_bool_func2::*cmp_func)();
  42.   int compare_string();                /* compare arg[0] & arg[1] */
  43.   int compare_real();                /* compare arg[0] & arg[1] */
  44.   int compare_int();                /* compare arg[0] & arg[1] */
  45.   optimize_type select_optimize() const { return OPTIMIZE_OP; }
  46.   virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
  47.   bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
  48.   void print(String *str) { Item_func::print_op(str); }
  49. };
  50.  
  51.  
  52. class Item_func_not :public Item_bool_func
  53. {
  54. public:
  55.   Item_func_not(Item *a) :Item_bool_func(a) {}
  56.   longlong val_int();
  57.   const char *func_name() const { return "not"; }
  58. };
  59.  
  60. class Item_func_eq :public Item_bool_func2
  61. {
  62. public:
  63.   Item_func_eq(Item *a,Item *b) :Item_bool_func2(a,b) { };
  64.   longlong val_int();
  65.   enum Functype functype() const { return EQ_FUNC; }
  66.   enum Functype rev_functype() const { return EQ_FUNC; }
  67.   cond_result eq_cmp_result() const { return COND_TRUE; }
  68.   const char *func_name() const { return "="; }
  69. };
  70.  
  71. class Item_func_equal :public Item_bool_func2
  72. {
  73. public:
  74.   Item_func_equal(Item *a,Item *b) :Item_bool_func2(a,b) { };
  75.   longlong val_int();
  76.   void fix_length_and_dec()
  77.   { Item_bool_func2::fix_length_and_dec() ; maybe_null=0; }
  78.   enum Functype functype() const { return EQUAL_FUNC; }
  79.   enum Functype rev_functype() const { return EQUAL_FUNC; }
  80.   cond_result eq_cmp_result() const { return COND_TRUE; }
  81.   const char *func_name() const { return "<=>"; }
  82. };
  83.  
  84.  
  85. class Item_func_ge :public Item_bool_func2
  86. {
  87. public:
  88.   Item_func_ge(Item *a,Item *b) :Item_bool_func2(a,b) { };
  89.   longlong val_int();
  90.   enum Functype functype() const { return GE_FUNC; }
  91.   enum Functype rev_functype() const { return LE_FUNC; }
  92.   cond_result eq_cmp_result() const { return COND_TRUE; }
  93.   const char *func_name() const { return ">="; }
  94. };
  95.  
  96.  
  97. class Item_func_gt :public Item_bool_func2
  98. {
  99. public:
  100.   Item_func_gt(Item *a,Item *b) :Item_bool_func2(a,b) { };
  101.   longlong val_int();
  102.   enum Functype functype() const { return GT_FUNC; }
  103.   enum Functype rev_functype() const { return LT_FUNC; }
  104.   cond_result eq_cmp_result() const { return COND_FALSE; }
  105.   const char *func_name() const { return ">"; }
  106. };
  107.  
  108.  
  109. class Item_func_le :public Item_bool_func2
  110. {
  111. public:
  112.   Item_func_le(Item *a,Item *b) :Item_bool_func2(a,b) { };
  113.   longlong val_int();
  114.   enum Functype functype() const { return LE_FUNC; }
  115.   enum Functype rev_functype() const { return GE_FUNC; }
  116.   cond_result eq_cmp_result() const { return COND_TRUE; }
  117.   const char *func_name() const { return "<="; }
  118. };
  119.  
  120.  
  121. class Item_func_lt :public Item_bool_func2
  122. {
  123. public:
  124.   Item_func_lt(Item *a,Item *b) :Item_bool_func2(a,b) { }
  125.   longlong val_int();
  126.   enum Functype functype() const { return LT_FUNC; }
  127.   enum Functype rev_functype() const { return GT_FUNC; }
  128.   cond_result eq_cmp_result() const { return COND_FALSE; }
  129.   const char *func_name() const { return "<"; }
  130. };
  131.  
  132.  
  133. class Item_func_ne :public Item_bool_func2
  134. {
  135. public:
  136.   Item_func_ne(Item *a,Item *b) :Item_bool_func2(a,b) { }
  137.   longlong val_int();
  138.   enum Functype functype() const { return NE_FUNC; }
  139.   cond_result eq_cmp_result() const { return COND_FALSE; }
  140.   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
  141.   const char *func_name() const { return "<>"; }
  142. };
  143.  
  144.  
  145. class Item_func_between :public Item_int_func
  146. {
  147.   int (*string_compare)(const String *x,const String *y);
  148. public:
  149.   Item_result cmp_type;
  150.   String value0,value1,value2;
  151.   Item_func_between(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
  152.   longlong val_int();
  153.   optimize_type select_optimize() const { return OPTIMIZE_KEY; }
  154.   enum Functype functype() const   { return BETWEEN; }
  155.   const char *func_name() const { return "between"; }
  156.   void fix_length_and_dec();
  157. };
  158.  
  159.  
  160. class Item_func_strcmp :public Item_bool_func2
  161. {
  162. public:
  163.   Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
  164.   longlong val_int();
  165.   void fix_length_and_dec() { max_length=2; }
  166.   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
  167.   const char *func_name() const { return "strcmp"; }
  168. };
  169.  
  170.  
  171. class Item_func_interval :public Item_int_func
  172. {
  173.   Item *item;
  174.   double *intervals;
  175. public:
  176.   Item_func_interval(Item *a,List<Item> &list)
  177.     :Item_int_func(list),item(a),intervals(0) {}
  178.   longlong val_int();
  179.   bool fix_fields(THD *thd,struct st_table_list *tlist)
  180.   {
  181.     return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
  182.   }
  183.   void fix_length_and_dec();
  184.   ~Item_func_interval() { delete item; }
  185.   const char *func_name() const { return "interval"; }
  186.   void update_used_tables();
  187. };
  188.  
  189.  
  190. class Item_func_ifnull :public Item_func
  191. {
  192.   enum Item_result cached_result_type;
  193. public:
  194.   Item_func_ifnull(Item *a,Item *b) :Item_func(a,b) { }
  195.   double val();
  196.   longlong val_int();
  197.   String *val_str(String *str);
  198.   enum Item_result result_type () const { return cached_result_type; }
  199.   void fix_length_and_dec();
  200.   const char *func_name() const { return "ifnull"; }
  201. };
  202.  
  203.  
  204. class Item_func_if :public Item_func
  205. {
  206.   enum Item_result cached_result_type;
  207. public:
  208.   Item_func_if(Item *a,Item *b,Item *c) :Item_func(a,b,c) { }
  209.   double val();
  210.   longlong val_int();
  211.   String *val_str(String *str);
  212.   enum Item_result result_type () const { return cached_result_type; }
  213.   void fix_length_and_dec();
  214.   const char *func_name() const { return "if"; }
  215. };
  216.  
  217.  
  218. class Item_func_nullif :public Item_bool_func2
  219. {
  220.   enum Item_result cached_result_type;
  221. public:
  222.   Item_func_nullif(Item *a,Item *b) :Item_bool_func2(a,b) { }
  223.   double val();
  224.   longlong val_int();
  225.   String *val_str(String *str);
  226.   enum Item_result result_type () const { return cached_result_type; }
  227.   void fix_length_and_dec();
  228.   const char *func_name() const { return "nullif"; }
  229. };
  230.  
  231.  
  232. class Item_func_coalesce :public Item_func
  233. {
  234.   enum Item_result cached_result_type;
  235. public:
  236.   Item_func_coalesce(List<Item> &list) :Item_func(list) {}
  237.   double val();
  238.   longlong val_int();
  239.   String *val_str(String *);
  240.   void fix_length_and_dec();
  241.   enum Item_result result_type () const { return cached_result_type; }
  242.   const char *func_name() const { return "coalesce"; }
  243. };
  244.  
  245. class Item_func_case :public Item_func
  246. {
  247.   Item * first_expr, *else_expr;
  248.   enum Item_result cached_result_type;
  249.   String tmp_value;
  250. public:
  251.   Item_func_case(List<Item> &list, Item *first_expr_, Item *else_expr_)
  252.     :Item_func(list), first_expr(first_expr_), else_expr(else_expr_) {}
  253.   double val();
  254.   longlong val_int();
  255.   String *val_str(String *);
  256.   void fix_length_and_dec();
  257.   enum Item_result result_type () const { return cached_result_type; }
  258.   const char *func_name() const { return "case"; }
  259.   void print(String *str);
  260.   bool fix_fields(THD *thd,struct st_table_list *tlist);
  261.   Item *find_item(String *str);
  262. };
  263.  
  264.  
  265. /* Functions to handle the optimized IN */
  266.  
  267. class in_vector :public Sql_alloc
  268. {
  269.  protected:
  270.   char *base;
  271.   uint size;
  272.   qsort_cmp compare;
  273.   uint count;
  274. public:
  275.   uint used_count;
  276.   in_vector(uint elements,uint element_length,qsort_cmp cmp_func)
  277.     :base((char*) sql_calloc(elements*element_length)),
  278.      size(element_length), compare(cmp_func), count(elements),
  279.      used_count(elements) {}
  280.   virtual ~in_vector() {}
  281.   virtual void set(uint pos,Item *item)=0;
  282.   virtual byte *get_value(Item *item)=0;
  283.   void sort()
  284.     {
  285.       qsort(base,used_count,size,compare);
  286.     }
  287.   int find(Item *item);
  288. };
  289.  
  290.  
  291. class in_string :public in_vector
  292. {
  293.   char buff[80];
  294.   String tmp;
  295. public:
  296.   in_string(uint elements,qsort_cmp cmp_func);
  297.   ~in_string();
  298.   void set(uint pos,Item *item);
  299.   byte *get_value(Item *item);
  300. };
  301.  
  302.  
  303. class in_longlong :public in_vector
  304. {
  305.   longlong tmp;
  306. public:
  307.   in_longlong(uint elements);
  308.   void set(uint pos,Item *item);
  309.   byte *get_value(Item *item);
  310. };
  311.  
  312.  
  313. class in_double :public in_vector
  314. {
  315.   double tmp;
  316. public:
  317.   in_double(uint elements);
  318.   void set(uint pos,Item *item);
  319.   byte *get_value(Item *item);
  320. };
  321.  
  322.  
  323. /*
  324. ** Classes for easy comparing of non const items
  325. */
  326.  
  327. class cmp_item :public Sql_alloc
  328. {
  329. public:
  330.   cmp_item() {}
  331.   virtual ~cmp_item() {}
  332.   virtual void store_value(Item *item)=0;
  333.   virtual int cmp(Item *item)=0;
  334. };
  335.  
  336.  
  337. class cmp_item_sort_string :public cmp_item {
  338.  protected:
  339.   char value_buff[80];
  340.   String value,*value_res;
  341. public:
  342.   cmp_item_sort_string() :value(value_buff,sizeof(value_buff)) {}
  343.   void store_value(Item *item)
  344.     {
  345.       value_res=item->val_str(&value);
  346.     }
  347.   int cmp(Item *arg)
  348.     {
  349.       char buff[80];
  350.       String tmp(buff,sizeof(buff)),*res;
  351.       if (!(res=arg->val_str(&tmp)))
  352.     return 1;                /* Can't be right */
  353.       return sortcmp(value_res,res);
  354.     }
  355. };
  356.  
  357. class cmp_item_binary_string :public cmp_item_sort_string {
  358. public:
  359.   cmp_item_binary_string() {}
  360.   int cmp(Item *arg)
  361.     {
  362.       char buff[80];
  363.       String tmp(buff,sizeof(buff)),*res;
  364.       if (!(res=arg->val_str(&tmp)))
  365.     return 1;                /* Can't be right */
  366.       return stringcmp(value_res,res);
  367.     }
  368. };
  369.  
  370.  
  371. class cmp_item_int :public cmp_item
  372. {
  373.   longlong value;
  374. public:
  375.   void store_value(Item *item)
  376.     {
  377.       value=item->val_int();
  378.     }
  379.   int cmp(Item *arg)
  380.     {
  381.       return value != arg->val_int();
  382.     }
  383. };
  384.  
  385.  
  386. class cmp_item_real :public cmp_item
  387. {
  388.   double value;
  389. public:
  390.   void store_value(Item *item)
  391.     {
  392.       value= item->val();
  393.     }
  394.   int cmp(Item *arg)
  395.     {
  396.       return value != arg->val();
  397.     }
  398. };
  399.  
  400.  
  401. class Item_func_in :public Item_int_func
  402. {
  403.   Item *item;
  404.   in_vector *array;
  405.   cmp_item *in_item;
  406.  public:
  407.   Item_func_in(Item *a,List<Item> &list)
  408.     :Item_int_func(list),item(a),array(0),in_item(0) {}
  409.   longlong val_int();
  410.   bool fix_fields(THD *thd,struct st_table_list *tlist)
  411.   {
  412.     return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
  413.   }
  414.   void fix_length_and_dec();
  415.   ~Item_func_in() { delete item; delete array; delete in_item; }
  416.   optimize_type select_optimize() const
  417.     { return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; }
  418.   Item *key_item() const { return item; }
  419.   void print(String *str);
  420.   enum Functype functype() const { return IN_FUNC; }
  421.   const char *func_name() const { return " IN "; }
  422.   void update_used_tables();
  423. };
  424.  
  425.  
  426.  
  427. /* Functions used by where clause */
  428.  
  429. class Item_func_isnull :public Item_bool_func
  430. {
  431. public:
  432.   Item_func_isnull(Item *a) :Item_bool_func(a) {}
  433.   longlong val_int();
  434.   enum Functype functype() const { return ISNULL_FUNC; }
  435.   void fix_length_and_dec()
  436.   {
  437.     decimals=0; max_length=1; maybe_null=0;
  438.     Item_func_isnull::update_used_tables();
  439.   }
  440.   const char *func_name() const { return "isnull"; }
  441.   /* Optimize case of not_null_column IS NULL */
  442.   void update_used_tables()
  443.   {
  444.     if (!args[0]->maybe_null)
  445.       used_tables_cache=0;            /* is always false */
  446.     else
  447.     {
  448.       args[0]->update_used_tables();
  449.       used_tables_cache=args[0]->used_tables();
  450.     }
  451.   }
  452.   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
  453. };
  454.  
  455. class Item_func_isnotnull :public Item_bool_func
  456. {
  457. public:
  458.   Item_func_isnotnull(Item *a) :Item_bool_func(a) {}
  459.   longlong val_int();
  460.   enum Functype functype() const { return ISNOTNULL_FUNC; }
  461.   void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
  462.   const char *func_name() const { return "isnotnull"; }
  463.   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
  464. };
  465.  
  466. class Item_func_like :public Item_bool_func2
  467. {
  468.   char escape;
  469. public:
  470.   Item_func_like(Item *a,Item *b, char* escape_arg) :Item_bool_func2(a,b),escape(*escape_arg)
  471.   {}
  472.   longlong val_int();
  473.   enum Functype functype() const { return LIKE_FUNC; }
  474.   optimize_type select_optimize() const;
  475.   cond_result eq_cmp_result() const { return COND_TRUE; }
  476.   const char *func_name() const { return "like"; }
  477.   void fix_length_and_dec();
  478. };
  479.  
  480. #ifdef USE_REGEX
  481.  
  482. #include <regex.h>
  483.  
  484. class Item_func_regex :public Item_bool_func
  485. {
  486.   regex_t preg;
  487.   bool regex_compiled;
  488.   bool regex_is_const;
  489.   String prev_regexp;
  490. public:
  491.   Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
  492.     regex_compiled(0),regex_is_const(0) {}
  493.   ~Item_func_regex();
  494.   longlong val_int();
  495.   bool fix_fields(THD *thd,struct st_table_list *tlist);
  496.   const char *func_name() const { return "regex"; }
  497. };
  498.  
  499. #else
  500.  
  501. class Item_func_regex :public Item_bool_func
  502. {
  503. public:
  504.   Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b) {}
  505.   longlong val_int() { return 0;}
  506.   const char *func_name() const { return "regex"; }
  507. };
  508.  
  509. #endif /* USE_REGEX */
  510.  
  511.  
  512. typedef class Item COND;
  513.  
  514. class Item_cond :public Item_bool_func
  515. {
  516. protected:
  517.   List<Item> list;
  518. public:
  519.   Item_cond() : Item_bool_func() { const_item_cache=0; }
  520.   Item_cond(Item *i1,Item *i2) :Item_bool_func()
  521.     { list.push_back(i1); list.push_back(i2); }
  522.   ~Item_cond() { list.delete_elements(); }
  523.   bool add(Item *item) { return list.push_back(item); }
  524.   bool fix_fields(THD *,struct st_table_list *);
  525.  
  526.   enum Type type() const { return COND_ITEM; }
  527.   List<Item>* argument_list() { return &list; }
  528.   table_map used_tables() const;
  529.   void update_used_tables();
  530.   void print(String *str);
  531.   void split_sum_func(List<Item> &fields);
  532.   friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
  533. };
  534.  
  535.  
  536. class Item_cond_and :public Item_cond
  537. {
  538. public:
  539.   Item_cond_and() :Item_cond() {}
  540.   Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
  541.   enum Functype functype() const { return COND_AND_FUNC; }
  542.   longlong val_int();
  543.   const char *func_name() const { return "and"; }
  544. };
  545.  
  546. class Item_cond_or :public Item_cond
  547. {
  548. public:
  549.   Item_cond_or() :Item_cond() {}
  550.   Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
  551.   enum Functype functype() const { return COND_OR_FUNC; }
  552.   longlong val_int();
  553.   const char *func_name() const { return "or"; }
  554. };
  555.  
  556.  
  557. /* Some usefull inline functions */
  558.  
  559. inline Item *and_conds(Item *a,Item *b)
  560. {
  561.   if (!b) return a;
  562.   if (!a) return b;
  563.   Item *cond=new Item_cond_and(a,b);
  564.   if (cond)
  565.     cond->update_used_tables();
  566.   return cond;
  567. }
  568.