Drizzled Public API Documentation

cmpfunc.h
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
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 #pragma once
00021 
00022 /* compare and test functions */
00023 
00024 #include <drizzled/common.h>
00025 #include <drizzled/comp_creator.h>
00026 #include <drizzled/function/math/int.h>
00027 #include <drizzled/function/numhybrid.h>
00028 #include <drizzled/item/decimal.h>
00029 #include <drizzled/item/float.h>
00030 #include <drizzled/item/function/boolean.h>
00031 #include <drizzled/item/int.h>
00032 #include <drizzled/item/row.h>
00033 #include <drizzled/item/string.h>
00034 #include <drizzled/item/sum.h>
00035 #include <drizzled/qsort_cmp.h>
00036 
00037 namespace drizzled
00038 {
00039 
00040 extern Item_result item_cmp_type(Item_result a,Item_result b);
00041 
00042 class Item_bool_func2;
00043 class Arg_comparator;
00044 class Item_sum_hybrid;
00045 class Item_row;
00046 class Session;
00047 
00048 typedef int (Arg_comparator::*arg_cmp_func)();
00049 
00050 typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
00051 
00052 int64_t get_datetime_value(Session *session, 
00053                            Item ***item_arg, 
00054                            Item **cache_arg,
00055                            Item *warn_item, 
00056                            bool *is_null);
00057 
00058 class Arg_comparator: public memory::SqlAlloc
00059 {
00060   Item **a, **b;
00061   arg_cmp_func func;
00062   Item_bool_func2 *owner;
00063   Arg_comparator *comparators;   // used only for compare_row()
00064   double precision;
00065   /* Fields used in DATE/DATETIME comparison. */
00066   Session *session;
00067   enum_field_types a_type, b_type; // Types of a and b items
00068   Item *a_cache, *b_cache;         // Cached values of a and b items
00069   bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
00070   enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
00071                             CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
00072   int64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
00073                             Item *warn_item, bool *is_null);
00074 public:
00075   DTCollation cmp_collation;
00076 
00077   Arg_comparator();
00078 
00079   Arg_comparator(Item **a1, Item **a2);
00080 
00081   int set_compare_func(Item_bool_func2 *owner, Item_result type);
00082   inline int set_compare_func(Item_bool_func2 *owner_arg)
00083   {
00084     return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
00085                                                      (*b)->result_type()));
00086   }
00087   int set_cmp_func(Item_bool_func2 *owner_arg,
00088         Item **a1, Item **a2,
00089         Item_result type);
00090 
00091   inline int set_cmp_func(Item_bool_func2 *owner_arg,
00092         Item **a1, Item **a2)
00093   {
00094     return set_cmp_func(owner_arg, a1, a2,
00095                         item_cmp_type((*a1)->result_type(),
00096                                       (*a2)->result_type()));
00097   }
00098   inline int compare() { return (this->*func)(); }
00099 
00100   int compare_string();    // compare args[0] & args[1]
00101   int compare_binary_string();   // compare args[0] & args[1]
00102   int compare_real();            // compare args[0] & args[1]
00103   int compare_decimal();         // compare args[0] & args[1]
00104   int compare_int_signed();      // compare args[0] & args[1]
00105   int compare_int_signed_unsigned();
00106   int compare_int_unsigned_signed();
00107   int compare_int_unsigned();
00108   int compare_row();             // compare args[0] & args[1]
00109   int compare_e_string();  // compare args[0] & args[1]
00110   int compare_e_binary_string(); // compare args[0] & args[1]
00111   int compare_e_real();          // compare args[0] & args[1]
00112   int compare_e_decimal();       // compare args[0] & args[1]
00113   int compare_e_int();           // compare args[0] & args[1]
00114   int compare_e_int_diff_signedness();
00115   int compare_e_row();           // compare args[0] & args[1]
00116   int compare_real_fixed();
00117   int compare_e_real_fixed();
00118   int compare_datetime();        // compare args[0] & args[1] as DATETIMEs
00119 
00120   static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
00121                                                       int64_t *const_val_arg);
00122 
00123   void set_datetime_cmp_func(Item **a1, Item **b1);
00124   static arg_cmp_func comparator_matrix [5][2];
00125 
00126   friend class Item_func;
00127 };
00128 
00129 
00135 class Item_func_truth : public item::function::Boolean
00136 {
00137 public:
00138   virtual bool val_bool();
00139   virtual int64_t val_int();
00140   virtual void fix_length_and_dec();
00141   virtual void print(String *str);
00142 
00143 protected:
00144   Item_func_truth(Item *a, bool a_value, bool a_affirmative)
00145   : item::function::Boolean(a), value(a_value), affirmative(a_affirmative)
00146   {}
00147 
00148   ~Item_func_truth()
00149   {}
00150 private:
00155   const bool value;
00159   const bool affirmative;
00160 };
00161 
00162 
00167 class Item_func_istrue : public Item_func_truth
00168 {
00169 public:
00170   Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
00171   ~Item_func_istrue() {}
00172   virtual const char* func_name() const { return "istrue"; }
00173 };
00174 
00175 
00180 class Item_func_isnottrue : public Item_func_truth
00181 {
00182 public:
00183   Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
00184   ~Item_func_isnottrue() {}
00185   virtual const char* func_name() const { return "isnottrue"; }
00186 };
00187 
00188 
00193 class Item_func_isfalse : public Item_func_truth
00194 {
00195 public:
00196   Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
00197   ~Item_func_isfalse() {}
00198   virtual const char* func_name() const { return "isfalse"; }
00199 };
00200 
00201 
00206 class Item_func_isnotfalse : public Item_func_truth
00207 {
00208 public:
00209   Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
00210   ~Item_func_isnotfalse() {}
00211   virtual const char* func_name() const { return "isnotfalse"; }
00212 };
00213 
00214 
00215 class Item_cache;
00216 #define UNKNOWN ((bool)-1)
00217 
00218 
00219 /*
00220   Item_in_optimizer(left_expr, Item_in_subselect(...))
00221 
00222   Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
00223   class does the following:
00224    - Evaluate the left expression and store it in Item_cache_* object (to
00225      avoid re-evaluating it many times during subquery execution)
00226    - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
00227      don't care if the result is NULL or FALSE.
00228 
00229   NOTE
00230     It is not quite clear why the above listed functionality should be
00231     placed into a separate class called 'Item_in_optimizer'.
00232 */
00233 
00234 class Item_in_optimizer: public item::function::Boolean
00235 {
00236 protected:
00237   Item_cache *cache;
00238   bool save_cache;
00239   /*
00240     Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
00241       UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
00242       FALSE   - result is FALSE
00243       TRUE    - result is NULL
00244   */
00245   bool result_for_null_param;
00246 public:
00247   Item_in_optimizer(Item *a, Item_in_subselect *b):
00248     item::function::Boolean(a, reinterpret_cast<Item *>(b)), cache(0),
00249     save_cache(0), result_for_null_param(UNKNOWN)
00250   { with_subselect= true; }
00251   bool fix_fields(Session *, Item **);
00252   bool fix_left(Session *session, Item **ref);
00253   bool is_null();
00254   int64_t val_int();
00255   void cleanup();
00256   const char *func_name() const { return "<in_optimizer>"; }
00257   Item_cache **get_cache() { return &cache; }
00258   void keep_top_level_cache();
00259   Item *transform(Item_transformer transformer, unsigned char *arg);
00260 };
00261 
00262 class Eq_creator :public Comp_creator
00263 {
00264 public:
00265   Eq_creator() {}                             /* Remove gcc warning */
00266   virtual ~Eq_creator() {}                    /* Remove gcc warning */
00267   virtual Item_bool_func2* create(Item *a, Item *b) const;
00268   virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
00269   virtual bool eqne_op() const { return 1; }
00270   virtual bool l_op() const { return 0; }
00271   static const Eq_creator *instance();
00272 };
00273 
00274 class Ne_creator :public Comp_creator
00275 {
00276 public:
00277   Ne_creator() {}                             /* Remove gcc warning */
00278   virtual ~Ne_creator() {}                    /* Remove gcc warning */
00279   virtual Item_bool_func2* create(Item *a, Item *b) const;
00280   virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
00281   virtual bool eqne_op() const { return 1; }
00282   virtual bool l_op() const { return 0; }
00283   static const Ne_creator *instance();
00284 };
00285 
00286 class Gt_creator :public Comp_creator
00287 {
00288 public:
00289   Gt_creator() {}                             /* Remove gcc warning */
00290   virtual ~Gt_creator() {}                    /* Remove gcc warning */
00291   virtual Item_bool_func2* create(Item *a, Item *b) const;
00292   virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
00293   virtual bool eqne_op() const { return 0; }
00294   virtual bool l_op() const { return 0; }
00295   static const Gt_creator *instance();
00296 };
00297 
00298 class Lt_creator :public Comp_creator
00299 {
00300 public:
00301   Lt_creator() {}                             /* Remove gcc warning */
00302   virtual ~Lt_creator() {}                    /* Remove gcc warning */
00303   virtual Item_bool_func2* create(Item *a, Item *b) const;
00304   virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
00305   virtual bool eqne_op() const { return 0; }
00306   virtual bool l_op() const { return 1; }
00307   static const Lt_creator *instance();
00308 };
00309 
00310 class Ge_creator :public Comp_creator
00311 {
00312 public:
00313   Ge_creator() {}                             /* Remove gcc warning */
00314   virtual ~Ge_creator() {}                    /* Remove gcc warning */
00315   virtual Item_bool_func2* create(Item *a, Item *b) const;
00316   virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
00317   virtual bool eqne_op() const { return 0; }
00318   virtual bool l_op() const { return 0; }
00319   static const Ge_creator *instance();
00320 };
00321 
00322 class Le_creator :public Comp_creator
00323 {
00324 public:
00325   Le_creator() {}                             /* Remove gcc warning */
00326   virtual ~Le_creator() {}                    /* Remove gcc warning */
00327   virtual Item_bool_func2* create(Item *a, Item *b) const;
00328   virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
00329   virtual bool eqne_op() const { return 0; }
00330   virtual bool l_op() const { return 1; }
00331   static const Le_creator *instance();
00332 };
00333 
00334 class Item_bool_func2 :public Item_int_func
00335 {           /* Bool with 2 string args */
00336 protected:
00337   Arg_comparator cmp;
00338   String tmp_value1,tmp_value2;
00339   bool abort_on_null;
00340 
00341 public:
00342   Item_bool_func2(Item *a,Item *b)
00343     :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(false) {}
00344   void fix_length_and_dec();
00345   void set_cmp_func()
00346   {
00347     cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
00348   }
00349   optimize_type select_optimize() const { return OPTIMIZE_OP; }
00350   virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
00351   bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
00352 
00353   virtual inline void print(String *str)
00354   {
00355     Item_func::print_op(str);
00356   }
00357 
00358   bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
00359   bool is_bool_func() { return 1; }
00360   const CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
00361   uint32_t decimal_precision() const { return 1; }
00362   void top_level_item() { abort_on_null= true; }
00363 
00364   friend class  Arg_comparator;
00365 };
00366 
00367 class Item_bool_rowready_func2 :public Item_bool_func2
00368 {
00369 public:
00370   Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
00371   {
00372     allowed_arg_cols= 0;  // Fetch this value from first argument
00373   }
00374   Item *neg_transformer(Session *session);
00375   virtual Item *negated_item();
00376   bool subst_argument_checker(unsigned char **)
00377   { return true; }
00378 };
00379 
00380 class Item_func_not :public item::function::Boolean
00381 {
00382 public:
00383   Item_func_not(Item *a) :item::function::Boolean(a) {}
00384   int64_t val_int();
00385   enum Functype functype() const { return NOT_FUNC; }
00386   const char *func_name() const { return "not"; }
00387   Item *neg_transformer(Session *session);
00388   virtual void print(String *str);
00389 };
00390 
00391 class Item_maxmin_subselect;
00392 
00393 /*
00394   trigcond<param>(arg) ::= param? arg : TRUE
00395 
00396   The class Item_func_trig_cond is used for guarded predicates
00397   which are employed only for internal purposes.
00398   A guarded predicate is an object consisting of an a regular or
00399   a guarded predicate P and a pointer to a boolean guard variable g.
00400   A guarded predicate P/g is evaluated to true if the value of the
00401   guard g is false, otherwise it is evaluated to the same value that
00402   the predicate P: val(P/g)= g ? val(P):true.
00403   Guarded predicates allow us to include predicates into a conjunction
00404   conditionally. Currently they are utilized for pushed down predicates
00405   in queries with outer join operations.
00406 
00407   In the future, probably, it makes sense to extend this class to
00408   the objects consisting of three elements: a predicate P, a pointer
00409   to a variable g and a firing value s with following evaluation
00410   rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
00411   one item for the objects of the form P/g1/g2...
00412 
00413   Objects of this class are built only for query execution after
00414   the execution plan has been already selected. That's why this
00415   class needs only val_int out of generic methods.
00416 
00417   Current uses of Item_func_trig_cond objects:
00418    - To wrap selection conditions when executing outer joins
00419    - To wrap condition that is pushed down into subquery
00420 */
00421 
00422 class Item_func_trig_cond: public item::function::Boolean
00423 {
00424   bool *trig_var;
00425 public:
00426   Item_func_trig_cond(Item *a, bool *f) : item::function::Boolean(a) { trig_var= f; }
00427   int64_t val_int() { return *trig_var ? args[0]->val_int() : 1; }
00428   enum Functype functype() const { return TRIG_COND_FUNC; };
00429   const char *func_name() const { return "trigcond"; };
00430   bool const_item() const { return false; }
00431   bool *get_trig_var() { return trig_var; }
00432   /* The following is needed for ICP: */
00433   table_map used_tables() const { return args[0]->used_tables(); }
00434 };
00435 
00436 class Item_func_not_all :public Item_func_not
00437 {
00438   /* allow to check presence of values in max/min optimization */
00439   Item_sum_hybrid *test_sum_item;
00440   Item_maxmin_subselect *test_sub_item;
00441 
00442   bool abort_on_null;
00443 public:
00444   bool show;
00445 
00446   Item_func_not_all(Item *a)
00447     :Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
00448      show(0)
00449     {}
00450   virtual void top_level_item() { abort_on_null= 1; }
00451   bool top_level() { return abort_on_null; }
00452   int64_t val_int();
00453   enum Functype functype() const { return NOT_ALL_FUNC; }
00454   const char *func_name() const { return "<not>"; }
00455   virtual void print(String *str);
00456   void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
00457   void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
00458   bool empty_underlying_subquery();
00459   Item *neg_transformer(Session *session);
00460 };
00461 
00462 
00463 class Item_func_nop_all :public Item_func_not_all
00464 {
00465 public:
00466 
00467   Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
00468   int64_t val_int();
00469   const char *func_name() const { return "<nop>"; }
00470   Item *neg_transformer(Session *session);
00471 };
00472 
00473 
00474 class Item_func_eq :public Item_bool_rowready_func2
00475 {
00476 public:
00477   Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
00478   int64_t val_int();
00479   enum Functype functype() const { return EQ_FUNC; }
00480   enum Functype rev_functype() const { return EQ_FUNC; }
00481   cond_result eq_cmp_result() const { return COND_TRUE; }
00482   const char *func_name() const { return "="; }
00483   Item *negated_item();
00484 };
00485 
00486 class Item_func_equal :public Item_bool_rowready_func2
00487 {
00488 public:
00489   Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
00490   int64_t val_int();
00491   void fix_length_and_dec();
00492   table_map not_null_tables() const { return 0; }
00493   enum Functype functype() const { return EQUAL_FUNC; }
00494   enum Functype rev_functype() const { return EQUAL_FUNC; }
00495   cond_result eq_cmp_result() const { return COND_TRUE; }
00496   const char *func_name() const { return "<=>"; }
00497   Item *neg_transformer(Session *) { return 0; }
00498 };
00499 
00500 
00501 class Item_func_ge :public Item_bool_rowready_func2
00502 {
00503 public:
00504   Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
00505   int64_t val_int();
00506   enum Functype functype() const { return GE_FUNC; }
00507   enum Functype rev_functype() const { return LE_FUNC; }
00508   cond_result eq_cmp_result() const { return COND_TRUE; }
00509   const char *func_name() const { return ">="; }
00510   Item *negated_item();
00511 };
00512 
00513 
00514 class Item_func_gt :public Item_bool_rowready_func2
00515 {
00516 public:
00517   Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
00518   int64_t val_int();
00519   enum Functype functype() const { return GT_FUNC; }
00520   enum Functype rev_functype() const { return LT_FUNC; }
00521   cond_result eq_cmp_result() const { return COND_FALSE; }
00522   const char *func_name() const { return ">"; }
00523   Item *negated_item();
00524 };
00525 
00526 
00527 class Item_func_le :public Item_bool_rowready_func2
00528 {
00529 public:
00530   Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
00531   int64_t val_int();
00532   enum Functype functype() const { return LE_FUNC; }
00533   enum Functype rev_functype() const { return GE_FUNC; }
00534   cond_result eq_cmp_result() const { return COND_TRUE; }
00535   const char *func_name() const { return "<="; }
00536   Item *negated_item();
00537 };
00538 
00539 
00540 class Item_func_lt :public Item_bool_rowready_func2
00541 {
00542 public:
00543   Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
00544   int64_t val_int();
00545   enum Functype functype() const { return LT_FUNC; }
00546   enum Functype rev_functype() const { return GT_FUNC; }
00547   cond_result eq_cmp_result() const { return COND_FALSE; }
00548   const char *func_name() const { return "<"; }
00549   Item *negated_item();
00550 };
00551 
00552 
00553 class Item_func_ne :public Item_bool_rowready_func2
00554 {
00555 public:
00556   Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
00557   int64_t val_int();
00558   enum Functype functype() const { return NE_FUNC; }
00559   cond_result eq_cmp_result() const { return COND_FALSE; }
00560   optimize_type select_optimize() const { return OPTIMIZE_KEY; }
00561   const char *func_name() const { return "<>"; }
00562   Item *negated_item();
00563 };
00564 
00565 
00566 /*
00567   The class Item_func_opt_neg is defined to factor out the functionality
00568   common for the classes Item_func_between and Item_func_in. The objects
00569   of these classes can express predicates or there negations.
00570   The alternative approach would be to create pairs Item_func_between,
00571   Item_func_notbetween and Item_func_in, Item_func_notin.
00572 
00573 */
00574 
00575 class Item_func_opt_neg :public Item_int_func
00576 {
00577 public:
00578   bool negated;     /* <=> the item represents NOT <func> */
00579   bool pred_level;  /* <=> [NOT] <func> is used on a predicate level */
00580 public:
00581   Item_func_opt_neg(Item *a, Item *b, Item *c)
00582     :Item_int_func(a, b, c), negated(0), pred_level(0) {}
00583   Item_func_opt_neg(List<Item> &list)
00584     :Item_int_func(list), negated(0), pred_level(0) {}
00585 public:
00586   inline void negate() { negated= !negated; }
00587   inline void top_level_item() { pred_level= 1; }
00588   Item *neg_transformer(Session *)
00589   {
00590     negated= !negated;
00591     return this;
00592   }
00593   bool eq(const Item *item, bool binary_cmp) const;
00594   bool subst_argument_checker(unsigned char **)
00595   { return true; }
00596 };
00597 
00598 
00599 class Item_func_between :public Item_func_opt_neg
00600 {
00601   DTCollation cmp_collation;
00602 public:
00603   Item_result cmp_type;
00604   String value0,value1,value2;
00605   /* TRUE <=> arguments will be compared as dates. */
00606   bool compare_as_dates;
00607   /* Comparators used for DATE/DATETIME comparison. */
00608   Arg_comparator ge_cmp, le_cmp;
00609   Item_func_between(Item *a, Item *b, Item *c)
00610     :Item_func_opt_neg(a, b, c), compare_as_dates(false) {}
00611   int64_t val_int();
00612   optimize_type select_optimize() const { return OPTIMIZE_KEY; }
00613   enum Functype functype() const   { return BETWEEN; }
00614   const char *func_name() const { return "between"; }
00615   bool fix_fields(Session *, Item **);
00616   void fix_length_and_dec();
00617   virtual void print(String *str);
00618   bool is_bool_func() { return 1; }
00619   const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
00620   uint32_t decimal_precision() const { return 1; }
00621 };
00622 
00623 
00624 class Item_func_strcmp :public Item_bool_func2
00625 {
00626 public:
00627   Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
00628   int64_t val_int();
00629   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
00630   const char *func_name() const { return "strcmp"; }
00631 
00632   virtual inline void print(String *str)
00633   {
00634     Item_func::print(str);
00635   }
00636 };
00637 
00638 
00639 struct interval_range
00640 {
00641   Item_result type;
00642   double dbl;
00643   type::Decimal dec;
00644 };
00645 
00646 class Item_func_interval :public Item_int_func
00647 {
00648   Item_row *row;
00649   bool use_decimal_comparison;
00650   interval_range *intervals;
00651 public:
00652   Item_func_interval(Item_row *a)
00653     :Item_int_func(a),row(a),intervals(0)
00654   {
00655     allowed_arg_cols= 0;    // Fetch this value from first argument
00656   }
00657   int64_t val_int();
00658   void fix_length_and_dec();
00659   const char *func_name() const { return "interval"; }
00660   uint32_t decimal_precision() const { return 2; }
00661 };
00662 
00663 
00664 class Item_func_coalesce :public Item_func_numhybrid
00665 {
00666 protected:
00667   enum_field_types cached_field_type;
00668   Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
00669 public:
00670   Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
00671   double real_op();
00672   int64_t int_op();
00673   String *str_op(String *);
00674   type::Decimal *decimal_op(type::Decimal *);
00675   void fix_length_and_dec();
00676   void find_num_type() {}
00677   enum Item_result result_type () const { return hybrid_type; }
00678   const char *func_name() const { return "coalesce"; }
00679   table_map not_null_tables() const { return 0; }
00680   enum_field_types field_type() const { return cached_field_type; }
00681 };
00682 
00683 
00684 class Item_func_ifnull :public Item_func_coalesce
00685 {
00686 protected:
00687   bool field_type_defined;
00688 public:
00689   Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
00690   double real_op();
00691   int64_t int_op();
00692   String *str_op(String *str);
00693   type::Decimal *decimal_op(type::Decimal *);
00694   enum_field_types field_type() const;
00695   void fix_length_and_dec();
00696   const char *func_name() const { return "ifnull"; }
00697   Field *tmp_table_field()
00698   {
00699     return Item_func::tmp_table_field();
00700   }
00701   Field *tmp_table_field(Table *table);
00702   uint32_t decimal_precision() const;
00703 };
00704 
00705 
00706 class Item_func_if :public Item_func
00707 {
00708   enum Item_result cached_result_type;
00709   enum_field_types cached_field_type;
00710 public:
00711   Item_func_if(Item *a,Item *b,Item *c)
00712     :Item_func(a,b,c), cached_result_type(INT_RESULT)
00713   {}
00714   double val_real();
00715   int64_t val_int();
00716   String *val_str(String *str);
00717   type::Decimal *val_decimal(type::Decimal *);
00718   enum Item_result result_type () const { return cached_result_type; }
00719   enum_field_types field_type() const { return cached_field_type; }
00720   bool fix_fields(Session *, Item **);
00721   void fix_length_and_dec();
00722   uint32_t decimal_precision() const;
00723   const char *func_name() const { return "if"; }
00724 };
00725 
00726 
00727 class Item_func_nullif :public Item_bool_func2
00728 {
00729   enum Item_result cached_result_type;
00730 public:
00731   Item_func_nullif(Item *a,Item *b)
00732     :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
00733   {}
00734   double val_real();
00735   int64_t val_int();
00736   String *val_str(String *str);
00737   type::Decimal *val_decimal(type::Decimal *);
00738   enum Item_result result_type () const { return cached_result_type; }
00739   void fix_length_and_dec();
00740   uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
00741   const char *func_name() const { return "nullif"; }
00742 
00743   virtual inline void print(String *str)
00744   {
00745     Item_func::print(str);
00746   }
00747 
00748   table_map not_null_tables() const { return 0; }
00749   bool is_null();
00750 };
00751 
00752 
00753 /* Functions to handle the optimized IN */
00754 
00755 
00756 /* A vector of values of some type  */
00757 
00758 class in_vector :public memory::SqlAlloc
00759 {
00760 public:
00761   char *base;
00762   uint32_t size;
00763   qsort2_cmp compare;
00764   const CHARSET_INFO *collation;
00765   uint32_t count;
00766   uint32_t used_count;
00767   in_vector() {}
00768   in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
00769         const CHARSET_INFO * const cmp_coll)
00770     :base((char*) memory::sql_calloc(elements*element_length)),
00771      size(element_length), compare(cmp_func), collation(cmp_coll),
00772      count(elements), used_count(elements) {}
00773   virtual ~in_vector() {}
00774   virtual void set(uint32_t pos,Item *item)=0;
00775   virtual unsigned char *get_value(Item *item)=0;
00776   void sort();
00777   int find(Item *item);
00778 
00779   /*
00780     Create an instance of Item_{type} (e.g. Item_decimal) constant object
00781     which type allows it to hold an element of this vector without any
00782     conversions.
00783     The purpose of this function is to be able to get elements of this
00784     vector in form of Item_xxx constants without creating Item_xxx object
00785     for every array element you get (i.e. this implements "FlyWeight" pattern)
00786   */
00787   virtual Item* create_item() { return NULL; }
00788 
00789   /*
00790     Store the value at position #pos into provided item object
00791     SYNOPSIS
00792       value_to_item()
00793         pos   Index of value to store
00794         item  Constant item to store value into. The item must be of the same
00795               type that create_item() returns.
00796   */
00797   virtual void value_to_item(uint32_t, Item *) { }
00798 
00799   /* Compare values number pos1 and pos2 for equality */
00800   bool compare_elems(uint32_t pos1, uint32_t pos2)
00801   {
00802     return test(compare(collation, base + pos1*size, base + pos2*size));
00803   }
00804   virtual Item_result result_type()= 0;
00805 };
00806 
00807 class in_string :public in_vector
00808 {
00809   char buff[STRING_BUFFER_USUAL_SIZE];
00810   String tmp;
00811 public:
00812   in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs);
00813   ~in_string();
00814   void set(uint32_t pos,Item *item);
00815   unsigned char *get_value(Item *item);
00816   Item* create_item()
00817   {
00818     return new Item_string(collation);
00819   }
00820   void value_to_item(uint32_t pos, Item *item)
00821   {
00822     String *str=((String*) base)+pos;
00823     Item_string *to= (Item_string*)item;
00824     to->str_value= *str;
00825   }
00826   Item_result result_type() { return STRING_RESULT; }
00827 };
00828 
00829 class in_int64_t :public in_vector
00830 {
00831 protected:
00832   /*
00833     Here we declare a temporary variable (tmp) of the same type as the
00834     elements of this vector. tmp is used in finding if a given value is in
00835     the list.
00836   */
00837   struct packed_int64_t
00838   {
00839     int64_t val;
00840     int64_t unsigned_flag;  // Use int64_t, not bool, to preserve alignment
00841   } tmp;
00842 public:
00843   in_int64_t(uint32_t elements);
00844   void set(uint32_t pos,Item *item);
00845   unsigned char *get_value(Item *item);
00846 
00847   Item* create_item()
00848   {
00849     /*
00850       We're created a signed INT, this may not be correct in
00851       general case (see BUG#19342).
00852     */
00853     return new Item_int((int64_t)0);
00854   }
00855   void value_to_item(uint32_t pos, Item *item)
00856   {
00857     ((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
00858     ((Item_int*) item)->unsigned_flag= (bool)
00859       ((packed_int64_t*) base)[pos].unsigned_flag;
00860   }
00861   Item_result result_type() { return INT_RESULT; }
00862 
00863   friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
00864 };
00865 
00866 
00867 /*
00868   Class to represent a vector of constant DATE/DATETIME values.
00869   Values are obtained with help of the get_datetime_value() function.
00870   If the left item is a constant one then its value is cached in the
00871   lval_cache variable.
00872 */
00873 class in_datetime :public in_int64_t
00874 {
00875 public:
00876   Session *session;
00877   /* An item used to issue warnings. */
00878   Item *warn_item;
00879   /* Cache for the left item. */
00880   Item *lval_cache;
00881 
00882   in_datetime(Item *warn_item_arg, uint32_t elements);
00883 
00884   void set(uint32_t pos,Item *item);
00885   unsigned char *get_value(Item *item);
00886   friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
00887 };
00888 
00889 
00890 class in_double :public in_vector
00891 {
00892   double tmp;
00893 public:
00894   in_double(uint32_t elements);
00895   void set(uint32_t pos,Item *item);
00896   unsigned char *get_value(Item *item);
00897   Item *create_item()
00898   {
00899     return new Item_float(0.0, 0);
00900   }
00901   void value_to_item(uint32_t pos, Item *item)
00902   {
00903     ((Item_float*)item)->value= ((double*) base)[pos];
00904   }
00905   Item_result result_type() { return REAL_RESULT; }
00906 };
00907 
00908 
00909 class in_decimal :public in_vector
00910 {
00911   type::Decimal val;
00912 public:
00913   in_decimal(uint32_t elements);
00914   void set(uint32_t pos, Item *item);
00915   unsigned char *get_value(Item *item);
00916   Item *create_item()
00917   {
00918     return new Item_decimal(0, false);
00919   }
00920   void value_to_item(uint32_t pos, Item *item)
00921   {
00922     type::Decimal *dec= ((type::Decimal *)base) + pos;
00923     Item_decimal *item_dec= (Item_decimal*)item;
00924     item_dec->set_decimal_value(dec);
00925   }
00926   Item_result result_type() { return DECIMAL_RESULT; }
00927 
00928 };
00929 
00930 
00931 /*
00932 ** Classes for easy comparing of non const items
00933 */
00934 
00935 class cmp_item :public memory::SqlAlloc
00936 {
00937 public:
00938   const CHARSET_INFO *cmp_charset;
00939 
00940   cmp_item()
00941   {
00942     cmp_charset= &my_charset_bin;
00943   }
00944 
00945   virtual ~cmp_item() {}
00946   virtual void store_value(Item *item)= 0;
00947   virtual int cmp(Item *item)= 0;
00948   // for optimized IN with row
00949   virtual int compare(cmp_item *item)= 0;
00950   static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
00951   virtual cmp_item *make_same()= 0;
00952   virtual void store_value_by_template(cmp_item *, Item *item)
00953   {
00954     store_value(item);
00955   }
00956 };
00957 
00958 class cmp_item_string :public cmp_item
00959 {
00960 protected:
00961   String *value_res;
00962 public:
00963   cmp_item_string () {}
00964   cmp_item_string (const CHARSET_INFO * const cs) { cmp_charset= cs; }
00965   void set_charset(const CHARSET_INFO * const cs) { cmp_charset= cs; }
00966   friend class cmp_item_sort_string;
00967   friend class cmp_item_sort_string_in_static;
00968 };
00969 
00970 class cmp_item_sort_string :public cmp_item_string
00971 {
00972 protected:
00973   char value_buff[STRING_BUFFER_USUAL_SIZE];
00974   String value;
00975 public:
00976   cmp_item_sort_string():
00977     cmp_item_string() {}
00978   cmp_item_sort_string(const CHARSET_INFO * const cs):
00979     cmp_item_string(cs),
00980     value(value_buff, sizeof(value_buff), cs) {}
00981   void store_value(Item *item)
00982   {
00983     value_res= item->val_str(&value);
00984   }
00985   int cmp(Item *arg)
00986   {
00987     char buff[STRING_BUFFER_USUAL_SIZE];
00988     String tmp(buff, sizeof(buff), cmp_charset), *res;
00989     res= arg->val_str(&tmp);
00990     return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
00991             (res ? -1 : 0));
00992   }
00993   int compare(cmp_item *ci)
00994   {
00995     cmp_item_string *l_cmp= (cmp_item_string *) ci;
00996     return sortcmp(value_res, l_cmp->value_res, cmp_charset);
00997   }
00998   cmp_item *make_same();
00999   void set_charset(const CHARSET_INFO * const cs)
01000   {
01001     cmp_charset= cs;
01002     value.set_quick(value_buff, sizeof(value_buff), cs);
01003   }
01004 };
01005 
01006 class cmp_item_int :public cmp_item
01007 {
01008   int64_t value;
01009 public:
01010   cmp_item_int() {}                           /* Remove gcc warning */
01011   void store_value(Item *item)
01012   {
01013     value= item->val_int();
01014   }
01015   int cmp(Item *arg)
01016   {
01017     return value != arg->val_int();
01018   }
01019   int compare(cmp_item *ci)
01020   {
01021     cmp_item_int *l_cmp= (cmp_item_int *)ci;
01022     return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
01023   }
01024   cmp_item *make_same();
01025 };
01026 
01027 /*
01028   Compare items in the DATETIME context.
01029   Values are obtained with help of the get_datetime_value() function.
01030   If the left item is a constant one then its value is cached in the
01031   lval_cache variable.
01032 */
01033 class cmp_item_datetime :public cmp_item
01034 {
01035   int64_t value;
01036 
01037 public:
01038   Session *session;
01039   /* Item used for issuing warnings. */
01040   Item *warn_item;
01041   /* Cache for the left item. */
01042   Item *lval_cache;
01043 
01044   cmp_item_datetime(Item *warn_item_arg);
01045 
01046   void store_value(Item *item);
01047   int cmp(Item *arg);
01048   int compare(cmp_item *ci);
01049   cmp_item *make_same();
01050 };
01051 
01052 class cmp_item_real :public cmp_item
01053 {
01054   double value;
01055 public:
01056   cmp_item_real() {}                          /* Remove gcc warning */
01057   void store_value(Item *item)
01058   {
01059     value= item->val_real();
01060   }
01061   int cmp(Item *arg)
01062   {
01063     return value != arg->val_real();
01064   }
01065   int compare(cmp_item *ci)
01066   {
01067     cmp_item_real *l_cmp= (cmp_item_real *) ci;
01068     return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
01069   }
01070   cmp_item *make_same();
01071 };
01072 
01073 
01074 class cmp_item_decimal :public cmp_item
01075 {
01076   type::Decimal value;
01077 public:
01078   cmp_item_decimal() {}                       /* Remove gcc warning */
01079   void store_value(Item *item);
01080   int cmp(Item *arg);
01081   int compare(cmp_item *c);
01082   cmp_item *make_same();
01083 };
01084 
01085 
01086 /*
01087    cmp_item for optimized IN with row (right part string, which never
01088    be changed)
01089 */
01090 
01091 class cmp_item_sort_string_in_static :public cmp_item_string
01092 {
01093  protected:
01094   String value;
01095 public:
01096   cmp_item_sort_string_in_static(const CHARSET_INFO * const cs):
01097     cmp_item_string(cs) {}
01098   void store_value(Item *item)
01099   {
01100     value_res= item->val_str(&value);
01101   }
01102   int cmp(Item *)
01103   {
01104     // Should never be called
01105     assert(0);
01106     return 1;
01107   }
01108   int compare(cmp_item *ci)
01109   {
01110     cmp_item_string *l_cmp= (cmp_item_string *) ci;
01111     return sortcmp(value_res, l_cmp->value_res, cmp_charset);
01112   }
01113   cmp_item *make_same()
01114   {
01115     return new cmp_item_sort_string_in_static(cmp_charset);
01116   }
01117 };
01118 
01119 
01120 /*
01121   The class Item_func_case is the CASE ... WHEN ... THEN ... END function
01122   implementation.
01123 
01124   When there is no expression between CASE and the first WHEN
01125   (the CASE expression) then this function simple checks all WHEN expressions
01126   one after another. When some WHEN expression evaluated to TRUE then the
01127   value of the corresponding THEN expression is returned.
01128 
01129   When the CASE expression is specified then it is compared to each WHEN
01130   expression individually. When an equal WHEN expression is found
01131   corresponding THEN expression is returned.
01132   In order to do correct comparisons several comparators are used. One for
01133   each result type. Different result types that are used in particular
01134   CASE ... END expression are collected in the fix_length_and_dec() member
01135   function and only comparators for there result types are used.
01136 */
01137 
01138 class Item_func_case :public Item_func
01139 {
01140   int first_expr_num, else_expr_num;
01141   enum Item_result cached_result_type, left_result_type;
01142   String tmp_value;
01143   uint32_t ncases;
01144   Item_result cmp_type;
01145   DTCollation cmp_collation;
01146   enum_field_types cached_field_type;
01147   cmp_item *cmp_items[DECIMAL_RESULT+1]; /* For all result types */
01148   cmp_item *case_item;
01149 public:
01150   Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
01151     :Item_func(), first_expr_num(-1), else_expr_num(-1),
01152     cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
01153   {
01154     ncases= list.size();
01155     if (first_expr_arg)
01156     {
01157       first_expr_num= list.size();
01158       list.push_back(first_expr_arg);
01159     }
01160     if (else_expr_arg)
01161     {
01162       else_expr_num= list.size();
01163       list.push_back(else_expr_arg);
01164     }
01165     set_arguments(list);
01166     memset(&cmp_items, 0, sizeof(cmp_items));
01167   }
01168   double val_real();
01169   int64_t val_int();
01170   String *val_str(String *);
01171   type::Decimal *val_decimal(type::Decimal *);
01172   bool fix_fields(Session *session, Item **ref);
01173   void fix_length_and_dec();
01174   uint32_t decimal_precision() const;
01175   table_map not_null_tables() const { return 0; }
01176   enum Item_result result_type () const { return cached_result_type; }
01177   enum_field_types field_type() const { return cached_field_type; }
01178   const char *func_name() const { return "case"; }
01179   virtual void print(String *str);
01180   Item *find_item(String *str);
01181   const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
01182   void cleanup();
01183   void agg_str_lengths(Item *arg);
01184   void agg_num_lengths(Item *arg);
01185 };
01186 
01187 /*
01188   The Item_func_in class implements the in_expr IN(values_list) function.
01189 
01190   The current implementation distinguishes 2 cases:
01191   1) all items in the value_list are constants and have the same
01192     result type. This case is handled by in_vector class.
01193   2) items in the value_list have different result types or there is some
01194     non-constant items.
01195     In this case Item_func_in employs several cmp_item objects to performs
01196     comparisons of in_expr and an item from the values_list. One cmp_item
01197     object for each result type. Different result types are collected in the
01198     fix_length_and_dec() member function by means of collect_cmp_types()
01199     function.
01200 */
01201 class Item_func_in :public Item_func_opt_neg
01202 {
01203 public:
01204   /*
01205     an array of values when the right hand arguments of IN
01206     are all SQL constant and there are no nulls
01207   */
01208   in_vector *array;
01209   bool have_null;
01210   /*
01211     true when all arguments of the IN clause are of compatible types
01212     and can be used safely as comparisons for key conditions
01213   */
01214   bool arg_types_compatible;
01215   Item_result left_result_type;
01216   cmp_item *cmp_items[6]; /* One cmp_item for each result type */
01217   DTCollation cmp_collation;
01218 
01219   Item_func_in(List<Item> &list)
01220     :Item_func_opt_neg(list), array(0), have_null(0),
01221     arg_types_compatible(false)
01222   {
01223     memset(&cmp_items, 0, sizeof(cmp_items));
01224     allowed_arg_cols= 0;  // Fetch this value from first argument
01225   }
01226   int64_t val_int();
01227   bool fix_fields(Session *, Item **);
01228   void fix_length_and_dec();
01229   uint32_t decimal_precision() const { return 1; }
01230   void cleanup()
01231   {
01232     Item_int_func::cleanup();
01233     delete array;
01234     array= 0;
01235     for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
01236     {
01237       delete cmp_items[i];
01238       cmp_items[i]= 0;
01239     }
01240     return;
01241   }
01242   optimize_type select_optimize() const
01243     { return OPTIMIZE_KEY; }
01244   virtual void print(String *str);
01245   enum Functype functype() const { return IN_FUNC; }
01246   const char *func_name() const { return " IN "; }
01247   bool nulls_in_row();
01248   bool is_bool_func() { return 1; }
01249   const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
01250 };
01251 
01252 class cmp_item_row :public cmp_item
01253 {
01254   cmp_item **comparators;
01255   uint32_t n;
01256 public:
01257   cmp_item_row(): comparators(0), n(0) {}
01258   ~cmp_item_row();
01259   void store_value(Item *item);
01260   inline void alloc_comparators();
01261   int cmp(Item *arg);
01262   int compare(cmp_item *arg);
01263   cmp_item *make_same();
01264   void store_value_by_template(cmp_item *tmpl, Item *);
01265   friend void Item_func_in::fix_length_and_dec();
01266 };
01267 
01268 
01269 class in_row :public in_vector
01270 {
01271   cmp_item_row tmp;
01272 public:
01273   in_row(uint32_t elements, Item *);
01274   ~in_row();
01275   void set(uint32_t pos,Item *item);
01276   unsigned char *get_value(Item *item);
01277   friend void Item_func_in::fix_length_and_dec();
01278   Item_result result_type() { return ROW_RESULT; }
01279 };
01280 
01281 /* Functions used by where clause */
01282 
01283 class Item_func_isnull :public item::function::Boolean
01284 {
01285 protected:
01286   int64_t cached_value;
01287 public:
01288   Item_func_isnull(Item *a) :item::function::Boolean(a) {}
01289   int64_t val_int();
01290   enum Functype functype() const { return ISNULL_FUNC; }
01291   void fix_length_and_dec()
01292   {
01293     decimals=0; max_length=1; maybe_null=0;
01294     update_used_tables();
01295   }
01296   const char *func_name() const { return "isnull"; }
01297   /* Optimize case of not_null_column IS NULL */
01298   virtual void update_used_tables()
01299   {
01300     if (!args[0]->maybe_null)
01301     {
01302       used_tables_cache= 0;     /* is always false */
01303       const_item_cache= 1;
01304       cached_value= (int64_t) 0;
01305     }
01306     else
01307     {
01308       args[0]->update_used_tables();
01309       if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
01310           !with_subselect)
01311       {
01312   /* Remember if the value is always NULL or never NULL */
01313   cached_value= (int64_t) args[0]->is_null();
01314       }
01315     }
01316   }
01317   table_map not_null_tables() const { return 0; }
01318   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
01319   Item *neg_transformer(Session *session);
01320   const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
01321 };
01322 
01323 /* Functions used by HAVING for rewriting IN subquery */
01324 
01325 class Item_in_subselect;
01326 
01327 /*
01328   This is like IS NOT NULL but it also remembers if it ever has
01329   encountered a NULL.
01330 */
01331 class Item_is_not_null_test :public Item_func_isnull
01332 {
01333   Item_in_subselect* owner;
01334 public:
01335   Item_is_not_null_test(Item_in_subselect* ow, Item *a)
01336     :Item_func_isnull(a), owner(ow)
01337   {}
01338   enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
01339   int64_t val_int();
01340   const char *func_name() const { return "<is_not_null_test>"; }
01341   void update_used_tables();
01342   /*
01343     we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
01344   */
01345   table_map used_tables() const
01346     { return used_tables_cache | RAND_TABLE_BIT; }
01347 };
01348 
01349 
01350 class Item_func_isnotnull :public item::function::Boolean
01351 {
01352   bool abort_on_null;
01353 public:
01354   Item_func_isnotnull(Item *a) :item::function::Boolean(a), abort_on_null(0) {}
01355   int64_t val_int();
01356   enum Functype functype() const { return ISNOTNULL_FUNC; }
01357   void fix_length_and_dec()
01358   {
01359     decimals=0; max_length=1; maybe_null=0;
01360   }
01361   const char *func_name() const { return "isnotnull"; }
01362   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
01363   table_map not_null_tables() const
01364   { return abort_on_null ? not_null_tables_cache : 0; }
01365   Item *neg_transformer(Session *session);
01366   virtual void print(String *str);
01367   const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
01368   void top_level_item() { abort_on_null=1; }
01369 };
01370 
01371 
01372 class Item_func_like :public Item_bool_func2
01373 {
01374   // Turbo Boyer-Moore data
01375   bool        canDoTurboBM; // pattern is '%abcd%' case
01376   const char* pattern;
01377   int         pattern_len;
01378 
01379   // TurboBM buffers, *this is owner
01380   int* bmGs; //   good suffix shift table, size is pattern_len + 1
01381   int* bmBc; // bad character shift table, size is alphabet_size
01382 
01383   void turboBM_compute_suffixes(int* suff);
01384   void turboBM_compute_good_suffix_shifts(int* suff);
01385   void turboBM_compute_bad_character_shifts();
01386   bool turboBM_matches(const char* text, int text_len) const;
01387   enum { alphabet_size = 256 };
01388 
01389   Item *escape_item;
01390 
01391   bool escape_used_in_parsing;
01392 
01393 
01394 public:
01395 
01396   char *escape;
01397 
01398   Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
01399     :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
01400      bmGs(0), bmBc(0), escape_item(escape_arg),
01401      escape_used_in_parsing(escape_used), escape(NULL) {}
01402   int64_t val_int();
01403   enum Functype functype() const { return LIKE_FUNC; }
01404   optimize_type select_optimize() const;
01405   cond_result eq_cmp_result() const { return COND_TRUE; }
01406   const char *func_name() const { return "like"; }
01407   bool fix_fields(Session *session, Item **ref);
01408   void cleanup();
01409 };
01410 
01411 
01412 typedef class Item COND;
01413 
01414 class Item_cond :public item::function::Boolean
01415 {
01416 protected:
01417   List<Item> list;
01418   bool abort_on_null;
01419   table_map and_tables_cache;
01420 
01421 public:
01422 
01423   using Item::split_sum_func;
01424 
01425   /* Item_cond() is only used to create top level items */
01426   Item_cond(): item::function::Boolean(), abort_on_null(1)
01427   { const_item_cache=0; }
01428   Item_cond(Item *i1,Item *i2)
01429     :item::function::Boolean(), abort_on_null(0)
01430   {
01431     list.push_back(i1);
01432     list.push_back(i2);
01433   }
01434   Item_cond(Session *session, Item_cond *item);
01435   Item_cond(List<Item> &nlist)
01436     :item::function::Boolean(), list(nlist), abort_on_null(0) {}
01437   bool add(Item *item) { return list.push_back(item); }
01438   bool add_at_head(Item *item) { return list.push_front(item); }
01439   void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
01440   bool fix_fields(Session *, Item **ref);
01441   void fix_after_pullout(Select_Lex *new_parent, Item **ref);
01442 
01443   enum Type type() const { return COND_ITEM; }
01444   List<Item>* argument_list() { return &list; }
01445   table_map used_tables() const;
01446   void update_used_tables();
01447   virtual void print(String *str);
01448   void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
01449   friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
01450                          COND **conds);
01451   void top_level_item() { abort_on_null=1; }
01452   void copy_andor_arguments(Session *session, Item_cond *item);
01453   bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
01454   Item *transform(Item_transformer transformer, unsigned char *arg);
01455   void traverse_cond(Cond_traverser, void *arg, traverse_order order);
01456   void neg_arguments(Session *session);
01457   enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
01458   bool subst_argument_checker(unsigned char **)
01459   { return true; }
01460   Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
01461                 Item_transformer transformer, unsigned char *arg_t);
01462 };
01463 
01464 
01465 /*
01466   The class Item_equal is used to represent conjunctions of equality
01467   predicates of the form field1 = field2, and field=const in where
01468   conditions and on expressions.
01469 
01470   All equality predicates of the form field1=field2 contained in a
01471   conjunction are substituted for a sequence of items of this class.
01472   An item of this class Item_equal(f1,f2,...fk) represents a
01473   multiple equality f1=f2=...=fk.
01474 
01475   If a conjunction contains predicates f1=f2 and f2=f3, a new item of
01476   this class is created Item_equal(f1,f2,f3) representing the multiple
01477   equality f1=f2=f3 that substitutes the above equality predicates in
01478   the conjunction.
01479   A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
01480   substituted for the item representing the same multiple equality
01481   f1=f2=f3.
01482   An item Item_equal(f1,f2) can appear instead of a conjunction of
01483   f2=f1 and f1=f2, or instead of just the predicate f1=f2.
01484 
01485   An item of the class Item_equal inherits equalities from outer
01486   conjunctive levels.
01487 
01488   Suppose we have a where condition of the following form:
01489   WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
01490   In this case:
01491     f1=f2 will be substituted for Item_equal(f1,f2);
01492     f3=f4 and f3=f5  will be substituted for Item_equal(f3,f4,f5);
01493     f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
01494 
01495   An object of the class Item_equal can contain an optional constant
01496   item c. Then it represents a multiple equality of the form
01497   c=f1=...=fk.
01498 
01499   Objects of the class Item_equal are used for the following:
01500 
01501   1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
01502   pair of tables ti and tj as joined by an equi-condition.
01503   Thus it provide us with additional access paths from table to table.
01504 
01505   2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
01506   SARGable predicates:
01507     f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
01508   It also can give us additional index scans and can allow us to
01509   improve selectivity estimates.
01510 
01511   3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
01512   selected execution plan for the query: if table ti is accessed
01513   before the table tj then in any predicate P in the where condition
01514   the occurrence of tj.fj is substituted for ti.fi. This can allow
01515   an evaluation of the predicate at an earlier step.
01516 
01517   When feature 1 is supported they say that join transitive closure
01518   is employed.
01519   When feature 2 is supported they say that search argument transitive
01520   closure is employed.
01521   Both features are usually supported by preprocessing original query and
01522   adding additional predicates.
01523   We do not just add predicates, we rather dynamically replace some
01524   predicates that can not be used to access tables in the investigated
01525   plan for those, obtained by substitution of some fields for equal fields,
01526   that can be used.
01527 
01528   Prepared Statements/Stored Procedures note: instances of class
01529   Item_equal are created only at the time a PS/SP is executed and
01530   are deleted in the end of execution. All changes made to these
01531   objects need not be registered in the list of changes of the parse
01532   tree and do not harm PS/SP re-execution.
01533 
01534   Item equal objects are employed only at the optimize phase. Usually they are
01535   not supposed to be evaluated.  Yet in some cases we call the method val_int()
01536   for them. We have to take care of restricting the predicate such an
01537   object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
01538 */
01539 
01540 class Item_equal: public item::function::Boolean
01541 {
01542 public:
01543   typedef List<Item_field> fields_t;
01544 
01545   Item_equal() :
01546     const_item(0),
01547     eval_item(0),
01548     cond_false(0)
01549   {
01550     const_item_cache=0;
01551   }
01552 
01553   fields_t::iterator begin()
01554   {
01555     return fields.begin();
01556   }
01557 
01558   Item_equal(Item_field *f1, Item_field *f2);
01559   Item_equal(Item *c, Item_field *f);
01560   Item_equal(Item_equal *item_equal);
01561   inline Item* get_const() { return const_item; }
01562   void add(Item *c);
01563   void add(Item_field *f);
01564   uint32_t members();
01565   bool contains(Field *field);
01566   Item_field* get_first() { return &fields.front(); }
01567   void merge(Item_equal *item);
01568   void update_const();
01569   enum Functype functype() const { return MULT_EQUAL_FUNC; }
01570   int64_t val_int();
01571   const char *func_name() const { return "multiple equal"; }
01572   optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
01573   void sort(Item_field_cmpfunc cmp, void *arg);
01574   void fix_length_and_dec();
01575   bool fix_fields(Session *session, Item **ref);
01576   void update_used_tables();
01577   bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
01578   Item *transform(Item_transformer transformer, unsigned char *arg);
01579   virtual void print(String *str);
01580   const CHARSET_INFO *compare_collation()
01581   { return fields.front().collation.collation; }
01582 private:
01583   fields_t fields; /* list of equal field items                    */
01584   Item *const_item;        /* optional constant item equal to fields items */
01585   cmp_item *eval_item;
01586   bool cond_false;
01587 
01588 };
01589 
01590 class COND_EQUAL: public memory::SqlAlloc
01591 {
01592 public:
01593   uint32_t max_members;               /* max number of members the current level
01594                                      list and all lower level lists */
01595   COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
01596   List<Item_equal> current_level; /* list of multiple equalities of
01597                                      the current and level           */
01598   COND_EQUAL()
01599   {
01600     upper_levels= 0;
01601   }
01602 };
01603 
01604 typedef List<Item_field>::iterator Item_equal_iterator;
01605 
01606 class Item_cond_and :public Item_cond
01607 {
01608 public:
01609   COND_EQUAL cond_equal;  /* contains list of Item_equal objects for
01610                              the current and level and reference
01611                              to multiple equalities of upper and levels */
01612   Item_cond_and() :Item_cond() {}
01613   Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
01614   Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
01615   Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
01616   enum Functype functype() const { return COND_AND_FUNC; }
01617   int64_t val_int();
01618   const char *func_name() const { return "and"; }
01619   table_map not_null_tables() const
01620   { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
01621   Item* copy_andor_structure(Session *session)
01622   {
01623     Item_cond_and *item;
01624     if ((item= new Item_cond_and(session, this)))
01625        item->copy_andor_arguments(session, this);
01626     return item;
01627   }
01628   Item *neg_transformer(Session *session);
01629 };
01630 
01631 inline bool is_cond_and(Item *item)
01632 {
01633   if (item->type() != Item::COND_ITEM)
01634     return false;
01635 
01636   Item_cond *cond_item= (Item_cond*) item;
01637   return (cond_item->functype() == Item_func::COND_AND_FUNC);
01638 }
01639 
01640 class Item_cond_or :public Item_cond
01641 {
01642 public:
01643   Item_cond_or() :Item_cond() {}
01644   Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
01645   Item_cond_or(Session *session, Item_cond_or *item) :Item_cond(session, item) {}
01646   Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
01647   enum Functype functype() const { return COND_OR_FUNC; }
01648   int64_t val_int();
01649   const char *func_name() const { return "or"; }
01650   table_map not_null_tables() const { return and_tables_cache; }
01651   Item* copy_andor_structure(Session *session)
01652   {
01653     Item_cond_or *item;
01654     if ((item= new Item_cond_or(session, this)))
01655       item->copy_andor_arguments(session, this);
01656     return item;
01657   }
01658   Item *neg_transformer(Session *session);
01659 };
01660 
01661 inline bool is_cond_or(Item *item)
01662 {
01663   if (item->type() != Item::COND_ITEM)
01664     return false;
01665 
01666   Item_cond *cond_item= (Item_cond*) item;
01667   return (cond_item->functype() == Item_func::COND_OR_FUNC);
01668 }
01669 
01670 /*
01671   XOR is Item_cond, not an Item_int_func because we could like to
01672   optimize (a XOR b) later on. It's low prio, though
01673 */
01674 
01675 class Item_cond_xor :public Item_cond
01676 {
01677 public:
01678   Item_cond_xor() :Item_cond() {}
01679   Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
01680   enum Functype functype() const { return COND_XOR_FUNC; }
01681   /* TODO: remove the next line when implementing XOR optimization */
01682   enum Type type() const { return FUNC_ITEM; }
01683   int64_t val_int();
01684   const char *func_name() const { return "xor"; }
01685   void top_level_item() {}
01686 };
01687 
01688 enum_field_types agg_field_type(Item **items, uint32_t nitems);
01689 
01690 
01691 /* Some useful inline functions */
01692 
01693 inline Item *and_conds(Item *a, Item *b)
01694 {
01695   if (!b) return a;
01696   if (!a) return b;
01697   return new Item_cond_and(a, b);
01698 }
01699 
01700 Item *and_expressions(Item *a, Item *b, Item **org_item);
01701 
01702 } /* namespace drizzled */
01703