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