My Project
item_cmpfunc.h
00001 #ifndef ITEM_CMPFUNC_INCLUDED
00002 #define ITEM_CMPFUNC_INCLUDED
00003 
00004 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; version 2 of the License.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
00018 
00019 
00020 /* compare and test functions */
00021 
00022 #include "thr_malloc.h"                         /* sql_calloc */
00023 #include "item_func.h"             /* Item_int_func, Item_bool_func */
00024 #include "my_regex.h"
00025 
00026 extern Item_result item_cmp_type(Item_result a,Item_result b);
00027 class Item_bool_func2;
00028 class Arg_comparator;
00029 
00030 typedef int (Arg_comparator::*arg_cmp_func)();
00031 
00032 typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg); 
00033 
00034 class Arg_comparator: public Sql_alloc
00035 {
00036   Item **a, **b;
00037   arg_cmp_func func;
00038   Item_result_field *owner;
00039   Arg_comparator *comparators;   // used only for compare_row()
00040   double precision;
00041   /* Fields used in DATE/DATETIME comparison. */
00042   THD *thd;
00043   enum_field_types a_type, b_type; // Types of a and b items
00044   Item *a_cache, *b_cache;         // Cached values of a and b items
00045   bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
00046   bool set_null;                   // TRUE <=> set owner->null_value
00047                                    //   when one of arguments is NULL.
00048   longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
00049                                Item *warn_item, bool *is_null);
00050   longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
00051                                Item *warn_item, bool *is_null);
00052   bool try_year_cmp_func(Item_result type);
00053   static bool get_date_from_const(Item *date_arg, Item *str_arg,
00054                                   ulonglong *value);
00055 public:
00056   DTCollation cmp_collation;
00057   /* Allow owner function to use string buffers. */
00058   String value1, value2;
00059 
00060   Arg_comparator(): comparators(0), thd(0), a_cache(0), b_cache(0), set_null(TRUE),
00061     get_value_a_func(0), get_value_b_func(0) {};
00062   Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), comparators(0), thd(0),
00063     a_cache(0), b_cache(0), set_null(TRUE),
00064     get_value_a_func(0), get_value_b_func(0) {};
00065 
00066   int set_compare_func(Item_result_field *owner, Item_result type);
00067   inline int set_compare_func(Item_result_field *owner_arg)
00068   {
00069     return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
00070                                                      (*b)->result_type()));
00071   }
00072   int set_cmp_func(Item_result_field *owner_arg,
00073                           Item **a1, Item **a2,
00074                           Item_result type);
00075 
00076   inline int set_cmp_func(Item_result_field *owner_arg,
00077                           Item **a1, Item **a2, bool set_null_arg)
00078   {
00079     set_null= set_null_arg;
00080     return set_cmp_func(owner_arg, a1, a2,
00081                         item_cmp_type((*a1)->result_type(),
00082                                       (*a2)->result_type()));
00083   }
00084   inline int compare() { return (this->*func)(); }
00085 
00086   int compare_string();          // compare args[0] & args[1]
00087   int compare_binary_string();   // compare args[0] & args[1]
00088   int compare_real();            // compare args[0] & args[1]
00089   int compare_decimal();         // compare args[0] & args[1]
00090   int compare_int_signed();      // compare args[0] & args[1]
00091   int compare_int_signed_unsigned();
00092   int compare_int_unsigned_signed();
00093   int compare_int_unsigned();
00094   int compare_time_packed();
00095   int compare_e_time_packed();
00096   int compare_row();             // compare args[0] & args[1]
00097   int compare_e_string();        // compare args[0] & args[1]
00098   int compare_e_binary_string(); // compare args[0] & args[1]
00099   int compare_e_real();          // compare args[0] & args[1]
00100   int compare_e_decimal();       // compare args[0] & args[1]
00101   int compare_e_int();           // compare args[0] & args[1]
00102   int compare_e_int_diff_signedness();
00103   int compare_e_row();           // compare args[0] & args[1]
00104   int compare_real_fixed();
00105   int compare_e_real_fixed();
00106   int compare_datetime();        // compare args[0] & args[1] as DATETIMEs
00107 
00108   static bool can_compare_as_dates(Item *a, Item *b, ulonglong *const_val_arg);
00109 
00110   Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
00111                                   Item_result type);
00112   void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1);
00113   static arg_cmp_func comparator_matrix [5][2];
00114   inline bool is_owner_equal_func()
00115   {
00116     return (owner->type() == Item::FUNC_ITEM &&
00117            ((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
00118   }
00119   void cleanup()
00120   {
00121     delete [] comparators;
00122     comparators= 0;
00123   }
00124   /*
00125     Set correct cmp_context if items would be compared as INTs.
00126   */
00127   inline void set_cmp_context_for_datetime()
00128   {
00129     DBUG_ASSERT(func == &Arg_comparator::compare_datetime);
00130     if ((*a)->is_temporal())
00131       (*a)->cmp_context= INT_RESULT;
00132     if ((*b)->is_temporal())
00133       (*b)->cmp_context= INT_RESULT;
00134   }
00135   friend class Item_func;
00136 };
00137 
00138 class Item_bool_func :public Item_int_func
00139 {
00140 public:
00141   Item_bool_func() : Item_int_func(), m_created_by_in2exists(false) {}
00142   Item_bool_func(Item *a) : Item_int_func(a),
00143     m_created_by_in2exists(false)  {}
00144   Item_bool_func(Item *a,Item *b) : Item_int_func(a,b),
00145     m_created_by_in2exists(false)  {}
00146   Item_bool_func(THD *thd, Item_bool_func *item) : Item_int_func(thd, item),
00147     m_created_by_in2exists(item->m_created_by_in2exists) {}
00148   bool is_bool_func() { return 1; }
00149   void fix_length_and_dec() { decimals=0; max_length=1; }
00150   uint decimal_precision() const { return 1; }
00151   virtual bool created_by_in2exists() const { return m_created_by_in2exists; }
00152   void set_created_by_in2exists() { m_created_by_in2exists= true; }
00153 private:
00158   bool m_created_by_in2exists;
00159 };
00160 
00161 
00167 class Item_func_truth : public Item_bool_func
00168 {
00169 public:
00170   virtual bool val_bool();
00171   virtual longlong val_int();
00172   virtual void fix_length_and_dec();
00173   virtual void print(String *str, enum_query_type query_type);
00174 
00175 protected:
00176   Item_func_truth(Item *a, bool a_value, bool a_affirmative)
00177   : Item_bool_func(a), value(a_value), affirmative(a_affirmative)
00178   {}
00179 
00180   ~Item_func_truth()
00181   {}
00182 private:
00187   const bool value;
00191   const bool affirmative;
00192 };
00193 
00194 
00199 class Item_func_istrue : public Item_func_truth
00200 {
00201 public:
00202   Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
00203   ~Item_func_istrue() {}
00204   virtual const char* func_name() const { return "istrue"; }
00205 };
00206 
00207 
00212 class Item_func_isnottrue : public Item_func_truth
00213 {
00214 public:
00215   Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
00216   ~Item_func_isnottrue() {}
00217   virtual const char* func_name() const { return "isnottrue"; }
00218 };
00219 
00220 
00225 class Item_func_isfalse : public Item_func_truth
00226 {
00227 public:
00228   Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
00229   ~Item_func_isfalse() {}
00230   virtual const char* func_name() const { return "isfalse"; }
00231 };
00232 
00233 
00238 class Item_func_isnotfalse : public Item_func_truth
00239 {
00240 public:
00241   Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
00242   ~Item_func_isnotfalse() {}
00243   virtual const char* func_name() const { return "isnotfalse"; }
00244 };
00245 
00246 
00247 class Item_cache;
00248 #define UNKNOWN ((my_bool)-1)
00249 
00250 
00251 /*
00252   Item_in_optimizer(left_expr, Item_in_subselect(...))
00253 
00254   Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
00255   class does the following:
00256    - Evaluate the left expression and store it in Item_cache_* object (to
00257      avoid re-evaluating it many times during subquery execution)
00258    - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
00259      don't care if the result is NULL or FALSE.
00260 
00261    args[1] keeps a reference to the Item_in_subselect object.
00262 
00263    args[0] is a copy of Item_in_subselect's left expression and should be
00264    kept equal also after resolving.
00265 
00266   NOTE
00267     It is not quite clear why the above listed functionality should be
00268     placed into a separate class called 'Item_in_optimizer'.
00269 */
00270 
00271 class Item_in_optimizer: public Item_bool_func
00272 {
00273 private:
00274   Item_cache *cache;
00275   bool save_cache;
00276   /* 
00277     Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
00278       UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
00279       FALSE   - result is FALSE
00280       TRUE    - result is NULL
00281   */
00282   my_bool result_for_null_param;
00283 public:
00284   Item_in_optimizer(Item *a, Item_in_subselect *b):
00285     Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
00286     save_cache(0), result_for_null_param(UNKNOWN)
00287   { with_subselect= TRUE; }
00288   bool fix_fields(THD *, Item **);
00289   bool fix_left(THD *thd, Item **ref);
00290   void fix_after_pullout(st_select_lex *parent_select,
00291                          st_select_lex *removed_select);
00292   bool is_null();
00293   longlong val_int();
00294   void cleanup();
00295   const char *func_name() const { return "<in_optimizer>"; }
00296   Item_cache **get_cache() { return &cache; }
00297   void keep_top_level_cache();
00298   Item *transform(Item_transformer transformer, uchar *arg);
00299 };
00300 
00301 class Comp_creator
00302 {
00303 public:
00304   Comp_creator() {}                           /* Remove gcc warning */
00305   virtual ~Comp_creator() {}                  /* Remove gcc warning */
00306   virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
00307   virtual const char* symbol(bool invert) const = 0;
00308   virtual bool eqne_op() const = 0;
00309   virtual bool l_op() const = 0;
00310 };
00311 
00312 class Eq_creator :public Comp_creator
00313 {
00314 public:
00315   Eq_creator() {}                             /* Remove gcc warning */
00316   virtual ~Eq_creator() {}                    /* Remove gcc warning */
00317   virtual Item_bool_func2* create(Item *a, Item *b) const;
00318   virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
00319   virtual bool eqne_op() const { return 1; }
00320   virtual bool l_op() const { return 0; }
00321 };
00322 
00323 class Ne_creator :public Comp_creator
00324 {
00325 public:
00326   Ne_creator() {}                             /* Remove gcc warning */
00327   virtual ~Ne_creator() {}                    /* Remove gcc warning */
00328   virtual Item_bool_func2* create(Item *a, Item *b) const;
00329   virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
00330   virtual bool eqne_op() const { return 1; }
00331   virtual bool l_op() const { return 0; }
00332 };
00333 
00334 class Gt_creator :public Comp_creator
00335 {
00336 public:
00337   Gt_creator() {}                             /* Remove gcc warning */
00338   virtual ~Gt_creator() {}                    /* Remove gcc warning */
00339   virtual Item_bool_func2* create(Item *a, Item *b) const;
00340   virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
00341   virtual bool eqne_op() const { return 0; }
00342   virtual bool l_op() const { return 0; }
00343 };
00344 
00345 class Lt_creator :public Comp_creator
00346 {
00347 public:
00348   Lt_creator() {}                             /* Remove gcc warning */
00349   virtual ~Lt_creator() {}                    /* Remove gcc warning */
00350   virtual Item_bool_func2* create(Item *a, Item *b) const;
00351   virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
00352   virtual bool eqne_op() const { return 0; }
00353   virtual bool l_op() const { return 1; }
00354 };
00355 
00356 class Ge_creator :public Comp_creator
00357 {
00358 public:
00359   Ge_creator() {}                             /* Remove gcc warning */
00360   virtual ~Ge_creator() {}                    /* Remove gcc warning */
00361   virtual Item_bool_func2* create(Item *a, Item *b) const;
00362   virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
00363   virtual bool eqne_op() const { return 0; }
00364   virtual bool l_op() const { return 0; }
00365 };
00366 
00367 class Le_creator :public Comp_creator
00368 {
00369 public:
00370   Le_creator() {}                             /* Remove gcc warning */
00371   virtual ~Le_creator() {}                    /* Remove gcc warning */
00372   virtual Item_bool_func2* create(Item *a, Item *b) const;
00373   virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
00374   virtual bool eqne_op() const { return 0; }
00375   virtual bool l_op() const { return 1; }
00376 };
00377 
00378 class Item_bool_func2 :public Item_bool_func
00379 {                                               /* Bool with 2 string args */
00380 private:
00381   bool convert_constant_arg(THD *thd, Item *field, Item **item);
00382 protected:
00383   Arg_comparator cmp;
00384   bool abort_on_null;
00385 
00386 public:
00387   Item_bool_func2(Item *a,Item *b)
00388     :Item_bool_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
00389   void fix_length_and_dec();
00390   int set_cmp_func()
00391   {
00392     return cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, TRUE);
00393   }
00394   optimize_type select_optimize() const { return OPTIMIZE_OP; }
00395   virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
00396   bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
00397 
00398   virtual inline void print(String *str, enum_query_type query_type)
00399   {
00400     Item_func::print_op(str, query_type);
00401   }
00402 
00403   bool is_null() { return MY_TEST(args[0]->is_null() || args[1]->is_null()); }
00404   const CHARSET_INFO *compare_collation()
00405   { return cmp.cmp_collation.collation; }
00406   void top_level_item() { abort_on_null= TRUE; }
00407   void cleanup()
00408   {
00409     Item_bool_func::cleanup();
00410     cmp.cleanup();
00411   }
00412 
00413   friend class  Arg_comparator;
00414 };
00415 
00416 class Item_bool_rowready_func2 :public Item_bool_func2
00417 {
00418 public:
00419   Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
00420   {
00421     allowed_arg_cols= 0;  // Fetch this value from first argument
00422   }
00423   Item *neg_transformer(THD *thd);
00424   virtual Item *negated_item();
00425   bool subst_argument_checker(uchar **arg) { return TRUE; }
00426 };
00427 
00433 class Item_func_xor :public Item_bool_func2
00434 {
00435 public:
00436   Item_func_xor(Item *i1, Item *i2) :Item_bool_func2(i1, i2) {}
00437   enum Functype functype() const { return XOR_FUNC; }
00438   const char *func_name() const { return "xor"; }
00439   longlong val_int();
00440   void top_level_item() {}
00441   Item *neg_transformer(THD *thd);
00442 };
00443 
00444 class Item_func_not :public Item_bool_func
00445 {
00446 public:
00447   Item_func_not(Item *a) :Item_bool_func(a) {}
00448   longlong val_int();
00449   enum Functype functype() const { return NOT_FUNC; }
00450   const char *func_name() const { return "not"; }
00451   Item *neg_transformer(THD *thd);
00452   virtual void print(String *str, enum_query_type query_type);
00453 };
00454 
00455 class Item_maxmin_subselect;
00456 struct st_join_table;
00457 /*
00458   trigcond<param>(arg) ::= param? arg : TRUE
00459 
00460   The class Item_func_trig_cond is used for guarded predicates 
00461   which are employed only for internal purposes.
00462   A guarded predicate is an object consisting of an a regular or
00463   a guarded predicate P and a pointer to a boolean guard variable g. 
00464   A guarded predicate P/g is evaluated to true if the value of the
00465   guard g is false, otherwise it is evaluated to the same value that
00466   the predicate P: val(P/g)= g ? val(P):true.
00467   Guarded predicates allow us to include predicates into a conjunction
00468   conditionally. Currently they are utilized for pushed down predicates
00469   in queries with outer join operations.
00470 
00471   In the future, probably, it makes sense to extend this class to
00472   the objects consisting of three elements: a predicate P, a pointer
00473   to a variable g and a firing value s with following evaluation
00474   rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
00475   one item for the objects of the form P/g1/g2... 
00476 
00477   Objects of this class are built only for query execution after
00478   the execution plan has been already selected. That's why this
00479   class needs only val_int out of generic methods. 
00480  
00481   Current uses of Item_func_trig_cond objects:
00482    - To wrap selection conditions when executing outer joins
00483    - To wrap condition that is pushed down into subquery
00484 */
00485 
00486 class Item_func_trig_cond: public Item_bool_func
00487 {
00488 public:
00489   enum enum_trig_type
00490   {
00495     IS_NOT_NULL_COMPL,
00500     FOUND_MATCH,
00508     OUTER_FIELD_IS_NOT_NULL
00509   };
00510 private:
00512   bool *trig_var;
00514   const struct st_join_table *trig_tab;
00516   enum_trig_type trig_type;
00517 public:
00525   Item_func_trig_cond(Item *a, bool *f, struct st_join_table *tab,
00526                       enum_trig_type trig_type_arg)
00527     : Item_bool_func(a), trig_var(f), trig_tab(tab), trig_type(trig_type_arg)
00528   {}
00529   longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
00530   enum Functype functype() const { return TRIG_COND_FUNC; };
00532   const char *func_name() const { return "<if>"; };
00533   bool const_item() const { return FALSE; }
00534   bool *get_trig_var() { return trig_var; }
00535   /* The following is needed for ICP: */
00536   table_map used_tables() const { return args[0]->used_tables(); }
00537   void print(String *str, enum_query_type query_type);
00538 };
00539 
00540 
00541 class Item_func_not_all :public Item_func_not
00542 {
00543   /* allow to check presence of values in max/min optimization */
00544   Item_sum_hybrid *test_sum_item;
00545   Item_maxmin_subselect *test_sub_item;
00546   Item_subselect *subselect;
00547 
00548   bool abort_on_null;
00549 public:
00550   bool show;
00551 
00552   Item_func_not_all(Item *a)
00553     :Item_func_not(a), test_sum_item(0), test_sub_item(0), subselect(0),
00554      abort_on_null(0), show(0)
00555     {}
00556   virtual void top_level_item() { abort_on_null= 1; }
00557   bool top_level() { return abort_on_null; }
00558   longlong val_int();
00559   enum Functype functype() const { return NOT_ALL_FUNC; }
00560   const char *func_name() const { return "<not>"; }
00561   virtual void print(String *str, enum_query_type query_type);
00562   void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
00563   void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
00564   void set_subselect(Item_subselect *item) { subselect= item; }
00565   table_map not_null_tables() const
00566   {
00567     /*
00568       See handling of not_null_tables_cache in
00569       Item_in_optimizer::fix_fields().
00570 
00571       This item is the result of a transformation from an ALL clause
00572       such as
00573           left-expr < ALL(subquery)
00574       into
00575           <not>(left-expr >= (subquery)
00576 
00577       An inequality usually rejects NULLs from both operands, so the
00578       not_null_tables() of the inequality is the union of the
00579       null-rejecting tables of both operands. However, since this is a
00580       transformed ALL clause that should return true if the subquery
00581       is empty (even if left-expr is NULL), it is not null rejecting
00582       for left-expr. The not null tables mask for left-expr should be
00583       removed, leaving only the null-rejecting tables of the
00584       subquery. Item_subselect::not_null_tables() always returns 0 (no
00585       null-rejecting tables). Therefore, always return 0.
00586     */
00587     return 0;
00588   }
00589   bool empty_underlying_subquery();
00590   Item *neg_transformer(THD *thd);
00591 };
00592 
00593 
00594 class Item_func_nop_all :public Item_func_not_all
00595 {
00596 public:
00597 
00598   Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
00599   longlong val_int();
00600   const char *func_name() const { return "<nop>"; }
00601   table_map not_null_tables() const { return not_null_tables_cache; }
00602   Item *neg_transformer(THD *thd);
00603 };
00604 
00605 
00606 class Item_func_eq :public Item_bool_rowready_func2
00607 {
00608 public:
00609   Item_func_eq(Item *a,Item *b) :
00610     Item_bool_rowready_func2(a,b)
00611   {}
00612   longlong val_int();
00613   enum Functype functype() const { return EQ_FUNC; }
00614   enum Functype rev_functype() const { return EQ_FUNC; }
00615   cond_result eq_cmp_result() const { return COND_TRUE; }
00616   const char *func_name() const { return "="; }
00617   Item *negated_item();
00618   virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
00619   virtual Item* equality_substitution_transformer(uchar *arg);
00620 };
00621 
00622 class Item_func_equal :public Item_bool_rowready_func2
00623 {
00624 public:
00625   Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
00626   longlong val_int();
00627   void fix_length_and_dec();
00628   table_map not_null_tables() const { return 0; }
00629   enum Functype functype() const { return EQUAL_FUNC; }
00630   enum Functype rev_functype() const { return EQUAL_FUNC; }
00631   cond_result eq_cmp_result() const { return COND_TRUE; }
00632   const char *func_name() const { return "<=>"; }
00633   Item *neg_transformer(THD *thd) { return 0; }
00634 };
00635 
00636 
00637 class Item_func_ge :public Item_bool_rowready_func2
00638 {
00639 public:
00640   Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
00641   longlong val_int();
00642   enum Functype functype() const { return GE_FUNC; }
00643   enum Functype rev_functype() const { return LE_FUNC; }
00644   cond_result eq_cmp_result() const { return COND_TRUE; }
00645   const char *func_name() const { return ">="; }
00646   Item *negated_item();
00647 };
00648 
00649 
00650 class Item_func_gt :public Item_bool_rowready_func2
00651 {
00652 public:
00653   Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
00654   longlong val_int();
00655   enum Functype functype() const { return GT_FUNC; }
00656   enum Functype rev_functype() const { return LT_FUNC; }
00657   cond_result eq_cmp_result() const { return COND_FALSE; }
00658   const char *func_name() const { return ">"; }
00659   Item *negated_item();
00660 };
00661 
00662 
00663 class Item_func_le :public Item_bool_rowready_func2
00664 {
00665 public:
00666   Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
00667   longlong val_int();
00668   enum Functype functype() const { return LE_FUNC; }
00669   enum Functype rev_functype() const { return GE_FUNC; }
00670   cond_result eq_cmp_result() const { return COND_TRUE; }
00671   const char *func_name() const { return "<="; }
00672   Item *negated_item();
00673 };
00674 
00675 
00676 class Item_func_lt :public Item_bool_rowready_func2
00677 {
00678 public:
00679   Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
00680   longlong val_int();
00681   enum Functype functype() const { return LT_FUNC; }
00682   enum Functype rev_functype() const { return GT_FUNC; }
00683   cond_result eq_cmp_result() const { return COND_FALSE; }
00684   const char *func_name() const { return "<"; }
00685   Item *negated_item();
00686 };
00687 
00688 
00689 class Item_func_ne :public Item_bool_rowready_func2
00690 {
00691 public:
00692   Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
00693   longlong val_int();
00694   enum Functype functype() const { return NE_FUNC; }
00695   cond_result eq_cmp_result() const { return COND_FALSE; }
00696   optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
00697   const char *func_name() const { return "<>"; }
00698   Item *negated_item();
00699 };
00700 
00701 
00702 /*
00703   The class Item_func_opt_neg is defined to factor out the functionality
00704   common for the classes Item_func_between and Item_func_in. The objects
00705   of these classes can express predicates or there negations.
00706   The alternative approach would be to create pairs Item_func_between,
00707   Item_func_notbetween and Item_func_in, Item_func_notin.
00708 
00709 */
00710 
00711 class Item_func_opt_neg :public Item_int_func
00712 {
00713 public:
00714   bool negated;     /* <=> the item represents NOT <func> */
00715   bool pred_level;  /* <=> [NOT] <func> is used on a predicate level */
00716 public:
00717   Item_func_opt_neg(Item *a, Item *b, Item *c)
00718     :Item_int_func(a, b, c), negated(0), pred_level(0) {}
00719   Item_func_opt_neg(List<Item> &list)
00720     :Item_int_func(list), negated(0), pred_level(0) {}
00721 public:
00722   inline void negate() { negated= !negated; }
00723   inline void top_level_item() { pred_level= 1; }
00724   Item *neg_transformer(THD *thd)
00725   {
00726     negated= !negated;
00727     return this;
00728   }
00729   bool eq(const Item *item, bool binary_cmp) const;
00730   bool subst_argument_checker(uchar **arg) { return TRUE; }
00731 };
00732 
00733 
00734 class Item_func_between :public Item_func_opt_neg
00735 {
00736   DTCollation cmp_collation;
00737 public:
00738   Item_result cmp_type;
00739   String value0,value1,value2;
00740   /* TRUE <=> arguments will be compared as dates. */
00741   bool compare_as_dates_with_strings;
00742   bool compare_as_temporal_dates;
00743   bool compare_as_temporal_times;
00744   
00745   /* Comparators used for DATE/DATETIME comparison. */
00746   Arg_comparator ge_cmp, le_cmp;
00747   Item_func_between(Item *a, Item *b, Item *c)
00748     :Item_func_opt_neg(a, b, c), compare_as_dates_with_strings(FALSE),
00749     compare_as_temporal_dates(FALSE),
00750     compare_as_temporal_times(FALSE) {}
00751   longlong val_int();
00752   optimize_type select_optimize() const { return OPTIMIZE_KEY; }
00753   enum Functype functype() const   { return BETWEEN; }
00754   const char *func_name() const { return "between"; }
00755   bool fix_fields(THD *, Item **);
00756   void fix_after_pullout(st_select_lex *parent_select,
00757                          st_select_lex *removed_select);
00758   void fix_length_and_dec();
00759   virtual void print(String *str, enum_query_type query_type);
00760   bool is_bool_func() { return 1; }
00761   const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
00762   uint decimal_precision() const { return 1; }
00763 };
00764 
00765 
00766 class Item_func_strcmp :public Item_bool_func2
00767 {
00768 public:
00769   Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
00770   longlong val_int();
00771   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
00772   const char *func_name() const { return "strcmp"; }
00773 
00774   virtual inline void print(String *str, enum_query_type query_type)
00775   {
00776     Item_func::print(str, query_type);
00777   }
00778   void fix_length_and_dec()
00779   {
00780     Item_bool_func2::fix_length_and_dec();
00781     fix_char_length(2); // returns "1" or "0" or "-1"
00782   }
00783 };
00784 
00785 
00786 struct interval_range
00787 {
00788   Item_result type;
00789   double dbl;
00790   my_decimal dec;
00791 };
00792 
00793 class Item_func_interval :public Item_int_func
00794 {
00795   Item_row *row;
00796   my_bool use_decimal_comparison;
00797   interval_range *intervals;
00798 public:
00799   Item_func_interval(Item_row *a)
00800     :Item_int_func(a),row(a),intervals(0)
00801   {
00802     allowed_arg_cols= 0;    // Fetch this value from first argument
00803   }
00804   longlong val_int();
00805   void fix_length_and_dec();
00806   const char *func_name() const { return "interval"; }
00807   uint decimal_precision() const { return 2; }
00808 };
00809 
00810 
00811 class Item_func_coalesce :public Item_func_numhybrid
00812 {
00813 protected:
00814   enum_field_types cached_field_type;
00815   Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
00816 public:
00817   Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
00818   double real_op();
00819   longlong int_op();
00820   String *str_op(String *);
00821   bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
00822   bool time_op(MYSQL_TIME *ltime);
00823   my_decimal *decimal_op(my_decimal *);
00824   void fix_length_and_dec();
00825   void find_num_type() {}
00826   enum Item_result result_type () const { return hybrid_type; }
00827   const char *func_name() const { return "coalesce"; }
00828   table_map not_null_tables() const { return 0; }
00829   enum_field_types field_type() const { return cached_field_type; }
00830 };
00831 
00832 
00833 class Item_func_ifnull :public Item_func_coalesce
00834 {
00835 protected:
00836   bool field_type_defined;
00837 public:
00838   Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
00839   double real_op();
00840   longlong int_op();
00841   String *str_op(String *str);
00842   bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
00843   bool time_op(MYSQL_TIME *ltime);
00844   my_decimal *decimal_op(my_decimal *);
00845   void fix_length_and_dec();
00846   const char *func_name() const { return "ifnull"; }
00847   Field *tmp_table_field(TABLE *table);
00848   uint decimal_precision() const;
00849 };
00850 
00851 
00852 class Item_func_if :public Item_func
00853 {
00854   enum Item_result cached_result_type;
00855   enum_field_types cached_field_type;
00856 public:
00857   Item_func_if(Item *a,Item *b,Item *c)
00858     :Item_func(a,b,c), cached_result_type(INT_RESULT)
00859   {}
00860   double val_real();
00861   longlong val_int();
00862   String *val_str(String *str);
00863   my_decimal *val_decimal(my_decimal *);
00864   bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
00865   bool get_time(MYSQL_TIME *ltime);
00866   enum Item_result result_type () const { return cached_result_type; }
00867   enum_field_types field_type() const { return cached_field_type; }
00868   bool fix_fields(THD *, Item **);
00869   void fix_length_and_dec();
00870   void fix_after_pullout(st_select_lex *parent_select,
00871                          st_select_lex *removed_select);
00872   uint decimal_precision() const;
00873   const char *func_name() const { return "if"; }
00874 private:
00875   void cache_type_info(Item *source);
00876 };
00877 
00878 
00879 class Item_func_nullif :public Item_bool_func2
00880 {
00881   enum Item_result cached_result_type;
00882 public:
00883   Item_func_nullif(Item *a,Item *b)
00884     :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
00885   {}
00886   double val_real();
00887   longlong val_int();
00888   String *val_str(String *str);
00889   my_decimal *val_decimal(my_decimal *);
00890   enum Item_result result_type () const { return cached_result_type; }
00891   void fix_length_and_dec();
00892   uint decimal_precision() const { return args[0]->decimal_precision(); }
00893   const char *func_name() const { return "nullif"; }
00894 
00895   virtual inline void print(String *str, enum_query_type query_type)
00896   {
00897     Item_func::print(str, query_type);
00898   }
00899 
00900   table_map not_null_tables() const { return 0; }
00901   bool is_null();
00902 };
00903 
00904 
00905 /* Functions to handle the optimized IN */
00906 
00907 
00908 /* A vector of values of some type  */
00909 
00910 class in_vector :public Sql_alloc
00911 {
00912 public:
00913   char *base;
00914   uint size;
00915   qsort2_cmp compare;
00916   const CHARSET_INFO *collation;
00917   uint count;
00918   uint used_count;
00919   in_vector() {}
00920   in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 
00921             const CHARSET_INFO *cmp_coll)
00922     :base((char*) sql_calloc(elements*element_length)),
00923      size(element_length), compare(cmp_func), collation(cmp_coll),
00924      count(elements), used_count(elements) {}
00925   virtual ~in_vector() {}
00926   virtual void set(uint pos,Item *item)=0;
00927   virtual uchar *get_value(Item *item)=0;
00928   void sort()
00929   {
00930     my_qsort2(base,used_count,size,compare,collation);
00931   }
00932   int find(Item *item);
00933   
00934   /* 
00935     Create an instance of Item_{type} (e.g. Item_decimal) constant object
00936     which type allows it to hold an element of this vector without any
00937     conversions.
00938     The purpose of this function is to be able to get elements of this
00939     vector in form of Item_xxx constants without creating Item_xxx object
00940     for every array element you get (i.e. this implements "FlyWeight" pattern)
00941   */
00942   virtual Item* create_item() { return NULL; }
00943   
00944   /*
00945     Store the value at position #pos into provided item object
00946     SYNOPSIS
00947       value_to_item()
00948         pos   Index of value to store
00949         item  Constant item to store value into. The item must be of the same
00950               type that create_item() returns.
00951   */
00952   virtual void value_to_item(uint pos, Item *item) { }
00953   
00954   /* Compare values number pos1 and pos2 for equality */
00955   bool compare_elems(uint pos1, uint pos2)
00956   {
00957     return MY_TEST(compare(collation, base + pos1*size, base + pos2*size));
00958   }
00959   virtual Item_result result_type()= 0;
00960 };
00961 
00962 class in_string :public in_vector
00963 {
00964   char buff[STRING_BUFFER_USUAL_SIZE];
00965   String tmp;
00966 public:
00967   in_string(uint elements,qsort2_cmp cmp_func, const CHARSET_INFO *cs);
00968   ~in_string();
00969   void set(uint pos,Item *item);
00970   uchar *get_value(Item *item);
00971   Item* create_item()
00972   { 
00973     return new Item_string(collation);
00974   }
00975   void value_to_item(uint pos, Item *item)
00976   {    
00977     String *str=((String*) base)+pos;
00978     Item_string *to= (Item_string*)item;
00979     to->str_value= *str;
00980   }
00981   Item_result result_type() { return STRING_RESULT; }
00982 };
00983 
00984 class in_longlong :public in_vector
00985 {
00986 protected:
00987   /*
00988     Here we declare a temporary variable (tmp) of the same type as the
00989     elements of this vector. tmp is used in finding if a given value is in 
00990     the list. 
00991   */
00992   struct packed_longlong 
00993   {
00994     longlong val;
00995     longlong unsigned_flag;  // Use longlong, not bool, to preserve alignment
00996   } tmp;
00997 public:
00998   in_longlong(uint elements);
00999   void set(uint pos,Item *item);
01000   uchar *get_value(Item *item);
01001   
01002   Item* create_item()
01003   { 
01004     /* 
01005       We're created a signed INT, this may not be correct in 
01006       general case (see BUG#19342).
01007     */
01008     return new Item_int((longlong)0);
01009   }
01010   void value_to_item(uint pos, Item *item)
01011   {
01012     ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
01013     ((Item_int*) item)->unsigned_flag= (my_bool)
01014       ((packed_longlong*) base)[pos].unsigned_flag;
01015   }
01016   Item_result result_type() { return INT_RESULT; }
01017 
01018   friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
01019 };
01020 
01021 
01022 class in_datetime_as_longlong :public in_longlong
01023 {
01024 public:
01025   in_datetime_as_longlong(uint elements)
01026     :in_longlong(elements) {};
01027   Item *create_item()
01028   {
01029     return new Item_temporal(MYSQL_TYPE_DATETIME, 0LL);
01030   }
01031   void set(uint pos, Item *item);
01032   uchar *get_value(Item *item);
01033 };
01034 
01035 
01036 class in_time_as_longlong :public in_longlong
01037 {
01038 public:
01039   in_time_as_longlong(uint elements)
01040     :in_longlong(elements) {};
01041   Item *create_item()
01042   {
01043     return new Item_temporal(MYSQL_TYPE_TIME, 0LL);
01044   }
01045   void set(uint pos, Item *item);
01046   uchar *get_value(Item *item);
01047 };
01048 
01049 
01050 /*
01051   Class to represent a vector of constant DATE/DATETIME values.
01052   Values are obtained with help of the get_datetime_value() function.
01053   If the left item is a constant one then its value is cached in the
01054   lval_cache variable.
01055 */
01056 class in_datetime :public in_longlong
01057 {
01058 public:
01059   THD *thd;
01060   /* An item used to issue warnings. */
01061   Item *warn_item;
01062   /* Cache for the left item. */
01063   Item *lval_cache;
01064 
01065   in_datetime(Item *warn_item_arg, uint elements)
01066     :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
01067      lval_cache(0) {};
01068   void set(uint pos,Item *item);
01069   uchar *get_value(Item *item);
01070   friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
01071   Item* create_item()
01072   { 
01073     return new Item_temporal(MYSQL_TYPE_DATETIME, (longlong) 0);
01074   }
01075 };
01076 
01077 
01078 class in_double :public in_vector
01079 {
01080   double tmp;
01081 public:
01082   in_double(uint elements);
01083   void set(uint pos,Item *item);
01084   uchar *get_value(Item *item);
01085   Item *create_item()
01086   { 
01087     return new Item_float(0.0, 0);
01088   }
01089   void value_to_item(uint pos, Item *item)
01090   {
01091     ((Item_float*)item)->value= ((double*) base)[pos];
01092   }
01093   Item_result result_type() { return REAL_RESULT; }
01094 };
01095 
01096 
01097 class in_decimal :public in_vector
01098 {
01099   my_decimal val;
01100 public:
01101   in_decimal(uint elements);
01102   void set(uint pos, Item *item);
01103   uchar *get_value(Item *item);
01104   Item *create_item()
01105   { 
01106     return new Item_decimal(0, FALSE);
01107   }
01108   void value_to_item(uint pos, Item *item)
01109   {
01110     my_decimal *dec= ((my_decimal *)base) + pos;
01111     Item_decimal *item_dec= (Item_decimal*)item;
01112     item_dec->set_decimal_value(dec);
01113   }
01114   Item_result result_type() { return DECIMAL_RESULT; }
01115 
01116 };
01117 
01118 
01119 /*
01120 ** Classes for easy comparing of non const items
01121 */
01122 
01123 class cmp_item :public Sql_alloc
01124 {
01125 public:
01126   const CHARSET_INFO *cmp_charset;
01127   cmp_item() { cmp_charset= &my_charset_bin; }
01128   virtual ~cmp_item() {}
01129   virtual void store_value(Item *item)= 0;
01130   virtual int cmp(Item *item)= 0;
01131   // for optimized IN with row
01132   virtual int compare(cmp_item *item)= 0;
01133   static cmp_item* get_comparator(Item_result type, const CHARSET_INFO *cs);
01134   virtual cmp_item *make_same()= 0;
01135   virtual void store_value_by_template(cmp_item *tmpl, Item *item)
01136   {
01137     store_value(item);
01138   }
01139 };
01140 
01141 class cmp_item_string :public cmp_item 
01142 {
01143 protected:
01144   String *value_res;
01145 public:
01146   cmp_item_string () {}
01147   cmp_item_string (const CHARSET_INFO *cs) { cmp_charset= cs; }
01148   void set_charset(const CHARSET_INFO *cs) { cmp_charset= cs; }
01149   friend class cmp_item_sort_string;
01150   friend class cmp_item_sort_string_in_static;
01151 };
01152 
01153 class cmp_item_sort_string :public cmp_item_string
01154 {
01155 protected:
01156   char value_buff[STRING_BUFFER_USUAL_SIZE];
01157   String value;
01158 public:
01159   cmp_item_sort_string():
01160     cmp_item_string() {}
01161   cmp_item_sort_string(const CHARSET_INFO *cs):
01162     cmp_item_string(cs),
01163     value(value_buff, sizeof(value_buff), cs) {}
01164   void store_value(Item *item)
01165   {
01166     String *res= item->val_str(&value);
01167     if(res && (res != &value))
01168     {
01169       // 'res' may point in item's temporary internal data, so make a copy
01170       value.copy(*res);
01171     }
01172     value_res= &value;
01173   }
01174   int cmp(Item *arg)
01175   {
01176     char buff[STRING_BUFFER_USUAL_SIZE];
01177     String tmp(buff, sizeof(buff), cmp_charset), *res;
01178     res= arg->val_str(&tmp);
01179     return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
01180             (res ? -1 : 0));
01181   }
01182   int compare(cmp_item *ci)
01183   {
01184     cmp_item_string *l_cmp= (cmp_item_string *) ci;
01185     return sortcmp(value_res, l_cmp->value_res, cmp_charset);
01186   } 
01187   cmp_item *make_same();
01188   void set_charset(const CHARSET_INFO *cs)
01189   {
01190     cmp_charset= cs;
01191     value.set_quick(value_buff, sizeof(value_buff), cs);
01192   }
01193 };
01194 
01195 class cmp_item_int :public cmp_item
01196 {
01197   longlong value;
01198 public:
01199   cmp_item_int() {}                           /* Remove gcc warning */
01200   void store_value(Item *item)
01201   {
01202     value= item->val_int();
01203   }
01204   int cmp(Item *arg)
01205   {
01206     return value != arg->val_int();
01207   }
01208   int compare(cmp_item *ci)
01209   {
01210     cmp_item_int *l_cmp= (cmp_item_int *)ci;
01211     return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
01212   }
01213   cmp_item *make_same();
01214 };
01215 
01216 /*
01217   Compare items in the DATETIME context.
01218   Values are obtained with help of the get_datetime_value() function.
01219   If the left item is a constant one then its value is cached in the
01220   lval_cache variable.
01221 */
01222 class cmp_item_datetime :public cmp_item
01223 {
01224   longlong value;
01225 public:
01226   THD *thd;
01227   /* Item used for issuing warnings. */
01228   Item *warn_item;
01229   /* Cache for the left item. */
01230   Item *lval_cache;
01231 
01232   cmp_item_datetime(Item *warn_item_arg)
01233     :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
01234   void store_value(Item *item);
01235   int cmp(Item *arg);
01236   int compare(cmp_item *ci);
01237   cmp_item *make_same();
01238 };
01239 
01240 class cmp_item_real :public cmp_item
01241 {
01242   double value;
01243 public:
01244   cmp_item_real() {}                          /* Remove gcc warning */
01245   void store_value(Item *item)
01246   {
01247     value= item->val_real();
01248   }
01249   int cmp(Item *arg)
01250   {
01251     return value != arg->val_real();
01252   }
01253   int compare(cmp_item *ci)
01254   {
01255     cmp_item_real *l_cmp= (cmp_item_real *) ci;
01256     return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
01257   }
01258   cmp_item *make_same();
01259 };
01260 
01261 
01262 class cmp_item_decimal :public cmp_item
01263 {
01264   my_decimal value;
01265 public:
01266   cmp_item_decimal() {}                       /* Remove gcc warning */
01267   void store_value(Item *item);
01268   int cmp(Item *arg);
01269   int compare(cmp_item *c);
01270   cmp_item *make_same();
01271 };
01272 
01273 
01274 /* 
01275    cmp_item for optimized IN with row (right part string, which never
01276    be changed)
01277 */
01278 
01279 class cmp_item_sort_string_in_static :public cmp_item_string
01280 {
01281  protected:
01282   String value;
01283 public:
01284   cmp_item_sort_string_in_static(const CHARSET_INFO *cs):
01285     cmp_item_string(cs) {}
01286   void store_value(Item *item)
01287   {
01288     value_res= item->val_str(&value);
01289   }
01290   int cmp(Item *item)
01291   {
01292     // Should never be called
01293     DBUG_ASSERT(0);
01294     return 1;
01295   }
01296   int compare(cmp_item *ci)
01297   {
01298     cmp_item_string *l_cmp= (cmp_item_string *) ci;
01299     return sortcmp(value_res, l_cmp->value_res, cmp_charset);
01300   }
01301   cmp_item *make_same()
01302   {
01303     return new cmp_item_sort_string_in_static(cmp_charset);
01304   }
01305 };
01306 
01307 
01308 /*
01309   The class Item_func_case is the CASE ... WHEN ... THEN ... END function
01310   implementation.
01311 
01312   When there is no expression between CASE and the first WHEN 
01313   (the CASE expression) then this function simple checks all WHEN expressions
01314   one after another. When some WHEN expression evaluated to TRUE then the
01315   value of the corresponding THEN expression is returned.
01316 
01317   When the CASE expression is specified then it is compared to each WHEN
01318   expression individually. When an equal WHEN expression is found
01319   corresponding THEN expression is returned.
01320   In order to do correct comparisons several comparators are used. One for
01321   each result type. Different result types that are used in particular
01322   CASE ... END expression are collected in the fix_length_and_dec() member
01323   function and only comparators for there result types are used.
01324 */
01325 
01326 class Item_func_case :public Item_func
01327 {
01328   int first_expr_num, else_expr_num;
01329   enum Item_result cached_result_type, left_result_type;
01330   String tmp_value;
01331   uint ncases;
01332   Item_result cmp_type;
01333   DTCollation cmp_collation;
01334   enum_field_types cached_field_type;
01335   cmp_item *cmp_items[5]; /* For all result types */
01336   cmp_item *case_item;
01337 public:
01338   Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
01339     :Item_func(), first_expr_num(-1), else_expr_num(-1),
01340     cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
01341   {
01342     ncases= list.elements;
01343     if (first_expr_arg)
01344     {
01345       first_expr_num= list.elements;
01346       list.push_back(first_expr_arg);
01347     }
01348     if (else_expr_arg)
01349     {
01350       else_expr_num= list.elements;
01351       list.push_back(else_expr_arg);
01352     }
01353     set_arguments(list);
01354     memset(&cmp_items, 0, sizeof(cmp_items));
01355   }
01356   double val_real();
01357   longlong val_int();
01358   String *val_str(String *);
01359   my_decimal *val_decimal(my_decimal *);
01360   bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
01361   bool get_time(MYSQL_TIME *ltime);
01362   bool fix_fields(THD *thd, Item **ref);
01363   void fix_length_and_dec();
01364   uint decimal_precision() const;
01365   table_map not_null_tables() const { return 0; }
01366   enum Item_result result_type () const { return cached_result_type; }
01367   enum_field_types field_type() const { return cached_field_type; }
01368   const char *func_name() const { return "case"; }
01369   virtual void print(String *str, enum_query_type query_type);
01370   Item *find_item(String *str);
01371   const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
01372   void cleanup();
01373   void agg_num_lengths(Item *arg);
01374 };
01375 
01376 /*
01377   The Item_func_in class implements the in_expr IN(values_list) function.
01378 
01379   The current implementation distinguishes 2 cases:
01380   1) all items in the value_list are constants and have the same
01381     result type. This case is handled by in_vector class.
01382   2) items in the value_list have different result types or there is some
01383     non-constant items.
01384     In this case Item_func_in employs several cmp_item objects to performs
01385     comparisons of in_expr and an item from the values_list. One cmp_item
01386     object for each result type. Different result types are collected in the
01387     fix_length_and_dec() member function by means of collect_cmp_types()
01388     function.
01389 */
01390 class Item_func_in :public Item_func_opt_neg
01391 {
01392 public:
01393   /* 
01394     an array of values when the right hand arguments of IN
01395     are all SQL constant and there are no nulls 
01396   */
01397   in_vector *array;
01398   bool have_null;
01399   /* 
01400     true when all arguments of the IN clause are of compatible types
01401     and can be used safely as comparisons for key conditions
01402   */
01403   bool arg_types_compatible;
01404   Item_result left_result_type;
01405   cmp_item *cmp_items[6]; /* One cmp_item for each result type */
01406   DTCollation cmp_collation;
01407 
01408   Item_func_in(List<Item> &list)
01409     :Item_func_opt_neg(list), array(0), have_null(0),
01410     arg_types_compatible(FALSE)
01411   {
01412     memset(&cmp_items, 0, sizeof(cmp_items));
01413     allowed_arg_cols= 0;  // Fetch this value from first argument
01414   }
01415   longlong val_int();
01416   bool fix_fields(THD *, Item **);
01417   void fix_after_pullout(st_select_lex *parent_select,
01418                          st_select_lex *removed_select);
01419   void fix_length_and_dec();
01420   uint decimal_precision() const { return 1; }
01421   void cleanup()
01422   {
01423     uint i;
01424     DBUG_ENTER("Item_func_in::cleanup");
01425     Item_int_func::cleanup();
01426     delete array;
01427     array= 0;
01428     for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
01429     {
01430       delete cmp_items[i];
01431       cmp_items[i]= 0;
01432     }
01433     DBUG_VOID_RETURN;
01434   }
01435   optimize_type select_optimize() const
01436     { return OPTIMIZE_KEY; }
01437   virtual void print(String *str, enum_query_type query_type);
01438   enum Functype functype() const { return IN_FUNC; }
01439   const char *func_name() const { return " IN "; }
01440   bool nulls_in_row();
01441   bool is_bool_func() { return 1; }
01442   const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
01443 };
01444 
01445 class cmp_item_row :public cmp_item
01446 {
01447   cmp_item **comparators;
01448   uint n;
01449 public:
01450   cmp_item_row(): comparators(0), n(0) {}
01451   ~cmp_item_row();
01452   void store_value(Item *item);
01453   inline void alloc_comparators();
01454   int cmp(Item *arg);
01455   int compare(cmp_item *arg);
01456   cmp_item *make_same();
01457   void store_value_by_template(cmp_item *tmpl, Item *);
01458   friend void Item_func_in::fix_length_and_dec();
01459 };
01460 
01461 
01462 class in_row :public in_vector
01463 {
01464   cmp_item_row tmp;
01465 public:
01466   in_row(uint elements, Item *);
01467   ~in_row();
01468   void set(uint pos,Item *item);
01469   uchar *get_value(Item *item);
01470   friend void Item_func_in::fix_length_and_dec();
01471   Item_result result_type() { return ROW_RESULT; }
01472 };
01473 
01474 /* Functions used by where clause */
01475 
01476 class Item_func_isnull :public Item_bool_func
01477 {
01478 protected:
01479   longlong cached_value;
01480 public:
01481   Item_func_isnull(Item *a) :Item_bool_func(a) {}
01482   longlong val_int();
01483   enum Functype functype() const { return ISNULL_FUNC; }
01484   void fix_length_and_dec()
01485   {
01486     decimals=0; max_length=1; maybe_null=0;
01487     update_used_tables();
01488   }
01489   const char *func_name() const { return "isnull"; }
01490   /* Optimize case of not_null_column IS NULL */
01491   virtual void update_used_tables()
01492   {
01493     if (!args[0]->maybe_null)
01494     {
01495       used_tables_cache= 0;                     /* is always false */
01496       const_item_cache= 1;
01497       cached_value= (longlong) 0;
01498     }
01499     else
01500     {
01501       args[0]->update_used_tables();
01502       with_subselect= args[0]->has_subquery();
01503       with_stored_program= args[0]->has_stored_program();
01504 
01505       if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
01506            !with_subselect && !with_stored_program))
01507       {
01508         /* Remember if the value is always NULL or never NULL */
01509         cached_value= (longlong) args[0]->is_null();
01510       }
01511     }
01512   }
01513   table_map not_null_tables() const { return 0; }
01514   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
01515   Item *neg_transformer(THD *thd);
01516   const CHARSET_INFO *compare_collation()
01517   { return args[0]->collation.collation; }
01518 };
01519 
01520 /* Functions used by HAVING for rewriting IN subquery */
01521 
01522 class Item_in_subselect;
01523 
01524 /* 
01525   This is like IS NOT NULL but it also remembers if it ever has
01526   encountered a NULL; it remembers this in the "was_null" property of the
01527   "owner" item.
01528 */
01529 class Item_is_not_null_test :public Item_func_isnull
01530 {
01531   Item_in_subselect* owner;
01532 public:
01533   Item_is_not_null_test(Item_in_subselect* ow, Item *a)
01534     :Item_func_isnull(a), owner(ow)
01535   {}
01536   enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
01537   longlong val_int();
01538   const char *func_name() const { return "<is_not_null_test>"; }
01539   void update_used_tables();
01545   table_map get_initial_pseudo_tables() const { return RAND_TABLE_BIT; }
01546 };
01547 
01548 
01549 class Item_func_isnotnull :public Item_bool_func
01550 {
01551   bool abort_on_null;
01552 public:
01553   Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
01554   longlong val_int();
01555   enum Functype functype() const { return ISNOTNULL_FUNC; }
01556   void fix_length_and_dec()
01557   {
01558     decimals=0; max_length=1; maybe_null=0;
01559   }
01560   const char *func_name() const { return "isnotnull"; }
01561   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
01562   table_map not_null_tables() const
01563   { return abort_on_null ? not_null_tables_cache : 0; }
01564   Item *neg_transformer(THD *thd);
01565   virtual void print(String *str, enum_query_type query_type);
01566   const CHARSET_INFO *compare_collation()
01567   { return args[0]->collation.collation; }
01568   void top_level_item() { abort_on_null=1; }
01569 };
01570 
01571 
01572 class Item_func_like :public Item_bool_func2
01573 {
01574   // Turbo Boyer-Moore data
01575   bool        canDoTurboBM;     // pattern is '%abcd%' case
01576   const char* pattern;
01577   int         pattern_len;
01578 
01579   // TurboBM buffers, *this is owner
01580   int* bmGs; //   good suffix shift table, size is pattern_len + 1
01581   int* bmBc; // bad character shift table, size is alphabet_size
01582 
01583   void turboBM_compute_suffixes(int* suff);
01584   void turboBM_compute_good_suffix_shifts(int* suff);
01585   void turboBM_compute_bad_character_shifts();
01586   bool turboBM_matches(const char* text, int text_len) const;
01587   enum { alphabet_size = 256 };
01588 
01589   Item *escape_item;
01590   
01591   bool escape_used_in_parsing;
01592 
01593 public:
01594   int escape;
01595 
01596   Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
01597     :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), 
01598      bmGs(0), bmBc(0), escape_item(escape_arg),
01599      escape_used_in_parsing(escape_used) {}
01600   longlong val_int();
01601   enum Functype functype() const { return LIKE_FUNC; }
01602   optimize_type select_optimize() const;
01603   cond_result eq_cmp_result() const { return COND_TRUE; }
01604   const char *func_name() const { return "like"; }
01605   bool fix_fields(THD *thd, Item **ref);
01606   void cleanup();
01611   bool escape_was_used_in_parsing() const { return escape_used_in_parsing; }
01612 };
01613 
01614 
01615 class Item_func_regex :public Item_bool_func
01616 {
01617   my_regex_t preg;
01618   bool regex_compiled;
01619   bool regex_is_const;
01620   String prev_regexp;
01621   DTCollation cmp_collation;
01622   const CHARSET_INFO *regex_lib_charset;
01623   int regex_lib_flags;
01624   String conv;
01625   int regcomp(bool send_error);
01626 public:
01627   Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
01628     regex_compiled(0),regex_is_const(0) {}
01629   void cleanup();
01630   longlong val_int();
01631   bool fix_fields(THD *thd, Item **ref);
01632   const char *func_name() const { return "regexp"; }
01633 
01634   virtual inline void print(String *str, enum_query_type query_type)
01635   {
01636     print_op(str, query_type);
01637   }
01638 
01639   const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
01640 };
01641 
01642 
01643 class Item_cond :public Item_bool_func
01644 {
01645 protected:
01646   List<Item> list;
01647   bool abort_on_null;
01648 
01649 public:
01650   /* Item_cond() is only used to create top level items */
01651   Item_cond(): Item_bool_func(), abort_on_null(1)
01652   { const_item_cache=0; }
01653   Item_cond(Item *i1,Item *i2)
01654     :Item_bool_func(), abort_on_null(0)
01655   {
01656     list.push_back(i1);
01657     list.push_back(i2);
01658   }
01659   Item_cond(THD *thd, Item_cond *item);
01660   Item_cond(List<Item> &nlist)
01661     :Item_bool_func(), list(nlist), abort_on_null(0) {}
01662   bool add(Item *item)
01663   {
01664     DBUG_ASSERT(item);
01665     return list.push_back(item);
01666   }
01667   bool add_at_head(Item *item)
01668   {
01669     DBUG_ASSERT(item);
01670     return list.push_front(item);
01671   }
01672   void add_at_head(List<Item> *nlist)
01673   {
01674     DBUG_ASSERT(nlist->elements);
01675     list.prepand(nlist);
01676   }
01677   bool fix_fields(THD *, Item **ref);
01678   void fix_after_pullout(st_select_lex *parent_select,
01679                          st_select_lex *removed_select);
01680 
01681   enum Type type() const { return COND_ITEM; }
01682   List<Item>* argument_list() { return &list; }
01683   table_map used_tables() const { return used_tables_cache; }
01684   void update_used_tables();
01685   virtual void print(String *str, enum_query_type query_type);
01686   void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
01687                       List<Item> &fields);
01688   friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
01689                          Item **conds);
01690   void top_level_item() { abort_on_null=1; }
01691   void copy_andor_arguments(THD *thd, Item_cond *item, bool real_items= false);
01692   bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
01693   Item *transform(Item_transformer transformer, uchar *arg);
01694   void traverse_cond(Cond_traverser, void *arg, traverse_order order);
01695   void neg_arguments(THD *thd);
01696   enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
01697   bool subst_argument_checker(uchar **arg) { return TRUE; }
01698   Item *compile(Item_analyzer analyzer, uchar **arg_p,
01699                 Item_transformer transformer, uchar *arg_t);
01700 
01701   virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
01702 };
01703 
01704 
01705 /*
01706   The class Item_equal is used to represent conjunctions of equality
01707   predicates of the form field1 = field2, and field=const in where
01708   conditions and on expressions.
01709 
01710   All equality predicates of the form field1=field2 contained in a
01711   conjunction are substituted for a sequence of items of this class.
01712   An item of this class Item_equal(f1,f2,...fk) represents a
01713   multiple equality f1=f2=...=fk.
01714 
01715   If a conjunction contains predicates f1=f2 and f2=f3, a new item of
01716   this class is created Item_equal(f1,f2,f3) representing the multiple
01717   equality f1=f2=f3 that substitutes the above equality predicates in
01718   the conjunction.
01719   A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
01720   substituted for the item representing the same multiple equality
01721   f1=f2=f3.
01722   An item Item_equal(f1,f2) can appear instead of a conjunction of 
01723   f2=f1 and f1=f2, or instead of just the predicate f1=f2.
01724 
01725   An item of the class Item_equal inherits equalities from outer 
01726   conjunctive levels.
01727 
01728   Suppose we have a where condition of the following form:
01729   WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
01730   In this case:
01731     f1=f2 will be substituted for Item_equal(f1,f2);
01732     f3=f4 and f3=f5  will be substituted for Item_equal(f3,f4,f5);
01733     f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
01734 
01735   An object of the class Item_equal can contain an optional constant
01736   item c. Then it represents a multiple equality of the form 
01737   c=f1=...=fk.
01738 
01739   Objects of the class Item_equal are used for the following:
01740 
01741   1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
01742   pair of tables ti and tj as joined by an equi-condition.
01743   Thus it provide us with additional access paths from table to table.
01744 
01745   2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
01746   SARGable predicates:
01747     f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
01748   It also can give us additional index scans and can allow us to
01749   improve selectivity estimates.
01750 
01751   3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
01752   selected execution plan for the query: if table ti is accessed 
01753   before the table tj then in any predicate P in the where condition
01754   the occurrence of tj.fj is substituted for ti.fi. This can allow
01755   an evaluation of the predicate at an earlier step.
01756 
01757   When feature 1 is supported they say that join transitive closure 
01758   is employed.
01759   When feature 2 is supported they say that search argument transitive
01760   closure is employed.
01761   Both features are usually supported by preprocessing original query and
01762   adding additional predicates.
01763   We do not just add predicates, we rather dynamically replace some
01764   predicates that can not be used to access tables in the investigated
01765   plan for those, obtained by substitution of some fields for equal fields,
01766   that can be used.     
01767 
01768   Prepared Statements/Stored Procedures note: instances of class
01769   Item_equal are created only at the time a PS/SP is executed and
01770   are deleted in the end of execution. All changes made to these
01771   objects need not be registered in the list of changes of the parse
01772   tree and do not harm PS/SP re-execution.
01773 
01774   Item equal objects are employed only at the optimize phase. Usually they are
01775   not supposed to be evaluated.  Yet in some cases we call the method val_int()
01776   for them. We have to take care of restricting the predicate such an
01777   object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
01778 */
01779 struct st_join_table;
01780 
01781 class Item_equal: public Item_bool_func
01782 {
01783   List<Item_field> fields; /* list of equal field items                    */
01784   Item *const_item;        /* optional constant item equal to fields items */
01785   cmp_item *eval_item;
01786   Arg_comparator cmp;
01787   bool cond_false;
01788   bool compare_as_dates;
01789 public:
01790   inline Item_equal()
01791     : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
01792   { const_item_cache=0 ;}
01793   Item_equal(Item_field *f1, Item_field *f2);
01794   Item_equal(Item *c, Item_field *f);
01795   Item_equal(Item_equal *item_equal);
01796   virtual ~Item_equal()
01797   {
01798     delete eval_item;
01799   }
01800 
01801   inline Item* get_const() { return const_item; }
01802   void compare_const(Item *c);
01803   void add(Item *c, Item_field *f);
01804   void add(Item *c);
01805   void add(Item_field *f);
01806   uint members();
01807   bool contains(Field *field);
01813   Item_field* get_first() { return fields.head(); }
01814   Item_field* get_subst_item(const Item_field *field);
01815   void merge(Item_equal *item);
01816   void update_const();
01817   enum Functype functype() const { return MULT_EQUAL_FUNC; }
01818   longlong val_int(); 
01819   const char *func_name() const { return "multiple equal"; }
01820   optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
01821   void sort(Item_field_cmpfunc compare, void *arg);
01822   friend class Item_equal_iterator;
01823   void fix_length_and_dec();
01824   bool fix_fields(THD *thd, Item **ref);
01825   void update_used_tables();
01826   bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
01827   Item *transform(Item_transformer transformer, uchar *arg);
01828   virtual void print(String *str, enum_query_type query_type);
01829   const CHARSET_INFO *compare_collation() 
01830   { return fields.head()->collation.collation; }
01831 
01832   virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
01833 
01834   virtual Item* equality_substitution_transformer(uchar *arg);
01835 }; 
01836 
01837 class COND_EQUAL: public Sql_alloc
01838 {
01839 public:
01840   uint max_members;               /* max number of members the current level
01841                                      list and all lower level lists */ 
01842   COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
01843   List<Item_equal> current_level; /* list of multiple equalities of 
01844                                      the current and level           */
01845   COND_EQUAL()
01846   { 
01847     upper_levels= 0;
01848   }
01849 };
01850 
01851 
01852 class Item_equal_iterator : public List_iterator_fast<Item_field>
01853 {
01854 public:
01855   inline Item_equal_iterator(Item_equal &item_equal) 
01856     :List_iterator_fast<Item_field> (item_equal.fields)
01857   {}
01858   inline Item_field* operator++(int)
01859   { 
01860     Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
01861     return  item;
01862   }
01863   inline void rewind(void) 
01864   { 
01865     List_iterator_fast<Item_field>::rewind();
01866   }
01867 };
01868 
01869 class Item_cond_and :public Item_cond
01870 {
01871 public:
01872   COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
01873                              the current and level and reference
01874                              to multiple equalities of upper and levels */  
01875   Item_cond_and() :Item_cond() {}
01876   Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
01877   Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
01878   Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
01879   enum Functype functype() const { return COND_AND_FUNC; }
01880   longlong val_int();
01881   const char *func_name() const { return "and"; }
01882   Item* copy_andor_structure(THD *thd, bool real_items)
01883   {
01884     Item_cond_and *item;
01885     if ((item= new Item_cond_and(thd, this)))
01886       item->copy_andor_arguments(thd, this, real_items);
01887     return item;
01888   }
01889   Item *neg_transformer(THD *thd);
01890 };
01891 
01892 inline bool is_cond_and(Item *item)
01893 {
01894   if (item->type() != Item::COND_ITEM)
01895     return FALSE;
01896 
01897   Item_cond *cond_item= (Item_cond*) item;
01898   return (cond_item->functype() == Item_func::COND_AND_FUNC);
01899 }
01900 
01901 class Item_cond_or :public Item_cond
01902 {
01903 public:
01904   Item_cond_or() :Item_cond() {}
01905   Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
01906   Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
01907   Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
01908   enum Functype functype() const { return COND_OR_FUNC; }
01909   longlong val_int();
01910   const char *func_name() const { return "or"; }
01911   Item* copy_andor_structure(THD *thd, bool real_items)
01912   {
01913     Item_cond_or *item;
01914     if ((item= new Item_cond_or(thd, this)))
01915       item->copy_andor_arguments(thd, this, real_items);
01916     return item;
01917   }
01918   Item *neg_transformer(THD *thd);
01919 };
01920 
01921 inline bool is_cond_or(Item *item)
01922 {
01923   if (item->type() != Item::COND_ITEM)
01924     return FALSE;
01925 
01926   Item_cond *cond_item= (Item_cond*) item;
01927   return (cond_item->functype() == Item_func::COND_OR_FUNC);
01928 }
01929 
01930 /* Some useful inline functions */
01931 
01932 inline Item *and_conds(Item *a, Item *b)
01933 {
01934   if (!b) return a;
01935   if (!a) return b;
01936   return new Item_cond_and(a, b);
01937 }
01938 
01939 
01940 Item *and_expressions(Item *a, Item *b, Item **org_item);
01941 
01942 longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
01943                             Item *warn_item, bool *is_null);
01944 
01945 
01946 bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
01947                              const char *warn_name, MYSQL_TIME *l_time);
01948 
01949 /*
01950   These need definitions from this file but the variables are defined
01951   in mysqld.h. The variables really belong in this component, but for
01952   the time being we leave them in mysqld.cc to avoid merge problems.
01953 */
01954 extern Eq_creator eq_creator;
01955 extern Ne_creator ne_creator;
01956 extern Gt_creator gt_creator;
01957 extern Lt_creator lt_creator;
01958 extern Ge_creator ge_creator;
01959 extern Le_creator le_creator;
01960 
01961 #endif /* ITEM_CMPFUNC_INCLUDED */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines