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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000-2003 MySQL 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. /* compare and test functions */
  14. #ifdef USE_PRAGMA_INTERFACE
  15. #pragma interface /* gcc class implementation */
  16. #endif
  17. extern Item_result item_cmp_type(Item_result a,Item_result b);
  18. class Item_bool_func2;
  19. class Arg_comparator;
  20. typedef int (Arg_comparator::*arg_cmp_func)();
  21. class Arg_comparator: public Sql_alloc
  22. {
  23.   Item **a, **b;
  24.   arg_cmp_func func;
  25.   Item_bool_func2 *owner;
  26.   Arg_comparator *comparators;   // used only for compare_row()
  27. public:
  28.   DTCollation cmp_collation;
  29.   Arg_comparator() {};
  30.   Arg_comparator(Item **a1, Item **a2): a(a1), b(a2) {};
  31.   int set_compare_func(Item_bool_func2 *owner, Item_result type);
  32.   inline int set_compare_func(Item_bool_func2 *owner_arg)
  33.   {
  34.     return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
  35.      (*b)->result_type()));
  36.   }
  37.   inline int set_cmp_func(Item_bool_func2 *owner_arg,
  38.   Item **a1, Item **a2,
  39.   Item_result type)
  40.   {
  41.     a= a1;
  42.     b= a2;
  43.     return set_compare_func(owner_arg, type);
  44.   }
  45.   inline int set_cmp_func(Item_bool_func2 *owner_arg,
  46.   Item **a1, Item **a2)
  47.   {
  48.     return set_cmp_func(owner_arg, a1, a2, item_cmp_type((*a1)->result_type(),
  49.  (*a2)->result_type()));
  50.   }
  51.   inline int compare() { return (this->*func)(); }
  52.   int compare_string();  // compare args[0] & args[1]
  53.   int compare_binary_string();  // compare args[0] & args[1]
  54.   int compare_real();            // compare args[0] & args[1]
  55.   int compare_int_signed();      // compare args[0] & args[1]
  56.   int compare_int_signed_unsigned();
  57.   int compare_int_unsigned_signed();
  58.   int compare_int_unsigned();
  59.   int compare_row();             // compare args[0] & args[1]
  60.   int compare_e_string();  // compare args[0] & args[1]
  61.   int compare_e_binary_string(); // compare args[0] & args[1]
  62.   int compare_e_real();          // compare args[0] & args[1]
  63.   int compare_e_int();           // compare args[0] & args[1]
  64.   int compare_e_int_diff_signedness();
  65.   int compare_e_row();           // compare args[0] & args[1]
  66.   static arg_cmp_func comparator_matrix [4][2];
  67.   friend class Item_func;
  68. };
  69. class Item_bool_func :public Item_int_func
  70. {
  71. public:
  72.   Item_bool_func() :Item_int_func() {}
  73.   Item_bool_func(Item *a) :Item_int_func(a) {}
  74.   Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
  75.   Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
  76.   bool is_bool_func() { return 1; }
  77.   void fix_length_and_dec() { decimals=0; max_length=1; }
  78. };
  79. class Item_cache;
  80. class Item_in_optimizer: public Item_bool_func
  81. {
  82. protected:
  83.   Item_cache *cache;
  84.   bool save_cache;
  85. public:
  86.   Item_in_optimizer(Item *a, Item_in_subselect *b):
  87.     Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), save_cache(0)
  88.   {}
  89.   bool fix_fields(THD *, struct st_table_list *, Item **);
  90.   bool fix_left(THD *thd, struct st_table_list *tables, Item **ref);
  91.   bool is_null();
  92.   /*
  93.     Item_in_optimizer item is special boolean function. On value request 
  94.     (one of val, val_int or val_str methods) it evaluate left expression 
  95.     of IN by storing it value in cache item (one of Item_cache* items), 
  96.     then it test cache is it NULL. If left expression (cache) is NULL then
  97.     Item_in_optimizer return NULL, else it evaluate Item_in_subselect.
  98.   */
  99.   longlong val_int();
  100.   void cleanup();
  101.   const char *func_name() const { return "<in_optimizer>"; }
  102.   Item_cache **get_cache() { return &cache; }
  103.   void keep_top_level_cache();
  104. };
  105. class Comp_creator
  106. {
  107. public:
  108.   virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
  109.   virtual const char* symbol(bool invert) const = 0;
  110.   virtual bool eqne_op() const = 0;
  111.   virtual bool l_op() const = 0;
  112. };
  113. class Eq_creator :public Comp_creator
  114. {
  115. public:
  116.   virtual Item_bool_func2* create(Item *a, Item *b) const;
  117.   virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
  118.   virtual bool eqne_op() const { return 1; }
  119.   virtual bool l_op() const { return 0; }
  120. };
  121. class Ne_creator :public Comp_creator
  122. {
  123. public:
  124.   virtual Item_bool_func2* create(Item *a, Item *b) const;
  125.   virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
  126.   virtual bool eqne_op() const { return 1; }
  127.   virtual bool l_op() const { return 0; }
  128. };
  129. class Gt_creator :public Comp_creator
  130. {
  131. public:
  132.   virtual Item_bool_func2* create(Item *a, Item *b) const;
  133.   virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
  134.   virtual bool eqne_op() const { return 0; }
  135.   virtual bool l_op() const { return 0; }
  136. };
  137. class Lt_creator :public Comp_creator
  138. {
  139. public:
  140.   virtual Item_bool_func2* create(Item *a, Item *b) const;
  141.   virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
  142.   virtual bool eqne_op() const { return 0; }
  143.   virtual bool l_op() const { return 1; }
  144. };
  145. class Ge_creator :public Comp_creator
  146. {
  147. public:
  148.   virtual Item_bool_func2* create(Item *a, Item *b) const;
  149.   virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
  150.   virtual bool eqne_op() const { return 0; }
  151.   virtual bool l_op() const { return 0; }
  152. };
  153. class Le_creator :public Comp_creator
  154. {
  155. public:
  156.   virtual Item_bool_func2* create(Item *a, Item *b) const;
  157.   virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
  158.   virtual bool eqne_op() const { return 0; }
  159.   virtual bool l_op() const { return 1; }
  160. };
  161. class Item_bool_func2 :public Item_int_func
  162. { /* Bool with 2 string args */
  163. protected:
  164.   Arg_comparator cmp;
  165.   String tmp_value1,tmp_value2;
  166. public:
  167.   Item_bool_func2(Item *a,Item *b)
  168.     :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1) {}
  169.   void fix_length_and_dec();
  170.   void set_cmp_func()
  171.   {
  172.     cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
  173.   }
  174.   optimize_type select_optimize() const { return OPTIMIZE_OP; }
  175.   virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
  176.   bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
  177.   void print(String *str) { Item_func::print_op(str); }
  178.   bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
  179.   bool is_bool_func() { return 1; }
  180.   CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
  181.   friend class  Arg_comparator;
  182. };
  183. class Item_bool_rowready_func2 :public Item_bool_func2
  184. {
  185. public:
  186.   Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
  187.   {
  188.     allowed_arg_cols= 0;  // Fetch this value from first argument
  189.   }
  190.   Item *neg_transformer(THD *thd);
  191.   virtual Item *negated_item();
  192. };
  193. class Item_func_not :public Item_bool_func
  194. {
  195. public:
  196.   Item_func_not(Item *a) :Item_bool_func(a) {}
  197.   longlong val_int();
  198.   enum Functype functype() const { return NOT_FUNC; }
  199.   const char *func_name() const { return "not"; }
  200.   Item *neg_transformer(THD *thd);
  201. };
  202. class Item_maxmin_subselect;
  203. class Item_func_not_all :public Item_func_not
  204. {
  205.   /* allow to check presence od values in max/min optimisation */
  206.   Item_sum_hybrid *test_sum_item;
  207.   Item_maxmin_subselect *test_sub_item;
  208.   bool abort_on_null;
  209. public:
  210.   bool show;
  211.   Item_func_not_all(Item *a)
  212.     :Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
  213.      show(0)
  214.     {}
  215.   virtual void top_level_item() { abort_on_null= 1; }
  216.   bool top_level() { return abort_on_null; }
  217.   longlong val_int();
  218.   enum Functype functype() const { return NOT_ALL_FUNC; }
  219.   const char *func_name() const { return "<not>"; }
  220.   void print(String *str);
  221.   void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
  222.   void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
  223.   bool empty_underlying_subquery();
  224. };
  225. class Item_func_nop_all :public Item_func_not_all
  226. {
  227. public:
  228.   Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
  229.   longlong val_int();
  230.   const char *func_name() const { return "<nop>"; }
  231. };
  232. class Item_func_eq :public Item_bool_rowready_func2
  233. {
  234. public:
  235.   Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
  236.   longlong val_int();
  237.   enum Functype functype() const { return EQ_FUNC; }
  238.   enum Functype rev_functype() const { return EQ_FUNC; }
  239.   cond_result eq_cmp_result() const { return COND_TRUE; }
  240.   const char *func_name() const { return "="; }
  241.   Item *negated_item();
  242. };
  243. class Item_func_equal :public Item_bool_rowready_func2
  244. {
  245. public:
  246.   Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
  247.   longlong val_int();
  248.   void fix_length_and_dec();
  249.   table_map not_null_tables() const { return 0; }
  250.   enum Functype functype() const { return EQUAL_FUNC; }
  251.   enum Functype rev_functype() const { return EQUAL_FUNC; }
  252.   cond_result eq_cmp_result() const { return COND_TRUE; }
  253.   const char *func_name() const { return "<=>"; }
  254.   Item *neg_transformer(THD *thd) { return 0; }
  255. };
  256. class Item_func_ge :public Item_bool_rowready_func2
  257. {
  258. public:
  259.   Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
  260.   longlong val_int();
  261.   enum Functype functype() const { return GE_FUNC; }
  262.   enum Functype rev_functype() const { return LE_FUNC; }
  263.   cond_result eq_cmp_result() const { return COND_TRUE; }
  264.   const char *func_name() const { return ">="; }
  265.   Item *negated_item();
  266. };
  267. class Item_func_gt :public Item_bool_rowready_func2
  268. {
  269. public:
  270.   Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
  271.   longlong val_int();
  272.   enum Functype functype() const { return GT_FUNC; }
  273.   enum Functype rev_functype() const { return LT_FUNC; }
  274.   cond_result eq_cmp_result() const { return COND_FALSE; }
  275.   const char *func_name() const { return ">"; }
  276.   Item *negated_item();
  277. };
  278. class Item_func_le :public Item_bool_rowready_func2
  279. {
  280. public:
  281.   Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
  282.   longlong val_int();
  283.   enum Functype functype() const { return LE_FUNC; }
  284.   enum Functype rev_functype() const { return GE_FUNC; }
  285.   cond_result eq_cmp_result() const { return COND_TRUE; }
  286.   const char *func_name() const { return "<="; }
  287.   Item *negated_item();
  288. };
  289. class Item_func_lt :public Item_bool_rowready_func2
  290. {
  291. public:
  292.   Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
  293.   longlong val_int();
  294.   enum Functype functype() const { return LT_FUNC; }
  295.   enum Functype rev_functype() const { return GT_FUNC; }
  296.   cond_result eq_cmp_result() const { return COND_FALSE; }
  297.   const char *func_name() const { return "<"; }
  298.   Item *negated_item();
  299. };
  300. class Item_func_ne :public Item_bool_rowready_func2
  301. {
  302. public:
  303.   Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
  304.   longlong val_int();
  305.   enum Functype functype() const { return NE_FUNC; }
  306.   cond_result eq_cmp_result() const { return COND_FALSE; }
  307.   optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
  308.   const char *func_name() const { return "<>"; }
  309.   Item *negated_item();
  310. };
  311. /*
  312.   The class Item_func_opt_neg is defined to factor out the functionality
  313.   common for the classes Item_func_between and Item_func_in. The objects
  314.   of these classes can express predicates or there negations.
  315.   The alternative approach would be to create pairs Item_func_between,
  316.   Item_func_notbetween and Item_func_in, Item_func_notin.
  317. */
  318. class Item_func_opt_neg :public Item_int_func
  319. {
  320. public:
  321.   bool negated;     /* <=> the item represents NOT <func> */
  322.   bool pred_level;  /* <=> [NOT] <func> is used on a predicate level */
  323. public:
  324.   Item_func_opt_neg(Item *a, Item *b, Item *c)
  325.     :Item_int_func(a, b, c), negated(0), pred_level(0) {}
  326.   Item_func_opt_neg(List<Item> &list)
  327.     :Item_int_func(list), negated(0), pred_level(0) {}
  328. public:
  329.   inline void negate() { negated= !negated; }
  330.   inline void top_level_item() { pred_level= 1; }
  331.   Item *neg_transformer(THD *thd)
  332.   {
  333.     negated= !negated;
  334.     return this;
  335.   }
  336. };
  337. class Item_func_between :public Item_func_opt_neg
  338. {
  339.   DTCollation cmp_collation;
  340. public:
  341.   Item_result cmp_type;
  342.   String value0,value1,value2;
  343.   Item_func_between(Item *a, Item *b, Item *c)
  344.     :Item_func_opt_neg(a, b, c) {}
  345.   longlong val_int();
  346.   optimize_type select_optimize() const { return OPTIMIZE_KEY; }
  347.   enum Functype functype() const   { return BETWEEN; }
  348.   const char *func_name() const { return "between"; }
  349.   bool fix_fields(THD *, struct st_table_list *, Item **);
  350.   void fix_length_and_dec();
  351.   void print(String *str);
  352.   CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
  353. };
  354. class Item_func_strcmp :public Item_bool_func2
  355. {
  356. public:
  357.   Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
  358.   longlong val_int();
  359.   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
  360.   const char *func_name() const { return "strcmp"; }
  361. };
  362. class Item_func_interval :public Item_int_func
  363. {
  364.   Item_row *row;
  365.   double *intervals;
  366. public:
  367.   Item_func_interval(Item_row *a)
  368.     :Item_int_func(a),row(a),intervals(0)
  369.   {
  370.     allowed_arg_cols= 0;    // Fetch this value from first argument
  371.   }
  372.   longlong val_int();
  373.   void fix_length_and_dec();
  374.   const char *func_name() const { return "interval"; }
  375. };
  376. class Item_func_ifnull :public Item_func
  377. {
  378.   enum Item_result cached_result_type;
  379.   enum_field_types cached_field_type;
  380.   bool field_type_defined;
  381. public:
  382.   Item_func_ifnull(Item *a,Item *b)
  383.     :Item_func(a,b), cached_result_type(INT_RESULT)
  384.   {}
  385.   double val();
  386.   longlong val_int();
  387.   String *val_str(String *str);
  388.   enum Item_result result_type () const { return cached_result_type; }
  389.   enum_field_types field_type() const;
  390.   void fix_length_and_dec();
  391.   const char *func_name() const { return "ifnull"; }
  392.   Field *tmp_table_field(TABLE *table);
  393.   table_map not_null_tables() const { return 0; }
  394. };
  395. class Item_func_if :public Item_func
  396. {
  397.   enum Item_result cached_result_type;
  398. public:
  399.   Item_func_if(Item *a,Item *b,Item *c)
  400.     :Item_func(a,b,c), cached_result_type(INT_RESULT)
  401.   {}
  402.   double val();
  403.   longlong val_int();
  404.   String *val_str(String *str);
  405.   enum Item_result result_type () const { return cached_result_type; }
  406.   bool fix_fields(THD *, struct st_table_list *, Item **);
  407.   void fix_length_and_dec();
  408.   const char *func_name() const { return "if"; }
  409. };
  410. class Item_func_nullif :public Item_bool_func2
  411. {
  412.   enum Item_result cached_result_type;
  413. public:
  414.   Item_func_nullif(Item *a,Item *b)
  415.     :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
  416.   {}
  417.   double val();
  418.   longlong val_int();
  419.   String *val_str(String *str);
  420.   enum Item_result result_type () const { return cached_result_type; }
  421.   void fix_length_and_dec();
  422.   const char *func_name() const { return "nullif"; }
  423.   void print(String *str) { Item_func::print(str); }
  424.   table_map not_null_tables() const { return 0; }
  425.   bool is_null();
  426. };
  427. class Item_func_coalesce :public Item_func
  428. {
  429.   enum Item_result cached_result_type;
  430. public:
  431.   Item_func_coalesce(List<Item> &list)
  432.     :Item_func(list),cached_result_type(INT_RESULT)
  433.   {}
  434.   double val();
  435.   longlong val_int();
  436.   String *val_str(String *);
  437.   void fix_length_and_dec();
  438.   enum Item_result result_type () const { return cached_result_type; }
  439.   const char *func_name() const { return "coalesce"; }
  440.   table_map not_null_tables() const { return 0; }
  441. };
  442. class Item_func_case :public Item_func
  443. {
  444.   int first_expr_num, else_expr_num;
  445.   enum Item_result cached_result_type;
  446.   String tmp_value;
  447.   uint ncases;
  448.   Item_result cmp_type;
  449.   DTCollation cmp_collation;
  450. public:
  451.   Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
  452.     :Item_func(), first_expr_num(-1), else_expr_num(-1),
  453.     cached_result_type(INT_RESULT)
  454.   { 
  455.     ncases= list.elements;
  456.     if (first_expr_arg)
  457.     {
  458.       first_expr_num= list.elements;
  459.       list.push_back(first_expr_arg);
  460.     }
  461.     if (else_expr_arg)
  462.     {
  463.       else_expr_num= list.elements;
  464.       list.push_back(else_expr_arg);
  465.     }
  466.     set_arguments(list);
  467.   }
  468.   double val();
  469.   longlong val_int();
  470.   String *val_str(String *);
  471.   void fix_length_and_dec();
  472.   table_map not_null_tables() const { return 0; }
  473.   enum Item_result result_type () const { return cached_result_type; }
  474.   const char *func_name() const { return "case"; }
  475.   void print(String *str);
  476.   Item *find_item(String *str);
  477.   CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
  478. };
  479. /* Functions to handle the optimized IN */
  480. class in_vector :public Sql_alloc
  481. {
  482.  protected:
  483.   char *base;
  484.   uint size;
  485.   qsort2_cmp compare;
  486.   CHARSET_INFO *collation;
  487.   uint count;
  488. public:
  489.   uint used_count;
  490.   in_vector() {}
  491.   in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 
  492.        CHARSET_INFO *cmp_coll)
  493.     :base((char*) sql_calloc(elements*element_length)),
  494.      size(element_length), compare(cmp_func), collation(cmp_coll),
  495.      count(elements), used_count(elements) {}
  496.   virtual ~in_vector() {}
  497.   virtual void set(uint pos,Item *item)=0;
  498.   virtual byte *get_value(Item *item)=0;
  499.   void sort()
  500.   {
  501.     qsort2(base,used_count,size,compare,collation);
  502.   }
  503.   int find(Item *item);
  504. };
  505. class in_string :public in_vector
  506. {
  507.   char buff[80];
  508.   String tmp;
  509. public:
  510.   in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
  511.   ~in_string();
  512.   void set(uint pos,Item *item);
  513.   byte *get_value(Item *item);
  514. };
  515. class in_longlong :public in_vector
  516. {
  517.   longlong tmp;
  518. public:
  519.   in_longlong(uint elements);
  520.   void set(uint pos,Item *item);
  521.   byte *get_value(Item *item);
  522. };
  523. class in_double :public in_vector
  524. {
  525.   double tmp;
  526. public:
  527.   in_double(uint elements);
  528.   void set(uint pos,Item *item);
  529.   byte *get_value(Item *item);
  530. };
  531. /*
  532. ** Classes for easy comparing of non const items
  533. */
  534. class cmp_item :public Sql_alloc
  535. {
  536. public:
  537.   CHARSET_INFO *cmp_charset;
  538.   cmp_item() { cmp_charset= &my_charset_bin; }
  539.   virtual ~cmp_item() {}
  540.   virtual void store_value(Item *item)= 0;
  541.   virtual int cmp(Item *item)= 0;
  542.   // for optimized IN with row
  543.   virtual int compare(cmp_item *item)= 0;
  544.   static cmp_item* get_comparator(Item *);
  545.   virtual cmp_item *make_same()= 0;
  546.   virtual void store_value_by_template(cmp_item *tmpl, Item *item)
  547.   {
  548.     store_value(item);
  549.   }
  550. };
  551. class cmp_item_string :public cmp_item 
  552. {
  553. protected:
  554.   String *value_res;
  555. public:
  556.   cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
  557.   friend class cmp_item_sort_string;
  558.   friend class cmp_item_sort_string_in_static;
  559. };
  560. class cmp_item_sort_string :public cmp_item_string
  561. {
  562. protected:
  563.   char value_buff[80];
  564.   String value;
  565. public:
  566.   cmp_item_sort_string(CHARSET_INFO *cs):
  567.     cmp_item_string(cs),
  568.     value(value_buff, sizeof(value_buff), cs) {}
  569.   void store_value(Item *item)
  570.   {
  571.     value_res= item->val_str(&value);
  572.   }
  573.   int cmp(Item *arg)
  574.   {
  575.     char buff[80];
  576.     String tmp(buff, sizeof(buff), cmp_charset), *res;
  577.     if (!(res= arg->val_str(&tmp)))
  578.       return 1; /* Can't be right */
  579.     return sortcmp(value_res, res, cmp_charset);
  580.   }
  581.   int compare(cmp_item *c)
  582.   {
  583.     cmp_item_string *cmp= (cmp_item_string *)c;
  584.     return sortcmp(value_res, cmp->value_res, cmp_charset);
  585.   } 
  586.   cmp_item *make_same();
  587. };
  588. class cmp_item_int :public cmp_item
  589. {
  590.   longlong value;
  591. public:
  592.   void store_value(Item *item)
  593.   {
  594.     value= item->val_int();
  595.   }
  596.   int cmp(Item *arg)
  597.   {
  598.     return value != arg->val_int();
  599.   }
  600.   int compare(cmp_item *c)
  601.   {
  602.     cmp_item_int *cmp= (cmp_item_int *)c;
  603.     return (value < cmp->value) ? -1 : ((value == cmp->value) ? 0 : 1);
  604.   }
  605.   cmp_item *make_same();
  606. };
  607. class cmp_item_real :public cmp_item
  608. {
  609.   double value;
  610. public:
  611.   void store_value(Item *item)
  612.   {
  613.     value= item->val();
  614.   }
  615.   int cmp(Item *arg)
  616.   {
  617.     return value != arg->val();
  618.   }
  619.   int compare(cmp_item *c)
  620.   {
  621.     cmp_item_real *cmp= (cmp_item_real *)c;
  622.     return (value < cmp->value)? -1 : ((value == cmp->value) ? 0 : 1);
  623.   }
  624.   cmp_item *make_same();
  625. };
  626. class cmp_item_row :public cmp_item
  627. {
  628.   cmp_item **comparators;
  629.   uint n;
  630. public:
  631.   cmp_item_row(): comparators(0), n(0) {}
  632.   ~cmp_item_row();
  633.   void store_value(Item *item);
  634.   int cmp(Item *arg);
  635.   int compare(cmp_item *arg);
  636.   cmp_item *make_same();
  637.   void store_value_by_template(cmp_item *tmpl, Item *);
  638. };
  639. class in_row :public in_vector
  640. {
  641.   cmp_item_row tmp;
  642. public:
  643.   in_row(uint elements, Item *);
  644.   ~in_row();
  645.   void set(uint pos,Item *item);
  646.   byte *get_value(Item *item);
  647. };
  648. /* 
  649.    cmp_item for optimized IN with row (right part string, which never
  650.    be changed)
  651. */
  652. class cmp_item_sort_string_in_static :public cmp_item_string
  653. {
  654.  protected:
  655.   String value;
  656. public:
  657.   cmp_item_sort_string_in_static(CHARSET_INFO *cs):
  658.     cmp_item_string(cs) {}
  659.   void store_value(Item *item)
  660.   {
  661.     value_res= item->val_str(&value);
  662.   }
  663.   int cmp(Item *item)
  664.   {
  665.     // Should never be called
  666.     DBUG_ASSERT(0);
  667.     return 1;
  668.   }
  669.   int compare(cmp_item *c)
  670.   {
  671.     cmp_item_string *cmp= (cmp_item_string *)c;
  672.     return sortcmp(value_res, cmp->value_res, cmp_charset);
  673.   }
  674.   cmp_item *make_same()
  675.   {
  676.     return new cmp_item_sort_string_in_static(cmp_charset);
  677.   }
  678. };
  679. class Item_func_in :public Item_func_opt_neg
  680. {
  681.   Item_result cmp_type;
  682.   in_vector *array;
  683.   cmp_item *in_item;
  684.   bool have_null;
  685.   DTCollation cmp_collation;
  686.  public:
  687.   Item_func_in(List<Item> &list)
  688.     :Item_func_opt_neg(list), array(0), in_item(0), have_null(0)
  689.   {
  690.     allowed_arg_cols= 0;  // Fetch this value from first argument
  691.   }
  692.   longlong val_int();
  693.   bool fix_fields(THD *, struct st_table_list *, Item **);
  694.   void fix_length_and_dec();
  695.   void cleanup()
  696.   {
  697.     DBUG_ENTER("Item_func_in::cleanup");
  698.     Item_int_func::cleanup();
  699.     delete array;
  700.     delete in_item;
  701.     array= 0;
  702.     in_item= 0;
  703.     DBUG_VOID_RETURN;
  704.   }
  705.   optimize_type select_optimize() const
  706.     { return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; }
  707.   void print(String *str);
  708.   enum Functype functype() const { return IN_FUNC; }
  709.   const char *func_name() const { return " IN "; }
  710.   bool nulls_in_row();
  711.   bool is_bool_func() { return 1; }
  712.   CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
  713. };
  714. /* Functions used by where clause */
  715. class Item_func_isnull :public Item_bool_func
  716. {
  717. protected:
  718.   longlong cached_value;
  719. public:
  720.   Item_func_isnull(Item *a) :Item_bool_func(a) {}
  721.   longlong val_int();
  722.   enum Functype functype() const { return ISNULL_FUNC; }
  723.   void fix_length_and_dec()
  724.   {
  725.     decimals=0; max_length=1; maybe_null=0;
  726.     update_used_tables();
  727.   }
  728.   const char *func_name() const { return "isnull"; }
  729.   /* Optimize case of not_null_column IS NULL */
  730.   virtual void update_used_tables()
  731.   {
  732.     if (!args[0]->maybe_null)
  733.     {
  734.       used_tables_cache= 0; /* is always false */
  735.       const_item_cache= 1;
  736.       cached_value= (longlong) 0;
  737.     }
  738.     else
  739.     {
  740.       args[0]->update_used_tables();
  741.       if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())))
  742.       {
  743. /* Remember if the value is always NULL or never NULL */
  744. cached_value= (longlong) args[0]->is_null();
  745.       }
  746.     }
  747.   }
  748.   table_map not_null_tables() const { return 0; }
  749.   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
  750.   Item *neg_transformer(THD *thd);
  751.   CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
  752. };
  753. /* Functions used by HAVING for rewriting IN subquery */
  754. class Item_in_subselect;
  755. class Item_is_not_null_test :public Item_func_isnull
  756. {
  757.   Item_in_subselect* owner;
  758. public:
  759.   Item_is_not_null_test(Item_in_subselect* ow, Item *a)
  760.     :Item_func_isnull(a), owner(ow)
  761.   {}
  762.   enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
  763.   longlong val_int();
  764.   const char *func_name() const { return "<is_not_null_test>"; }
  765.   void update_used_tables();
  766.   /*
  767.     we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
  768.   */
  769.   table_map used_tables() const
  770.     { return used_tables_cache | RAND_TABLE_BIT; }
  771. };
  772. class Item_func_isnotnull :public Item_bool_func
  773. {
  774. public:
  775.   Item_func_isnotnull(Item *a) :Item_bool_func(a) {}
  776.   longlong val_int();
  777.   enum Functype functype() const { return ISNOTNULL_FUNC; }
  778.   void fix_length_and_dec()
  779.   {
  780.     decimals=0; max_length=1; maybe_null=0;
  781.   }
  782.   const char *func_name() const { return "isnotnull"; }
  783.   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
  784.   table_map not_null_tables() const { return 0; }
  785.   Item *neg_transformer(THD *thd);
  786.   void print(String *str);
  787.   CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
  788. };
  789. class Item_func_like :public Item_bool_func2
  790. {
  791.   // Turbo Boyer-Moore data
  792.   bool        canDoTurboBM; // pattern is '%abcd%' case
  793.   const char* pattern;
  794.   int         pattern_len;
  795.   // TurboBM buffers, *this is owner
  796.   int* bmGs; //   good suffix shift table, size is pattern_len + 1
  797.   int* bmBc; // bad character shift table, size is alphabet_size
  798.   void turboBM_compute_suffixes(int* suff);
  799.   void turboBM_compute_good_suffix_shifts(int* suff);
  800.   void turboBM_compute_bad_character_shifts();
  801.   bool turboBM_matches(const char* text, int text_len) const;
  802.   enum { alphabet_size = 256 };
  803.   Item *escape_item;
  804. public:
  805.   int escape;
  806.   Item_func_like(Item *a,Item *b, Item *escape_arg)
  807.     :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), 
  808.      bmGs(0), bmBc(0), escape_item(escape_arg) {}
  809.   longlong val_int();
  810.   enum Functype functype() const { return LIKE_FUNC; }
  811.   optimize_type select_optimize() const;
  812.   cond_result eq_cmp_result() const { return COND_TRUE; }
  813.   const char *func_name() const { return "like"; }
  814.   bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
  815. };
  816. #ifdef USE_REGEX
  817. #include "my_regex.h"
  818. class Item_func_regex :public Item_bool_func
  819. {
  820.   my_regex_t preg;
  821.   bool regex_compiled;
  822.   bool regex_is_const;
  823.   String prev_regexp;
  824.   DTCollation cmp_collation;
  825. public:
  826.   Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
  827.     regex_compiled(0),regex_is_const(0) {}
  828.   void cleanup();
  829.   longlong val_int();
  830.   bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
  831.   const char *func_name() const { return "regexp"; }
  832.   void print(String *str) { print_op(str); }
  833.   CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
  834. };
  835. #else
  836. class Item_func_regex :public Item_bool_func
  837. {
  838. public:
  839.   Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b) {}
  840.   longlong val_int() { return 0;}
  841.   const char *func_name() const { return "regex"; }
  842.   void print(String *str) { print_op(str); }
  843. };
  844. #endif /* USE_REGEX */
  845. typedef class Item COND;
  846. class Item_cond :public Item_bool_func
  847. {
  848. protected:
  849.   List<Item> list;
  850.   bool abort_on_null;
  851.   table_map and_tables_cache;
  852. public:
  853.   /* Item_cond() is only used to create top level items */
  854.   Item_cond(): Item_bool_func(), abort_on_null(1)
  855.   { const_item_cache=0; }
  856.   Item_cond(Item *i1,Item *i2) 
  857.     :Item_bool_func(), abort_on_null(0)
  858.   {
  859.     list.push_back(i1);
  860.     list.push_back(i2);
  861.   }
  862.   Item_cond(THD *thd, Item_cond *item);
  863.   Item_cond(List<Item> &nlist)
  864.     :Item_bool_func(), list(nlist), abort_on_null(0) {}
  865.   bool add(Item *item) { return list.push_back(item); }
  866.   bool fix_fields(THD *, struct st_table_list *, Item **ref);
  867.   enum Type type() const { return COND_ITEM; }
  868.   List<Item>* argument_list() { return &list; }
  869.   table_map used_tables() const;
  870.   void update_used_tables();
  871.   void print(String *str);
  872.   void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
  873.   friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
  874.   void top_level_item() { abort_on_null=1; }
  875.   void copy_andor_arguments(THD *thd, Item_cond *item);
  876.   bool walk(Item_processor processor, byte *arg);
  877.   void neg_arguments(THD *thd);
  878. };
  879. class Item_cond_and :public Item_cond
  880. {
  881. public:
  882.   Item_cond_and() :Item_cond() {}
  883.   Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
  884.   Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
  885.   Item_cond_and(List<Item> &list): Item_cond(list) {}
  886.   enum Functype functype() const { return COND_AND_FUNC; }
  887.   longlong val_int();
  888.   const char *func_name() const { return "and"; }
  889.   table_map not_null_tables() const
  890.   { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
  891.   Item* copy_andor_structure(THD *thd)
  892.   {
  893.     Item_cond_and *item;
  894.     if ((item= new Item_cond_and(thd, this)))
  895.        item->copy_andor_arguments(thd, this);
  896.     return item;
  897.   }
  898.   Item *neg_transformer(THD *thd);
  899. };
  900. class Item_cond_or :public Item_cond
  901. {
  902. public:
  903.   Item_cond_or() :Item_cond() {}
  904.   Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
  905.   Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
  906.   Item_cond_or(List<Item> &list): Item_cond(list) {}
  907.   enum Functype functype() const { return COND_OR_FUNC; }
  908.   longlong val_int();
  909.   const char *func_name() const { return "or"; }
  910.   table_map not_null_tables() const { return and_tables_cache; }
  911.   Item* copy_andor_structure(THD *thd)
  912.   {
  913.     Item_cond_or *item;
  914.     if ((item= new Item_cond_or(thd, this)))
  915.       item->copy_andor_arguments(thd, this);
  916.     return item;
  917.   }
  918.   Item *neg_transformer(THD *thd);
  919. };
  920. /*
  921.   XOR is Item_cond, not an Item_int_func bevause we could like to
  922.   optimize (a XOR b) later on. It's low prio, though
  923. */
  924. class Item_cond_xor :public Item_cond
  925. {
  926. public:
  927.   Item_cond_xor() :Item_cond() {}
  928.   Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
  929.   enum Functype functype() const { return COND_XOR_FUNC; }
  930.   /* TODO: remove the next line when implementing XOR optimization */
  931.   enum Type type() const { return FUNC_ITEM; }
  932.   longlong val_int();
  933.   const char *func_name() const { return "xor"; }
  934.   void top_level_item() {}
  935. };
  936. /* Some usefull inline functions */
  937. inline Item *and_conds(Item *a, Item *b)
  938. {
  939.   if (!b) return a;
  940.   if (!a) return b;
  941.   return new Item_cond_and(a, b);
  942. }
  943. Item *and_expressions(Item *a, Item *b, Item **org_item);