Drizzled Public API Documentation

cmpfunc.cc

Go to the documentation of this file.
00001 /* Copyright (C) 2000-2006 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 
00024 #include <config.h>
00025 
00026 #include <drizzled/cached_item.h>
00027 #include <drizzled/check_stack_overrun.h>
00028 #include <drizzled/current_session.h>
00029 #include <drizzled/error.h>
00030 #include <drizzled/internal/my_sys.h>
00031 #include <drizzled/item/cache_int.h>
00032 #include <drizzled/item/cmpfunc.h>
00033 #include <drizzled/item/int_with_ref.h>
00034 #include <drizzled/item/subselect.h>
00035 #include <drizzled/session.h>
00036 #include <drizzled/sql_select.h>
00037 #include <drizzled/temporal.h>
00038 #include <drizzled/time_functions.h>
00039 #include <drizzled/sql_lex.h>
00040 
00041 #include <math.h>
00042 #include <algorithm>
00043 
00044 using namespace std;
00045 
00046 namespace drizzled
00047 {
00048 
00049 extern const double log_10[309];
00050 
00051 static Eq_creator eq_creator;
00052 static Ne_creator ne_creator;
00053 static Gt_creator gt_creator;
00054 static Lt_creator lt_creator;
00055 static Ge_creator ge_creator;
00056 static Le_creator le_creator;
00057 
00058 static bool convert_constant_item(Session *, Item_field *, Item **);
00059 
00060 static Item_result item_store_type(Item_result a, Item *item,
00061                                    bool unsigned_flag)
00062 {
00063   Item_result b= item->result_type();
00064 
00065   if (a == STRING_RESULT || b == STRING_RESULT)
00066     return STRING_RESULT;
00067   else if (a == REAL_RESULT || b == REAL_RESULT)
00068     return REAL_RESULT;
00069   else if (a == DECIMAL_RESULT || b == DECIMAL_RESULT ||
00070            unsigned_flag != item->unsigned_flag)
00071     return DECIMAL_RESULT;
00072   else
00073     return INT_RESULT;
00074 }
00075 
00076 static void agg_result_type(Item_result *type, Item **items, uint32_t nitems)
00077 {
00078   Item **item, **item_end;
00079   bool unsigned_flag= 0;
00080 
00081   *type= STRING_RESULT;
00082   /* Skip beginning NULL items */
00083   for (item= items, item_end= item + nitems; item < item_end; item++)
00084   {
00085     if ((*item)->type() != Item::NULL_ITEM)
00086     {
00087       *type= (*item)->result_type();
00088       unsigned_flag= (*item)->unsigned_flag;
00089       item++;
00090       break;
00091     }
00092   }
00093   /* Combine result types. Note: NULL items don't affect the result */
00094   for (; item < item_end; item++)
00095   {
00096     if ((*item)->type() != Item::NULL_ITEM)
00097       *type= item_store_type(*type, *item, unsigned_flag);
00098   }
00099 }
00100 
00101 
00102 /*
00103   Compare row signature of two expressions
00104 
00105   SYNOPSIS:
00106     cmp_row_type()
00107     item1          the first expression
00108     item2         the second expression
00109 
00110   DESCRIPTION
00111     The function checks that two expressions have compatible row signatures
00112     i.e. that the number of columns they return are the same and that if they
00113     are both row expressions then each component from the first expression has
00114     a row signature compatible with the signature of the corresponding component
00115     of the second expression.
00116 
00117   RETURN VALUES
00118     1  type incompatibility has been detected
00119     0  otherwise
00120 */
00121 
00122 static int cmp_row_type(Item* item1, Item* item2)
00123 {
00124   uint32_t n= item1->cols();
00125   if (item2->check_cols(n))
00126     return 1;
00127   for (uint32_t i=0; i<n; i++)
00128   {
00129     if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
00130         (item1->element_index(i)->result_type() == ROW_RESULT &&
00131          cmp_row_type(item1->element_index(i), item2->element_index(i))))
00132       return 1;
00133   }
00134   return 0;
00135 }
00136 
00137 
00161 static int agg_cmp_type(Item_result *type, Item **items, uint32_t nitems)
00162 {
00163   uint32_t i;
00164   type[0]= items[0]->result_type();
00165   for (i= 1 ; i < nitems ; i++)
00166   {
00167     type[0]= item_cmp_type(type[0], items[i]->result_type());
00168     /*
00169       When aggregating types of two row expressions we have to check
00170       that they have the same cardinality and that each component
00171       of the first row expression has a compatible row signature with
00172       the signature of the corresponding component of the second row
00173       expression.
00174     */
00175     if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
00176       return 1;     // error found: invalid usage of rows
00177   }
00178   return 0;
00179 }
00180 
00181 
00200 enum_field_types agg_field_type(Item **items, uint32_t nitems)
00201 {
00202   uint32_t i;
00203   if (!nitems || items[0]->result_type() == ROW_RESULT )
00204     return (enum_field_types)-1;
00205   enum_field_types res= items[0]->field_type();
00206   for (i= 1 ; i < nitems ; i++)
00207     res= Field::field_type_merge(res, items[i]->field_type());
00208   return res;
00209 }
00210 
00211 /*
00212   Collects different types for comparison of first item with each other items
00213 
00214   SYNOPSIS
00215     collect_cmp_types()
00216       items             Array of items to collect types from
00217       nitems            Number of items in the array
00218       skip_nulls        Don't collect types of NULL items if TRUE
00219 
00220   DESCRIPTION
00221     This function collects different result types for comparison of the first
00222     item in the list with each of the remaining items in the 'items' array.
00223 
00224   RETURN
00225     0 - if row type incompatibility has been detected (see cmp_row_type)
00226     Bitmap of collected types - otherwise
00227 */
00228 
00229 static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
00230 {
00231   uint32_t i;
00232   uint32_t found_types;
00233   Item_result left_result= items[0]->result_type();
00234   assert(nitems > 1);
00235   found_types= 0;
00236   for (i= 1; i < nitems ; i++)
00237   {
00238     if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
00239       continue; // Skip NULL constant items
00240     if ((left_result == ROW_RESULT ||
00241          items[i]->result_type() == ROW_RESULT) &&
00242         cmp_row_type(items[0], items[i]))
00243       return 0;
00244     found_types|= 1<< (uint32_t)item_cmp_type(left_result,
00245                                            items[i]->result_type());
00246   }
00247   /*
00248    Even if all right-hand items are NULLs and we are skipping them all, we need
00249    at least one type bit in the found_type bitmask.
00250   */
00251   if (skip_nulls && !found_types)
00252     found_types= 1 << (uint)left_result;
00253   return found_types;
00254 }
00255 
00256 
00257 Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
00258 {
00259   return new Item_func_eq(a, b);
00260 }
00261 
00262 
00263 const Eq_creator* Eq_creator::instance()
00264 {
00265   return &eq_creator;
00266 }
00267 
00268 
00269 Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
00270 {
00271   return new Item_func_ne(a, b);
00272 }
00273 
00274 
00275 const Ne_creator* Ne_creator::instance()
00276 {
00277   return &ne_creator;
00278 }
00279 
00280 
00281 Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
00282 {
00283   return new Item_func_gt(a, b);
00284 }
00285 
00286 
00287 const Gt_creator* Gt_creator::instance()
00288 {
00289   return &gt_creator;
00290 }
00291 
00292 
00293 Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
00294 {
00295   return new Item_func_lt(a, b);
00296 }
00297 
00298 
00299 const Lt_creator* Lt_creator::instance()
00300 {
00301   return &lt_creator;
00302 }
00303 
00304 
00305 Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
00306 {
00307   return new Item_func_ge(a, b);
00308 }
00309 
00310 
00311 const Ge_creator* Ge_creator::instance()
00312 {
00313   return &ge_creator;
00314 }
00315 
00316 
00317 Item_bool_func2* Le_creator::create(Item *a, Item *b) const
00318 {
00319   return new Item_func_le(a, b);
00320 }
00321 
00322 const Le_creator* Le_creator::instance()
00323 {
00324   return &le_creator;
00325 }
00326 
00327 
00328 /*
00329   Test functions
00330   Most of these  returns 0LL if false and 1LL if true and
00331   NULL if some arg is NULL.
00332 */
00333 
00334 int64_t Item_func_not::val_int()
00335 {
00336   assert(fixed == 1);
00337   bool value= args[0]->val_bool();
00338   null_value=args[0]->null_value;
00339   return ((!null_value && value == 0) ? 1 : 0);
00340 }
00341 
00342 /*
00343   We put any NOT expression into parenthesis to avoid
00344   possible problems with internal view representations where
00345   any '!' is converted to NOT. It may cause a problem if
00346   '!' is used in an expression together with other operators
00347   whose precedence is lower than the precedence of '!' yet
00348   higher than the precedence of NOT.
00349 */
00350 
00351 void Item_func_not::print(String *str)
00352 {
00353   str->append('(');
00354   Item_func::print(str);
00355   str->append(')');
00356 }
00357 
00363 int64_t Item_func_not_all::val_int()
00364 {
00365   assert(fixed == 1);
00366   bool value= args[0]->val_bool();
00367 
00368   /*
00369     return true if there was records in underlying select in max/min
00370     optimization (ALL subquery)
00371   */
00372   if (empty_underlying_subquery())
00373     return 1;
00374 
00375   null_value= args[0]->null_value;
00376   return ((!null_value && value == 0) ? 1 : 0);
00377 }
00378 
00379 
00380 bool Item_func_not_all::empty_underlying_subquery()
00381 {
00382   return ((test_sum_item && !test_sum_item->any_value()) ||
00383           (test_sub_item && !test_sub_item->any_value()));
00384 }
00385 
00386 void Item_func_not_all::print(String *str)
00387 {
00388   if (show)
00389     Item_func::print(str);
00390   else
00391     args[0]->print(str);
00392 }
00393 
00394 
00404 int64_t Item_func_nop_all::val_int()
00405 {
00406   assert(fixed == 1);
00407   int64_t value= args[0]->val_int();
00408 
00409   /*
00410     return false if there was records in underlying select in max/min
00411     optimization (SAME/ANY subquery)
00412   */
00413   if (empty_underlying_subquery())
00414     return 0;
00415 
00416   null_value= args[0]->null_value;
00417   return (null_value || value == 0) ? 0 : 1;
00418 }
00419 
00420 
00448 static bool convert_constant_item(Session *session, Item_field *field_item,
00449                                   Item **item)
00450 {
00451   Field *field= field_item->field;
00452   int result= 0;
00453 
00454   field->setWriteSet();
00455 
00456   if (!(*item)->with_subselect && (*item)->const_item())
00457   {
00458     ulong orig_sql_mode= session->variables.sql_mode;
00459     enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
00460     uint64_t orig_field_val= 0; /* original field value if valid */
00461 
00462     /* For comparison purposes allow invalid dates like 2000-01-32 */
00463     session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
00464                              MODE_INVALID_DATES;
00465     session->count_cuted_fields= CHECK_FIELD_IGNORE;
00466 
00467     /*
00468       Store the value of the field if it references an outer field because
00469       the call to save_in_field below overrides that value.
00470     */
00471     if (field_item->depended_from)
00472     {
00473       orig_field_val= field->val_int();
00474     }
00475 
00476     if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
00477     {
00478       Item *tmp= new Item_int_with_ref(field->val_int(), *item,
00479                                        test(field->flags & UNSIGNED_FLAG));
00480       if (tmp)
00481         *item= tmp;
00482       result= 1;          // Item was replaced
00483     }
00484 
00485     /* Restore the original field value. */
00486     if (field_item->depended_from)
00487     {
00488       result= field->store(orig_field_val, field->isUnsigned());
00489       /* orig_field_val must be a valid value that can be restored back. */
00490       assert(!result);
00491     }
00492     session->variables.sql_mode= orig_sql_mode;
00493     session->count_cuted_fields= orig_count_cuted_fields;
00494   }
00495   return result;
00496 }
00497 
00498 
00499 void Item_bool_func2::fix_length_and_dec()
00500 {
00501   max_length= 1;             // Function returns 0 or 1
00502 
00503   /*
00504     As some compare functions are generated after sql_yacc,
00505     we have to check for out of memory conditions here
00506   */
00507   if (!args[0] || !args[1])
00508     return;
00509 
00510   /*
00511     We allow to convert to Unicode character sets in some cases.
00512     The conditions when conversion is possible are:
00513     - arguments A and B have different charsets
00514     - A wins according to coercibility rules
00515     - character set of A is superset for character set of B
00516 
00517     If all of the above is true, then it's possible to convert
00518     B into the character set of A, and then compare according
00519     to the collation of A.
00520   */
00521 
00522 
00523   DTCollation coll;
00524   if (args[0]->result_type() == STRING_RESULT &&
00525       args[1]->result_type() == STRING_RESULT &&
00526       agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
00527     return;
00528 
00529   args[0]->cmp_context= args[1]->cmp_context=
00530     item_cmp_type(args[0]->result_type(), args[1]->result_type());
00531   // Make a special case of compare with fields to get nicer DATE comparisons
00532 
00533   if (functype() == LIKE_FUNC)  // Disable conversion in case of LIKE function.
00534   {
00535     set_cmp_func();
00536     return;
00537   }
00538 
00539   Item_field *field_item= NULL;
00540 
00541   if (args[0]->real_item()->type() == FIELD_ITEM)
00542   {
00543     field_item= static_cast<Item_field*>(args[0]->real_item());
00544     if (field_item->field->can_be_compared_as_int64_t() &&
00545         !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
00546     {
00547       if (convert_constant_item(&getSession(), field_item, &args[1]))
00548       {
00549         cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
00550                          INT_RESULT);   // Works for all types.
00551         args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
00552         return;
00553       }
00554     }
00555 
00556     if (args[1]->real_item()->type() == FIELD_ITEM)
00557     {
00558       field_item= static_cast<Item_field*>(args[1]->real_item());
00559       if (field_item->field->can_be_compared_as_int64_t() &&
00560           !(field_item->is_datetime() &&
00561             args[0]->result_type() == STRING_RESULT))
00562       {
00563         if (convert_constant_item(&getSession(), field_item, &args[0]))
00564         {
00565           cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
00566                            INT_RESULT); // Works for all types.
00567           args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
00568           return;
00569         }
00570       }
00571     }
00572   }
00573   set_cmp_func();
00574 }
00575 
00576 Arg_comparator::Arg_comparator():
00577   session(current_session),
00578   a_cache(0),
00579   b_cache(0)
00580 {}
00581 
00582 Arg_comparator::Arg_comparator(Item **a1, Item **a2):
00583   a(a1),
00584   b(a2),
00585   session(current_session),
00586   a_cache(0),
00587   b_cache(0)
00588 {}
00589 
00590 int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
00591 {
00592   owner= item;
00593   func= comparator_matrix[type]
00594     [test(owner->functype() == Item_func::EQUAL_FUNC)];
00595 
00596   switch (type) {
00597   case ROW_RESULT:
00598     {
00599       uint32_t n= (*a)->cols();
00600       if (n != (*b)->cols())
00601       {
00602         my_error(ER_OPERAND_COLUMNS, MYF(0), n);
00603         comparators= 0;
00604         return 1;
00605       }
00606       if (!(comparators= new Arg_comparator[n]))
00607         return 1;
00608       for (uint32_t i=0; i < n; i++)
00609       {
00610         if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
00611         {
00612           my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
00613           return 1;
00614         }
00615         comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
00616       }
00617       break;
00618     }
00619 
00620   case STRING_RESULT:
00621     {
00622       /*
00623         We must set cmp_charset here as we may be called from for an automatic
00624         generated item, like in natural join
00625       */
00626       if (cmp_collation.set((*a)->collation, (*b)->collation) ||
00627           cmp_collation.derivation == DERIVATION_NONE)
00628       {
00629         my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
00630         return 1;
00631       }
00632       if (cmp_collation.collation == &my_charset_bin)
00633       {
00634         /*
00635           We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
00636           without removing end space
00637         */
00638         if (func == &Arg_comparator::compare_string)
00639           func= &Arg_comparator::compare_binary_string;
00640         else if (func == &Arg_comparator::compare_e_string)
00641           func= &Arg_comparator::compare_e_binary_string;
00642 
00643         /*
00644           As this is binary compassion, mark all fields that they can't be
00645           transformed. Otherwise we would get into trouble with comparisons
00646 like:
00647 WHERE col= 'j' AND col LIKE BINARY 'j'
00648 which would be transformed to:
00649 WHERE col= 'j'
00650       */
00651         (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
00652         (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
00653       }
00654       break;
00655     }
00656   case INT_RESULT:
00657     {
00658       if (func == &Arg_comparator::compare_int_signed)
00659       {
00660         if ((*a)->unsigned_flag)
00661           func= (((*b)->unsigned_flag)?
00662                  &Arg_comparator::compare_int_unsigned :
00663                  &Arg_comparator::compare_int_unsigned_signed);
00664         else if ((*b)->unsigned_flag)
00665           func= &Arg_comparator::compare_int_signed_unsigned;
00666       }
00667       else if (func== &Arg_comparator::compare_e_int)
00668       {
00669         if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
00670           func= &Arg_comparator::compare_e_int_diff_signedness;
00671       }
00672       break;
00673     }
00674   case DECIMAL_RESULT:
00675     break;
00676   case REAL_RESULT:
00677     {
00678       if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
00679       {
00680         precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
00681         if (func == &Arg_comparator::compare_real)
00682           func= &Arg_comparator::compare_real_fixed;
00683         else if (func == &Arg_comparator::compare_e_real)
00684           func= &Arg_comparator::compare_e_real_fixed;
00685       }
00686       break;
00687     }
00688   }
00689 
00690   return 0;
00691 }
00692 
00693 
00716 static int64_t
00717 get_date_from_str(Session *session, String *str, type::timestamp_t warn_type,
00718                   char *warn_name, bool *error_arg)
00719 {
00720   int64_t value= 0;
00721   type::cut_t error= type::VALID;
00722   type::Time l_time;
00723   type::timestamp_t ret;
00724 
00725   ret= l_time.store(str->ptr(), str->length(),
00726                     (TIME_FUZZY_DATE | MODE_INVALID_DATES | (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
00727                     error);
00728 
00729   if (ret == type::DRIZZLE_TIMESTAMP_DATETIME || ret == type::DRIZZLE_TIMESTAMP_DATE)
00730   {
00731     /*
00732       Do not return yet, we may still want to throw a "trailing garbage"
00733       warning.
00734     */
00735     *error_arg= false;
00736     l_time.convert(value);
00737   }
00738   else
00739   {
00740     *error_arg= true;
00741     error= type::CUT;                                   /* force warning */
00742   }
00743 
00744   if (error != type::VALID)
00745   {
00746     make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
00747                                  str->ptr(), str->length(),
00748                                  warn_type, warn_name);
00749   }
00750 
00751   return value;
00752 }
00753 
00754 
00755 /*
00756   Check whether compare_datetime() can be used to compare items.
00757 
00758   SYNOPSIS
00759     Arg_comparator::can_compare_as_dates()
00760     a, b          [in]  items to be compared
00761     const_value   [out] converted value of the string constant, if any
00762 
00763   DESCRIPTION
00764     Check several cases when the DATE/DATETIME comparator should be used.
00765     The following cases are checked:
00766       1. Both a and b is a DATE/DATETIME field/function returning string or
00767          int result.
00768       2. Only a or b is a DATE/DATETIME field/function returning string or
00769          int result and the other item (b or a) is an item with string result.
00770          If the second item is a constant one then it's checked to be
00771          convertible to the DATE/DATETIME type. If the constant can't be
00772          converted to a DATE/DATETIME then an error is issued back to the Session.
00773       In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
00774       the comparison is handled by other comparators.
00775 
00776     If the datetime comparator can be used and one the operands of the
00777     comparison is a string constant that was successfully converted to a
00778     DATE/DATETIME type then the result of the conversion is returned in the
00779     const_value if it is provided.  If there is no constant or
00780     compare_datetime() isn't applicable then the *const_value remains
00781     unchanged.
00782 
00783   RETURN
00784     the found type of date comparison
00785 */
00786 
00787 enum Arg_comparator::enum_date_cmp_type
00788 Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
00789                                      int64_t *const_value)
00790 {
00791   enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
00792   Item *str_arg= 0, *date_arg= 0;
00793 
00794   if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
00795     return CMP_DATE_DFLT;
00796 
00797   if (in_a->is_datetime())
00798   {
00799     if (in_b->is_datetime())
00800     {
00801       cmp_type= CMP_DATE_WITH_DATE;
00802     }
00803     else if (in_b->result_type() == STRING_RESULT)
00804     {
00805       cmp_type= CMP_DATE_WITH_STR;
00806       date_arg= in_a;
00807       str_arg= in_b;
00808     }
00809   }
00810   else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
00811   {
00812     cmp_type= CMP_STR_WITH_DATE;
00813     date_arg= in_b;
00814     str_arg= in_a;
00815   }
00816 
00817   if (cmp_type != CMP_DATE_DFLT)
00818   {
00819     /*
00820       Do not cache GET_USER_VAR() function as its const_item() may return true
00821       for the current thread but it still may change during the execution.
00822     */
00823     if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
00824         (str_arg->type() != Item::FUNC_ITEM ||
00825         ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
00826     {
00827       /*
00828        * OK, we are here if we've got a date field (or something which can be 
00829        * compared as a date field) on one side of the equation, and a constant
00830        * string on the other side.  In this case, we must verify that the constant
00831        * string expression can indeed be evaluated as a datetime.  If it cannot, 
00832        * we throw an error here and stop processsing.  Bad data should ALWAYS 
00833        * produce an error, and no implicit conversion or truncation should take place.
00834        *
00835        * If the conversion to a DateTime temporal is successful, then we convert
00836        * the Temporal instance to a uint64_t for the comparison operator, which
00837        * compares date(times) using int64_t semantics.
00838        *
00839        * @TODO
00840        *
00841        * Does a uint64_t conversion really have to happen here?  Fields return int64_t
00842        * from val_int(), not uint64_t...
00843        */
00844       int64_t value;
00845       String *str_val;
00846       String tmp;
00847       /* DateTime used to pick up as many string conversion possibilities as possible. */
00848       DateTime temporal;
00849 
00850       str_val= str_arg->val_str(&tmp);
00851       if (! str_val)
00852       {
00853         /* 
00854          * If we are here, it is most likely due to the comparison item
00855          * being a NULL.  Although this is incorrect (SQL demands that the term IS NULL
00856          * be used, not = NULL since no item can be equal to NULL).
00857          *
00858          * So, return gracefully.
00859          */
00860         return CMP_DATE_DFLT;
00861       }
00862       if (temporal.from_string(str_val->c_ptr(), str_val->length()))
00863       {
00864         /* String conversion was good.  Convert to an integer for comparison purposes. */
00865         temporal.to_int64_t(&value);
00866       }
00867       else
00868       {
00869         /* We aren't a DATETIME but still could be a TIME */
00870         Time timevalue;
00871         if (timevalue.from_string(str_val->c_ptr(), str_val->length()))
00872         {
00873           uint64_t timeint;
00874           timevalue.to_uint64_t(timeint);
00875           value= static_cast<int64_t>(timeint);
00876         }
00877         else
00878         {
00879           /* Chuck an error. Bad datetime input. */
00880           my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
00881           return CMP_DATE_DFLT; /* :( What else can I return... */
00882         }
00883       }
00884 
00885       if (const_value)
00886         *const_value= value;
00887     }
00888   }
00889   return cmp_type;
00890 }
00891 
00892 
00893 int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
00894                                         Item **a1, Item **a2,
00895                                         Item_result type)
00896 {
00897   enum_date_cmp_type cmp_type;
00898   int64_t const_value= -1;
00899   a= a1;
00900   b= a2;
00901 
00902   if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
00903   {
00904     owner= owner_arg;
00905     a_type= (*a)->field_type();
00906     b_type= (*b)->field_type();
00907     a_cache= 0;
00908     b_cache= 0;
00909 
00910     if (const_value != -1)
00911     {
00912       Item_cache_int *cache= new Item_cache_int();
00913       /* Mark the cache as non-const to prevent re-caching. */
00914       cache->set_used_tables(1);
00915       if (!(*a)->is_datetime())
00916       {
00917         cache->store((*a), const_value);
00918         a_cache= cache;
00919         a= (Item **)&a_cache;
00920       }
00921       else
00922       {
00923         cache->store((*b), const_value);
00924         b_cache= cache;
00925         b= (Item **)&b_cache;
00926       }
00927     }
00928     is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
00929     func= &Arg_comparator::compare_datetime;
00930     get_value_func= &get_datetime_value;
00931 
00932     return 0;
00933   }
00934 
00935   return set_compare_func(owner_arg, type);
00936 }
00937 
00938 
00939 void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
00940 {
00941   /* A caller will handle null values by itself. */
00942   owner= NULL;
00943   a= a1;
00944   b= b1;
00945   a_type= (*a)->field_type();
00946   b_type= (*b)->field_type();
00947   a_cache= 0;
00948   b_cache= 0;
00949   is_nulls_eq= false;
00950   func= &Arg_comparator::compare_datetime;
00951   get_value_func= &get_datetime_value;
00952 }
00953 
00954 
00955 /*
00956   Retrieves correct DATETIME value from given item.
00957 
00958   SYNOPSIS
00959     get_datetime_value()
00960     session                 thread handle
00961     item_arg   [in/out] item to retrieve DATETIME value from
00962     cache_arg  [in/out] pointer to place to store the caching item to
00963     warn_item  [in]     item for issuing the conversion warning
00964     is_null    [out]    true <=> the item_arg is null
00965 
00966   DESCRIPTION
00967     Retrieves the correct DATETIME value from given item for comparison by the
00968     compare_datetime() function.
00969     If item's result can be compared as int64_t then its int value is used
00970     and its string value is used otherwise. Strings are always parsed and
00971     converted to int values by the get_date_from_str() function.
00972     This allows us to compare correctly string dates with missed insignificant
00973     zeros. If an item is a constant one then its value is cached and it isn't
00974     get parsed again. An Item_cache_int object is used for caching values. It
00975     seamlessly substitutes the original item.  The cache item is marked as
00976     non-constant to prevent re-caching it again.  In order to compare
00977     correctly DATE and DATETIME items the result of the former are treated as
00978     a DATETIME with zero time (00:00:00).
00979 
00980   RETURN
00981     obtained value
00982 */
00983 
00984 int64_t
00985 get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
00986                    Item *warn_item, bool *is_null)
00987 {
00988   int64_t value= 0;
00989   String buf, *str= 0;
00990   Item *item= **item_arg;
00991 
00992   if (item->result_as_int64_t())
00993   {
00994     value= item->val_int();
00995     *is_null= item->null_value;
00996     enum_field_types f_type= item->field_type();
00997     /*
00998       Item_date_add_interval may return DRIZZLE_TYPE_STRING as the result
00999       field type. To detect that the DATE value has been returned we
01000       compare it with 100000000L - any DATE value should be less than it.
01001       Don't shift cached DATETIME values up for the second time.
01002     */
01003     if (f_type == DRIZZLE_TYPE_DATE ||
01004         (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
01005       value*= 1000000L;
01006   }
01007   else
01008   {
01009     str= item->val_str(&buf);
01010     *is_null= item->null_value;
01011   }
01012 
01013   if (*is_null)
01014     return ~(uint64_t) 0;
01015 
01016   /*
01017     Convert strings to the integer DATE/DATETIME representation.
01018     Even if both dates provided in strings we can't compare them directly as
01019     strings as there is no warranty that they are correct and do not miss
01020     some insignificant zeros.
01021   */
01022   if (str)
01023   {
01024     bool error;
01025     enum_field_types f_type= warn_item->field_type();
01026     type::timestamp_t t_type= f_type == DRIZZLE_TYPE_DATE ? type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME;
01027     value= get_date_from_str(session, str, t_type, warn_item->name, &error);
01028     /*
01029       If str did not contain a valid date according to the current
01030       SQL_MODE, get_date_from_str() has already thrown a warning,
01031       and we don't want to throw NULL on invalid date (see 5.2.6
01032       "SQL modes" in the manual), so we're done here.
01033     */
01034   }
01035   /*
01036     Do not cache GET_USER_VAR() function as its const_item() may return true
01037     for the current thread but it still may change during the execution.
01038   */
01039   if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
01040       ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
01041   {
01042     Item_cache_int *cache= new Item_cache_int(DRIZZLE_TYPE_DATETIME);
01043     /* Mark the cache as non-const to prevent re-caching. */
01044     cache->set_used_tables(1);
01045     cache->store(item, value);
01046     *cache_arg= cache;
01047     *item_arg= cache_arg;
01048   }
01049 
01050   return value;
01051 }
01052 
01053 /*
01054   Compare items values as dates.
01055 
01056   SYNOPSIS
01057     Arg_comparator::compare_datetime()
01058 
01059   DESCRIPTION
01060     Compare items values as DATE/DATETIME for both EQUAL_FUNC and from other
01061     comparison functions. The correct DATETIME values are obtained
01062     with help of the get_datetime_value() function.
01063 
01064   RETURN
01065     If is_nulls_eq is true:
01066        1    if items are equal or both are null
01067        0    otherwise
01068     If is_nulls_eq is false:
01069       -1   a < b or one of items is null
01070        0   a == b
01071        1   a > b
01072 */
01073 
01074 int Arg_comparator::compare_datetime()
01075 {
01076   bool is_null= false;
01077   uint64_t a_value, b_value;
01078 
01079   /* Get DATE/DATETIME/TIME value of the 'a' item. */
01080   a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
01081   if (!is_nulls_eq && is_null)
01082   {
01083     if (owner)
01084       owner->null_value= 1;
01085     return -1;
01086   }
01087 
01088   /* Get DATE/DATETIME/TIME value of the 'b' item. */
01089   b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
01090   if (is_null)
01091   {
01092     if (owner)
01093       owner->null_value= is_nulls_eq ? 0 : 1;
01094     return is_nulls_eq ? 1 : -1;
01095   }
01096 
01097   if (owner)
01098     owner->null_value= 0;
01099 
01100   /* Compare values. */
01101   if (is_nulls_eq)
01102     return (a_value == b_value);
01103   return (a_value < b_value) ? -1 : ((a_value > b_value) ? 1 : 0);
01104 }
01105 
01106 
01107 int Arg_comparator::compare_string()
01108 {
01109   String *res1,*res2;
01110   if ((res1= (*a)->val_str(&owner->tmp_value1)))
01111   {
01112     if ((res2= (*b)->val_str(&owner->tmp_value2)))
01113     {
01114       owner->null_value= 0;
01115       return sortcmp(res1,res2,cmp_collation.collation);
01116     }
01117   }
01118   owner->null_value= 1;
01119   return -1;
01120 }
01121 
01122 
01134 int Arg_comparator::compare_binary_string()
01135 {
01136   String *res1,*res2;
01137   if ((res1= (*a)->val_str(&owner->tmp_value1)))
01138   {
01139     if ((res2= (*b)->val_str(&owner->tmp_value2)))
01140     {
01141       owner->null_value= 0;
01142       uint32_t res1_length= res1->length();
01143       uint32_t res2_length= res2->length();
01144       int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
01145       return cmp ? cmp : (int) (res1_length - res2_length);
01146     }
01147   }
01148   owner->null_value= 1;
01149   return -1;
01150 }
01151 
01152 
01158 int Arg_comparator::compare_e_string()
01159 {
01160   String *res1,*res2;
01161   res1= (*a)->val_str(&owner->tmp_value1);
01162   res2= (*b)->val_str(&owner->tmp_value2);
01163   if (!res1 || !res2)
01164     return test(res1 == res2);
01165   return test(sortcmp(res1, res2, cmp_collation.collation) == 0);
01166 }
01167 
01168 
01169 int Arg_comparator::compare_e_binary_string()
01170 {
01171   String *res1,*res2;
01172   res1= (*a)->val_str(&owner->tmp_value1);
01173   res2= (*b)->val_str(&owner->tmp_value2);
01174   if (!res1 || !res2)
01175     return test(res1 == res2);
01176   return test(stringcmp(res1, res2) == 0);
01177 }
01178 
01179 
01180 int Arg_comparator::compare_real()
01181 {
01182   /*
01183     Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
01184     gcc to flush double values out of 80-bit Intel FPU registers before
01185     performing the comparison.
01186   */
01187   volatile double val1, val2;
01188   val1= (*a)->val_real();
01189   if (!(*a)->null_value)
01190   {
01191     val2= (*b)->val_real();
01192     if (!(*b)->null_value)
01193     {
01194       owner->null_value= 0;
01195       if (val1 < val2)  return -1;
01196       if (val1 == val2) return 0;
01197       return 1;
01198     }
01199   }
01200   owner->null_value= 1;
01201   return -1;
01202 }
01203 
01204 int Arg_comparator::compare_decimal()
01205 {
01206   type::Decimal value1;
01207   type::Decimal *val1= (*a)->val_decimal(&value1);
01208   if (!(*a)->null_value)
01209   {
01210     type::Decimal value2;
01211     type::Decimal *val2= (*b)->val_decimal(&value2);
01212     if (!(*b)->null_value)
01213     {
01214       owner->null_value= 0;
01215       return class_decimal_cmp(val1, val2);
01216     }
01217   }
01218   owner->null_value= 1;
01219   return -1;
01220 }
01221 
01222 int Arg_comparator::compare_e_real()
01223 {
01224   double val1= (*a)->val_real();
01225   double val2= (*b)->val_real();
01226   if ((*a)->null_value || (*b)->null_value)
01227     return test((*a)->null_value && (*b)->null_value);
01228   return test(val1 == val2);
01229 }
01230 
01231 int Arg_comparator::compare_e_decimal()
01232 {
01233   type::Decimal value1, value2;
01234   type::Decimal *val1= (*a)->val_decimal(&value1);
01235   type::Decimal *val2= (*b)->val_decimal(&value2);
01236   if ((*a)->null_value || (*b)->null_value)
01237     return test((*a)->null_value && (*b)->null_value);
01238   return test(class_decimal_cmp(val1, val2) == 0);
01239 }
01240 
01241 
01242 int Arg_comparator::compare_real_fixed()
01243 {
01244   /*
01245     Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
01246     gcc to flush double values out of 80-bit Intel FPU registers before
01247     performing the comparison.
01248   */
01249   volatile double val1, val2;
01250   val1= (*a)->val_real();
01251   if (!(*a)->null_value)
01252   {
01253     val2= (*b)->val_real();
01254     if (!(*b)->null_value)
01255     {
01256       owner->null_value= 0;
01257       if (val1 == val2 || fabs(val1 - val2) < precision)
01258         return 0;
01259       if (val1 < val2)
01260         return -1;
01261       return 1;
01262     }
01263   }
01264   owner->null_value= 1;
01265   return -1;
01266 }
01267 
01268 
01269 int Arg_comparator::compare_e_real_fixed()
01270 {
01271   double val1= (*a)->val_real();
01272   double val2= (*b)->val_real();
01273   if ((*a)->null_value || (*b)->null_value)
01274     return test((*a)->null_value && (*b)->null_value);
01275   return test(val1 == val2 || fabs(val1 - val2) < precision);
01276 }
01277 
01278 
01279 int Arg_comparator::compare_int_signed()
01280 {
01281   int64_t val1= (*a)->val_int();
01282   if (!(*a)->null_value)
01283   {
01284     int64_t val2= (*b)->val_int();
01285     if (!(*b)->null_value)
01286     {
01287       owner->null_value= 0;
01288       if (val1 < val2)  return -1;
01289       if (val1 == val2)   return 0;
01290       return 1;
01291     }
01292   }
01293   owner->null_value= 1;
01294   return -1;
01295 }
01296 
01297 
01302 int Arg_comparator::compare_int_unsigned()
01303 {
01304   uint64_t val1= (*a)->val_int();
01305   if (!(*a)->null_value)
01306   {
01307     uint64_t val2= (*b)->val_int();
01308     if (!(*b)->null_value)
01309     {
01310       owner->null_value= 0;
01311       if (val1 < val2)  return -1;
01312       if (val1 == val2)   return 0;
01313       return 1;
01314     }
01315   }
01316   owner->null_value= 1;
01317   return -1;
01318 }
01319 
01320 
01325 int Arg_comparator::compare_int_signed_unsigned()
01326 {
01327   int64_t sval1= (*a)->val_int();
01328   if (!(*a)->null_value)
01329   {
01330     uint64_t uval2= (uint64_t)(*b)->val_int();
01331     if (!(*b)->null_value)
01332     {
01333       owner->null_value= 0;
01334       if (sval1 < 0 || (uint64_t)sval1 < uval2)
01335         return -1;
01336       if ((uint64_t)sval1 == uval2)
01337         return 0;
01338       return 1;
01339     }
01340   }
01341   owner->null_value= 1;
01342   return -1;
01343 }
01344 
01345 
01350 int Arg_comparator::compare_int_unsigned_signed()
01351 {
01352   uint64_t uval1= (uint64_t)(*a)->val_int();
01353   if (!(*a)->null_value)
01354   {
01355     int64_t sval2= (*b)->val_int();
01356     if (!(*b)->null_value)
01357     {
01358       owner->null_value= 0;
01359       if (sval2 < 0)
01360         return 1;
01361       if (uval1 < (uint64_t)sval2)
01362         return -1;
01363       if (uval1 == (uint64_t)sval2)
01364         return 0;
01365       return 1;
01366     }
01367   }
01368   owner->null_value= 1;
01369   return -1;
01370 }
01371 
01372 
01373 int Arg_comparator::compare_e_int()
01374 {
01375   int64_t val1= (*a)->val_int();
01376   int64_t val2= (*b)->val_int();
01377   if ((*a)->null_value || (*b)->null_value)
01378     return test((*a)->null_value && (*b)->null_value);
01379   return test(val1 == val2);
01380 }
01381 
01385 int Arg_comparator::compare_e_int_diff_signedness()
01386 {
01387   int64_t val1= (*a)->val_int();
01388   int64_t val2= (*b)->val_int();
01389   if ((*a)->null_value || (*b)->null_value)
01390     return test((*a)->null_value && (*b)->null_value);
01391   return (val1 >= 0) && test(val1 == val2);
01392 }
01393 
01394 int Arg_comparator::compare_row()
01395 {
01396   int res= 0;
01397   bool was_null= 0;
01398   (*a)->bring_value();
01399   (*b)->bring_value();
01400   uint32_t n= (*a)->cols();
01401   for (uint32_t i= 0; i<n; i++)
01402   {
01403     res= comparators[i].compare();
01404     if (owner->null_value)
01405     {
01406       // NULL was compared
01407       switch (owner->functype()) {
01408       case Item_func::NE_FUNC:
01409         break; // NE never aborts on NULL even if abort_on_null is set
01410       case Item_func::LT_FUNC:
01411       case Item_func::LE_FUNC:
01412       case Item_func::GT_FUNC:
01413       case Item_func::GE_FUNC:
01414         return -1; // <, <=, > and >= always fail on NULL
01415       default: // EQ_FUNC
01416         if (owner->abort_on_null)
01417           return -1; // We do not need correct NULL returning
01418       }
01419       was_null= 1;
01420       owner->null_value= 0;
01421       res= 0;  // continue comparison (maybe we will meet explicit difference)
01422     }
01423     else if (res)
01424       return res;
01425   }
01426   if (was_null)
01427   {
01428     /*
01429       There was NULL(s) in comparison in some parts, but there was no
01430       explicit difference in other parts, so we have to return NULL.
01431     */
01432     owner->null_value= 1;
01433     return -1;
01434   }
01435   return 0;
01436 }
01437 
01438 
01439 int Arg_comparator::compare_e_row()
01440 {
01441   (*a)->bring_value();
01442   (*b)->bring_value();
01443   uint32_t n= (*a)->cols();
01444   for (uint32_t i= 0; i<n; i++)
01445   {
01446     if (!comparators[i].compare())
01447       return 0;
01448   }
01449   return 1;
01450 }
01451 
01452 
01453 void Item_func_truth::fix_length_and_dec()
01454 {
01455   maybe_null= 0;
01456   null_value= 0;
01457   decimals= 0;
01458   max_length= 1;
01459 }
01460 
01461 
01462 void Item_func_truth::print(String *str)
01463 {
01464   str->append('(');
01465   args[0]->print(str);
01466   str->append(STRING_WITH_LEN(" is "));
01467   if (! affirmative)
01468     str->append(STRING_WITH_LEN("not "));
01469   if (value)
01470     str->append(STRING_WITH_LEN("true"));
01471   else
01472     str->append(STRING_WITH_LEN("false"));
01473   str->append(')');
01474 }
01475 
01476 
01477 bool Item_func_truth::val_bool()
01478 {
01479   bool val= args[0]->val_bool();
01480   if (args[0]->null_value)
01481   {
01482     /*
01483       NULL val IS {true, false} --> false
01484       NULL val IS NOT {true, false} --> true
01485     */
01486     return (! affirmative);
01487   }
01488 
01489   if (affirmative)
01490   {
01491     /* {true, false} val IS {true, false} value */
01492     return (val == value);
01493   }
01494 
01495   /* {true, false} val IS NOT {true, false} value */
01496   return (val != value);
01497 }
01498 
01499 
01500 int64_t Item_func_truth::val_int()
01501 {
01502   return (val_bool() ? 1 : 0);
01503 }
01504 
01505 
01506 bool Item_in_optimizer::fix_left(Session *session, Item **)
01507 {
01508   if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
01509       (!cache && !(cache= Item_cache::get_cache(args[0]))))
01510     return 1;
01511 
01512   cache->setup(args[0]);
01513   if (cache->cols() == 1)
01514   {
01515     if ((used_tables_cache= args[0]->used_tables()))
01516       cache->set_used_tables(OUTER_REF_TABLE_BIT);
01517     else
01518       cache->set_used_tables(0);
01519   }
01520   else
01521   {
01522     uint32_t n= cache->cols();
01523     for (uint32_t i= 0; i < n; i++)
01524     {
01525       if (args[0]->element_index(i)->used_tables())
01526   ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
01527       else
01528   ((Item_cache *)cache->element_index(i))->set_used_tables(0);
01529     }
01530     used_tables_cache= args[0]->used_tables();
01531   }
01532   not_null_tables_cache= args[0]->not_null_tables();
01533   with_sum_func= args[0]->with_sum_func;
01534   if ((const_item_cache= args[0]->const_item()))
01535     cache->store(args[0]);
01536   return 0;
01537 }
01538 
01539 
01540 bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
01541 {
01542   assert(fixed == 0);
01543   if (fix_left(session, ref))
01544     return true;
01545   if (args[0]->maybe_null)
01546     maybe_null=1;
01547 
01548   if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
01549     return true;
01550   Item_in_subselect * sub= (Item_in_subselect *)args[1];
01551   if (args[0]->cols() != sub->engine->cols())
01552   {
01553     my_error(ER_OPERAND_COLUMNS, MYF(0), args[0]->cols());
01554     return true;
01555   }
01556   if (args[1]->maybe_null)
01557     maybe_null=1;
01558   with_sum_func= with_sum_func || args[1]->with_sum_func;
01559   used_tables_cache|= args[1]->used_tables();
01560   not_null_tables_cache|= args[1]->not_null_tables();
01561   const_item_cache&= args[1]->const_item();
01562   fixed= 1;
01563   return false;
01564 }
01565 
01566 
01567 int64_t Item_in_optimizer::val_int()
01568 {
01569   bool tmp;
01570   assert(fixed == 1);
01571   cache->store(args[0]);
01572 
01573   if (cache->null_value)
01574   {
01575     if (((Item_in_subselect*)args[1])->is_top_level_item())
01576     {
01577       /*
01578         We're evaluating "NULL IN (SELECT ...)". The result can be NULL or
01579         false, and we can return one instead of another. Just return NULL.
01580       */
01581       null_value= 1;
01582     }
01583     else
01584     {
01585       if (!((Item_in_subselect*)args[1])->is_correlated &&
01586           result_for_null_param != UNKNOWN)
01587       {
01588         /* Use cached value from previous execution */
01589         null_value= result_for_null_param;
01590       }
01591       else
01592       {
01593         /*
01594           We're evaluating "NULL IN (SELECT ...)". The result is:
01595              false if SELECT produces an empty set, or
01596              NULL  otherwise.
01597           We disable the predicates we've pushed down into subselect, run the
01598           subselect and see if it has produced any rows.
01599         */
01600         Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
01601         if (cache->cols() == 1)
01602         {
01603           item_subs->set_cond_guard_var(0, false);
01604           (void) args[1]->val_bool_result();
01605           result_for_null_param= null_value= !item_subs->engine->no_rows();
01606           item_subs->set_cond_guard_var(0, true);
01607         }
01608         else
01609         {
01610           uint32_t i;
01611           uint32_t ncols= cache->cols();
01612           /*
01613             Turn off the predicates that are based on column compares for
01614             which the left part is currently NULL
01615           */
01616           for (i= 0; i < ncols; i++)
01617           {
01618             if (cache->element_index(i)->null_value)
01619               item_subs->set_cond_guard_var(i, false);
01620           }
01621 
01622           (void) args[1]->val_bool_result();
01623           result_for_null_param= null_value= !item_subs->engine->no_rows();
01624 
01625           /* Turn all predicates back on */
01626           for (i= 0; i < ncols; i++)
01627             item_subs->set_cond_guard_var(i, true);
01628         }
01629       }
01630     }
01631     return 0;
01632   }
01633   tmp= args[1]->val_bool_result();
01634   null_value= args[1]->null_value;
01635   return tmp;
01636 }
01637 
01638 
01639 void Item_in_optimizer::keep_top_level_cache()
01640 {
01641   cache->keep_array();
01642   save_cache= 1;
01643 }
01644 
01645 
01646 void Item_in_optimizer::cleanup()
01647 {
01648   item::function::Boolean::cleanup();
01649   if (!save_cache)
01650     cache= 0;
01651   return;
01652 }
01653 
01654 
01655 bool Item_in_optimizer::is_null()
01656 {
01657   cache->store(args[0]);
01658   return (null_value= (cache->null_value || args[1]->is_null()));
01659 }
01660 
01661 
01684 Item *Item_in_optimizer::transform(Item_transformer transformer, unsigned char *argument)
01685 {
01686   Item *new_item;
01687 
01688   assert(arg_count == 2);
01689 
01690   /* Transform the left IN operand. */
01691   new_item= (*args)->transform(transformer, argument);
01692   if (!new_item)
01693     return 0;
01694   *args= new_item;
01695 
01696   /*
01697     Transform the right IN operand which should be an Item_in_subselect or a
01698     subclass of it. The left operand of the IN must be the same as the left
01699     operand of this Item_in_optimizer, so in this case there is no further
01700     transformation, we only make both operands the same.
01701     TODO: is it the way it should be?
01702   */
01703   assert((args[1])->type() == Item::SUBSELECT_ITEM &&
01704               (((Item_subselect*)(args[1]))->substype() ==
01705                Item_subselect::IN_SUBS ||
01706                ((Item_subselect*)(args[1]))->substype() ==
01707                Item_subselect::ALL_SUBS ||
01708                ((Item_subselect*)(args[1]))->substype() ==
01709                Item_subselect::ANY_SUBS));
01710 
01711   Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
01712   in_arg->left_expr= args[0];
01713 
01714   return (this->*transformer)(argument);
01715 }
01716 
01717 
01718 
01719 int64_t Item_func_eq::val_int()
01720 {
01721   assert(fixed == 1);
01722   int value= cmp.compare();
01723   return value == 0 ? 1 : 0;
01724 }
01725 
01726 
01729 void Item_func_equal::fix_length_and_dec()
01730 {
01731   Item_bool_func2::fix_length_and_dec();
01732   maybe_null=null_value=0;
01733 }
01734 
01735 int64_t Item_func_equal::val_int()
01736 {
01737   assert(fixed == 1);
01738   return cmp.compare();
01739 }
01740 
01741 int64_t Item_func_ne::val_int()
01742 {
01743   assert(fixed == 1);
01744   int value= cmp.compare();
01745   return value != 0 && !null_value ? 1 : 0;
01746 }
01747 
01748 
01749 int64_t Item_func_ge::val_int()
01750 {
01751   assert(fixed == 1);
01752   int value= cmp.compare();
01753   return value >= 0 ? 1 : 0;
01754 }
01755 
01756 
01757 int64_t Item_func_gt::val_int()
01758 {
01759   assert(fixed == 1);
01760   int value= cmp.compare();
01761   return value > 0 ? 1 : 0;
01762 }
01763 
01764 int64_t Item_func_le::val_int()
01765 {
01766   assert(fixed == 1);
01767   int value= cmp.compare();
01768   return value <= 0 && !null_value ? 1 : 0;
01769 }
01770 
01771 
01772 int64_t Item_func_lt::val_int()
01773 {
01774   assert(fixed == 1);
01775   int value= cmp.compare();
01776   return value < 0 && !null_value ? 1 : 0;
01777 }
01778 
01779 
01780 int64_t Item_func_strcmp::val_int()
01781 {
01782   assert(fixed == 1);
01783   String *a=args[0]->val_str(&tmp_value1);
01784   String *b=args[1]->val_str(&tmp_value2);
01785   if (!a || !b)
01786   {
01787     null_value=1;
01788     return 0;
01789   }
01790   int value= sortcmp(a,b,cmp.cmp_collation.collation);
01791   null_value=0;
01792   return !value ? 0 : (value < 0 ? (int64_t) -1 : (int64_t) 1);
01793 }
01794 
01795 
01796 bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const
01797 {
01798   /* Assume we don't have rtti */
01799   if (this == item)
01800     return 1;
01801   if (item->type() != FUNC_ITEM)
01802     return 0;
01803   Item_func *item_func=(Item_func*) item;
01804   if (arg_count != item_func->arg_count ||
01805       functype() != item_func->functype())
01806     return 0;
01807   if (negated != ((Item_func_opt_neg *) item_func)->negated)
01808     return 0;
01809   for (uint32_t i=0; i < arg_count ; i++)
01810     if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
01811       return 0;
01812   return 1;
01813 }
01814 
01815 
01816 void Item_func_interval::fix_length_and_dec()
01817 {
01818   uint32_t rows= row->cols();
01819 
01820   use_decimal_comparison= ((row->element_index(0)->result_type() ==
01821                             DECIMAL_RESULT) ||
01822                            (row->element_index(0)->result_type() ==
01823                             INT_RESULT));
01824   if (rows > 8)
01825   {
01826     bool not_null_consts= true;
01827 
01828     for (uint32_t i= 1; not_null_consts && i < rows; i++)
01829     {
01830       Item *el= row->element_index(i);
01831       not_null_consts&= el->const_item() & !el->is_null();
01832     }
01833 
01834     if (not_null_consts &&
01835         (intervals=
01836           (interval_range*) memory::sql_alloc(sizeof(interval_range) * (rows - 1))))
01837     {
01838       if (use_decimal_comparison)
01839       {
01840         for (uint32_t i= 1; i < rows; i++)
01841         {
01842           Item *el= row->element_index(i);
01843           interval_range *range= intervals + (i-1);
01844           if ((el->result_type() == DECIMAL_RESULT) ||
01845               (el->result_type() == INT_RESULT))
01846           {
01847             range->type= DECIMAL_RESULT;
01848             range->dec.init();
01849             type::Decimal *dec= el->val_decimal(&range->dec);
01850             if (dec != &range->dec)
01851             {
01852               range->dec= *dec;
01853               range->dec.fix_buffer_pointer();
01854             }
01855           }
01856           else
01857           {
01858             range->type= REAL_RESULT;
01859             range->dbl= el->val_real();
01860           }
01861         }
01862       }
01863       else
01864       {
01865         for (uint32_t i= 1; i < rows; i++)
01866         {
01867           intervals[i-1].dbl= row->element_index(i)->val_real();
01868         }
01869       }
01870     }
01871   }
01872   maybe_null= 0;
01873   max_length= 2;
01874   used_tables_cache|= row->used_tables();
01875   not_null_tables_cache= row->not_null_tables();
01876   with_sum_func= with_sum_func || row->with_sum_func;
01877   const_item_cache&= row->const_item();
01878 }
01879 
01880 
01895 int64_t Item_func_interval::val_int()
01896 {
01897   assert(fixed == 1);
01898   double value;
01899   type::Decimal dec_buf, *dec= NULL;
01900   uint32_t i;
01901 
01902   if (use_decimal_comparison)
01903   {
01904     dec= row->element_index(0)->val_decimal(&dec_buf);
01905     if (row->element_index(0)->null_value)
01906       return -1;
01907     class_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
01908   }
01909   else
01910   {
01911     value= row->element_index(0)->val_real();
01912     if (row->element_index(0)->null_value)
01913       return -1;
01914   }
01915 
01916   if (intervals)
01917   {         // Use binary search to find interval
01918     uint32_t start,end;
01919     start= 0;
01920     end=   row->cols()-2;
01921     while (start != end)
01922     {
01923       uint32_t mid= (start + end + 1) / 2;
01924       interval_range *range= intervals + mid;
01925       bool cmp_result;
01926       /*
01927         The values in the range intervall may have different types,
01928         Only do a decimal comparision of the first argument is a decimal
01929         and we are comparing against a decimal
01930       */
01931       if (dec && range->type == DECIMAL_RESULT)
01932         cmp_result= class_decimal_cmp(&range->dec, dec) <= 0;
01933       else
01934         cmp_result= (range->dbl <= value);
01935       if (cmp_result)
01936   start= mid;
01937       else
01938   end= mid - 1;
01939     }
01940     interval_range *range= intervals+start;
01941     return ((dec && range->type == DECIMAL_RESULT) ?
01942             class_decimal_cmp(dec, &range->dec) < 0 :
01943             value < range->dbl) ? 0 : start + 1;
01944   }
01945 
01946   for (i=1 ; i < row->cols() ; i++)
01947   {
01948     Item *el= row->element_index(i);
01949     if (use_decimal_comparison &&
01950         ((el->result_type() == DECIMAL_RESULT) ||
01951          (el->result_type() == INT_RESULT)))
01952     {
01953       type::Decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
01954       /* Skip NULL ranges. */
01955       if (el->null_value)
01956         continue;
01957       if (class_decimal_cmp(e_dec, dec) > 0)
01958         return i - 1;
01959     }
01960     else
01961     {
01962       double val= el->val_real();
01963       /* Skip NULL ranges. */
01964       if (el->null_value)
01965         continue;
01966       if (val > value)
01967         return i - 1;
01968     }
01969   }
01970   return i-1;
01971 }
01972 
01973 
02002 bool Item_func_between::fix_fields(Session *session, Item **ref)
02003 {
02004   if (Item_func_opt_neg::fix_fields(session, ref))
02005     return 1;
02006 
02007   session->lex().current_select->between_count++;
02008 
02009   /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
02010   if (pred_level && !negated)
02011     return 0;
02012 
02013   /* not_null_tables_cache == union(T1(e), intersection(T1(e1),T1(e2))) */
02014   not_null_tables_cache= (args[0]->not_null_tables() |
02015                           (args[1]->not_null_tables() &
02016                            args[2]->not_null_tables()));
02017 
02018   return 0;
02019 }
02020 
02021 
02022 void Item_func_between::fix_length_and_dec()
02023 {
02024   max_length= 1;
02025   int i;
02026   bool datetime_found= false;
02027   compare_as_dates= true;
02028 
02029   /*
02030     As some compare functions are generated after sql_yacc,
02031     we have to check for out of memory conditions here
02032   */
02033   if (!args[0] || !args[1] || !args[2])
02034     return;
02035   if ( agg_cmp_type(&cmp_type, args, 3))
02036     return;
02037   if (cmp_type == STRING_RESULT &&
02038       agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
02039    return;
02040 
02041   /*
02042     Detect the comparison of DATE/DATETIME items.
02043     At least one of items should be a DATE/DATETIME item and other items
02044     should return the STRING result.
02045   */
02046   if (cmp_type == STRING_RESULT)
02047   {
02048     for (i= 0; i < 3; i++)
02049     {
02050       if (args[i]->is_datetime())
02051       {
02052         datetime_found= true;
02053         continue;
02054       }
02055     }
02056   }
02057   if (!datetime_found)
02058     compare_as_dates= false;
02059 
02060   if (compare_as_dates)
02061   {
02062     ge_cmp.set_datetime_cmp_func(args, args + 1);
02063     le_cmp.set_datetime_cmp_func(args, args + 2);
02064   }
02065   else if (args[0]->real_item()->type() == FIELD_ITEM)
02066   {
02067     Item_field *field_item= (Item_field*) (args[0]->real_item());
02068     if (field_item->field->can_be_compared_as_int64_t())
02069     {
02070       /*
02071         The following can't be recoded with || as convert_constant_item
02072         changes the argument
02073       */
02074       if (convert_constant_item(&getSession(), field_item, &args[1]))
02075         cmp_type=INT_RESULT;      // Works for all types.
02076       if (convert_constant_item(&getSession(), field_item, &args[2]))
02077         cmp_type=INT_RESULT;      // Works for all types.
02078     }
02079   }
02080 }
02081 
02082 
02083 int64_t Item_func_between::val_int()
02084 {           // ANSI BETWEEN
02085   assert(fixed == 1);
02086   if (compare_as_dates)
02087   {
02088     int ge_res, le_res;
02089 
02090     ge_res= ge_cmp.compare();
02091     if ((null_value= args[0]->null_value))
02092       return 0;
02093     le_res= le_cmp.compare();
02094 
02095     if (!args[1]->null_value && !args[2]->null_value)
02096       return (int64_t) ((ge_res >= 0 && le_res <=0) != negated);
02097     else if (args[1]->null_value)
02098     {
02099       null_value= le_res > 0;     // not null if false range.
02100     }
02101     else
02102     {
02103       null_value= ge_res < 0;
02104     }
02105   }
02106   else if (cmp_type == STRING_RESULT)
02107   {
02108     String *value,*a,*b;
02109     value=args[0]->val_str(&value0);
02110     if ((null_value=args[0]->null_value))
02111       return 0;
02112     a=args[1]->val_str(&value1);
02113     b=args[2]->val_str(&value2);
02114     if (!args[1]->null_value && !args[2]->null_value)
02115       return (int64_t) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
02116                           sortcmp(value,b,cmp_collation.collation) <= 0) !=
02117                          negated);
02118     if (args[1]->null_value && args[2]->null_value)
02119       null_value=1;
02120     else if (args[1]->null_value)
02121     {
02122       // Set to not null if false range.
02123       null_value= sortcmp(value,b,cmp_collation.collation) <= 0;
02124     }
02125     else
02126     {
02127       // Set to not null if false range.
02128       null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
02129     }
02130   }
02131   else if (cmp_type == INT_RESULT)
02132   {
02133     int64_t value=args[0]->val_int(), a, b;
02134     if ((null_value=args[0]->null_value))
02135       return 0;
02136     a=args[1]->val_int();
02137     b=args[2]->val_int();
02138     if (!args[1]->null_value && !args[2]->null_value)
02139       return (int64_t) ((value >= a && value <= b) != negated);
02140     if (args[1]->null_value && args[2]->null_value)
02141       null_value=1;
02142     else if (args[1]->null_value)
02143     {
02144       null_value= value <= b;     // not null if false range.
02145     }
02146     else
02147     {
02148       null_value= value >= a;
02149     }
02150   }
02151   else if (cmp_type == DECIMAL_RESULT)
02152   {
02153     type::Decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
02154                a_buf, *a_dec, b_buf, *b_dec;
02155     if ((null_value=args[0]->null_value))
02156       return 0;
02157     a_dec= args[1]->val_decimal(&a_buf);
02158     b_dec= args[2]->val_decimal(&b_buf);
02159     if (!args[1]->null_value && !args[2]->null_value)
02160       return (int64_t) ((class_decimal_cmp(dec, a_dec) >= 0 &&
02161                           class_decimal_cmp(dec, b_dec) <= 0) != negated);
02162     if (args[1]->null_value && args[2]->null_value)
02163       null_value=1;
02164     else if (args[1]->null_value)
02165       null_value= (class_decimal_cmp(dec, b_dec) <= 0);
02166     else
02167       null_value= (class_decimal_cmp(dec, a_dec) >= 0);
02168   }
02169   else
02170   {
02171     double value= args[0]->val_real(),a,b;
02172     if ((null_value=args[0]->null_value))
02173       return 0;
02174     a= args[1]->val_real();
02175     b= args[2]->val_real();
02176     if (!args[1]->null_value && !args[2]->null_value)
02177       return (int64_t) ((value >= a && value <= b) != negated);
02178     if (args[1]->null_value && args[2]->null_value)
02179       null_value=1;
02180     else if (args[1]->null_value)
02181     {
02182       null_value= value <= b;     // not null if false range.
02183     }
02184     else
02185     {
02186       null_value= value >= a;
02187     }
02188   }
02189   return (int64_t) (!null_value && negated);
02190 }
02191 
02192 
02193 void Item_func_between::print(String *str)
02194 {
02195   str->append('(');
02196   args[0]->print(str);
02197   if (negated)
02198     str->append(STRING_WITH_LEN(" not"));
02199   str->append(STRING_WITH_LEN(" between "));
02200   args[1]->print(str);
02201   str->append(STRING_WITH_LEN(" and "));
02202   args[2]->print(str);
02203   str->append(')');
02204 }
02205 
02206 void
02207 Item_func_ifnull::fix_length_and_dec()
02208 {
02209   agg_result_type(&hybrid_type, args, 2);
02210   maybe_null= args[1]->maybe_null;
02211   decimals= max(args[0]->decimals, args[1]->decimals);
02212   unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
02213 
02214   if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
02215   {
02216     int len0= args[0]->max_length - args[0]->decimals
02217       - (args[0]->unsigned_flag ? 0 : 1);
02218 
02219     int len1= args[1]->max_length - args[1]->decimals
02220       - (args[1]->unsigned_flag ? 0 : 1);
02221 
02222     max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
02223   }
02224   else
02225   {
02226     max_length= max(args[0]->max_length, args[1]->max_length);
02227   }
02228 
02229   switch (hybrid_type)
02230   {
02231   case STRING_RESULT:
02232     agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
02233     break;
02234 
02235   case DECIMAL_RESULT:
02236   case REAL_RESULT:
02237     break;
02238 
02239   case INT_RESULT:
02240     decimals= 0;
02241     break;
02242 
02243   case ROW_RESULT:
02244     assert(0);
02245   }
02246 
02247   cached_field_type= agg_field_type(args, 2);
02248 }
02249 
02250 
02251 uint32_t Item_func_ifnull::decimal_precision() const
02252 {
02253   int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
02254   return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
02255 }
02256 
02257 
02258 enum_field_types Item_func_ifnull::field_type() const
02259 {
02260   return cached_field_type;
02261 }
02262 
02263 Field *Item_func_ifnull::tmp_table_field(Table *table)
02264 {
02265   return tmp_table_field_from_field_type(table, 0);
02266 }
02267 
02268 double
02269 Item_func_ifnull::real_op()
02270 {
02271   assert(fixed == 1);
02272   double value= args[0]->val_real();
02273   if (!args[0]->null_value)
02274   {
02275     null_value=0;
02276     return value;
02277   }
02278   value= args[1]->val_real();
02279   if ((null_value=args[1]->null_value))
02280     return 0.0;
02281   return value;
02282 }
02283 
02284 int64_t
02285 Item_func_ifnull::int_op()
02286 {
02287   assert(fixed == 1);
02288   int64_t value=args[0]->val_int();
02289   if (!args[0]->null_value)
02290   {
02291     null_value=0;
02292     return value;
02293   }
02294   value=args[1]->val_int();
02295   if ((null_value=args[1]->null_value))
02296     return 0;
02297   return value;
02298 }
02299 
02300 
02301 type::Decimal *Item_func_ifnull::decimal_op(type::Decimal *decimal_value)
02302 {
02303   assert(fixed == 1);
02304   type::Decimal *value= args[0]->val_decimal(decimal_value);
02305   if (!args[0]->null_value)
02306   {
02307     null_value= 0;
02308     return value;
02309   }
02310   value= args[1]->val_decimal(decimal_value);
02311   if ((null_value= args[1]->null_value))
02312     return 0;
02313   return value;
02314 }
02315 
02316 
02317 String *
02318 Item_func_ifnull::str_op(String *str)
02319 {
02320   assert(fixed == 1);
02321   String *res  =args[0]->val_str(str);
02322   if (!args[0]->null_value)
02323   {
02324     null_value=0;
02325     res->set_charset(collation.collation);
02326     return res;
02327   }
02328   res=args[1]->val_str(str);
02329   if ((null_value=args[1]->null_value))
02330     return 0;
02331   res->set_charset(collation.collation);
02332   return res;
02333 }
02334 
02335 
02362 bool
02363 Item_func_if::fix_fields(Session *session, Item **ref)
02364 {
02365   assert(fixed == 0);
02366   args[0]->top_level_item();
02367 
02368   if (Item_func::fix_fields(session, ref))
02369     return 1;
02370 
02371   not_null_tables_cache= (args[1]->not_null_tables() &
02372                           args[2]->not_null_tables());
02373 
02374   return 0;
02375 }
02376 
02377 
02378 void
02379 Item_func_if::fix_length_and_dec()
02380 {
02381   maybe_null= args[1]->maybe_null || args[2]->maybe_null;
02382   decimals= max(args[1]->decimals, args[2]->decimals);
02383   unsigned_flag= args[1]->unsigned_flag && args[2]->unsigned_flag;
02384 
02385   enum Item_result arg1_type= args[1]->result_type();
02386   enum Item_result arg2_type= args[2]->result_type();
02387   bool null1= args[1]->const_item() && args[1]->null_value;
02388   bool null2= args[2]->const_item() && args[2]->null_value;
02389 
02390   if (null1)
02391   {
02392     cached_result_type= arg2_type;
02393     collation.set(args[2]->collation.collation);
02394     cached_field_type= args[2]->field_type();
02395   }
02396   else if (null2)
02397   {
02398     cached_result_type= arg1_type;
02399     collation.set(args[1]->collation.collation);
02400     cached_field_type= args[1]->field_type();
02401   }
02402   else
02403   {
02404     agg_result_type(&cached_result_type, args+1, 2);
02405     if (cached_result_type == STRING_RESULT)
02406     {
02407       if (agg_arg_charsets(collation, args+1, 2, MY_COLL_ALLOW_CONV, 1))
02408         return;
02409     }
02410     else
02411     {
02412       collation.set(&my_charset_bin); // Number
02413     }
02414     cached_field_type= agg_field_type(args + 1, 2);
02415   }
02416 
02417   if ((cached_result_type == DECIMAL_RESULT )
02418       || (cached_result_type == INT_RESULT))
02419   {
02420     int len1= args[1]->max_length - args[1]->decimals
02421       - (args[1]->unsigned_flag ? 0 : 1);
02422 
02423     int len2= args[2]->max_length - args[2]->decimals
02424       - (args[2]->unsigned_flag ? 0 : 1);
02425 
02426     max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
02427   }
02428   else
02429     max_length= max(args[1]->max_length, args[2]->max_length);
02430 }
02431 
02432 
02433 uint32_t Item_func_if::decimal_precision() const
02434 {
02435   int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
02436                   decimals);
02437   return min(precision, DECIMAL_MAX_PRECISION);
02438 }
02439 
02440 
02441 double
02442 Item_func_if::val_real()
02443 {
02444   assert(fixed == 1);
02445   Item *arg= args[0]->val_bool() ? args[1] : args[2];
02446   double value= arg->val_real();
02447   null_value=arg->null_value;
02448   return value;
02449 }
02450 
02451 int64_t
02452 Item_func_if::val_int()
02453 {
02454   assert(fixed == 1);
02455   Item *arg= args[0]->val_bool() ? args[1] : args[2];
02456   int64_t value=arg->val_int();
02457   null_value=arg->null_value;
02458   return value;
02459 }
02460 
02461 String *
02462 Item_func_if::val_str(String *str)
02463 {
02464   assert(fixed == 1);
02465   Item *arg= args[0]->val_bool() ? args[1] : args[2];
02466   String *res=arg->val_str(str);
02467   if (res)
02468     res->set_charset(collation.collation);
02469   null_value=arg->null_value;
02470   return res;
02471 }
02472 
02473 
02474 type::Decimal *
02475 Item_func_if::val_decimal(type::Decimal *decimal_value)
02476 {
02477   assert(fixed == 1);
02478   Item *arg= args[0]->val_bool() ? args[1] : args[2];
02479   type::Decimal *value= arg->val_decimal(decimal_value);
02480   null_value= arg->null_value;
02481   return value;
02482 }
02483 
02484 
02485 void
02486 Item_func_nullif::fix_length_and_dec()
02487 {
02488   Item_bool_func2::fix_length_and_dec();
02489   maybe_null=1;
02490   if (args[0])          // Only false if EOM
02491   {
02492     max_length=args[0]->max_length;
02493     decimals=args[0]->decimals;
02494     unsigned_flag= args[0]->unsigned_flag;
02495     cached_result_type= args[0]->result_type();
02496     if (cached_result_type == STRING_RESULT &&
02497         agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1))
02498       return;
02499   }
02500 }
02501 
02502 
02513 double
02514 Item_func_nullif::val_real()
02515 {
02516   assert(fixed == 1);
02517   double value;
02518   if (!cmp.compare())
02519   {
02520     null_value=1;
02521     return 0.0;
02522   }
02523   value= args[0]->val_real();
02524   null_value=args[0]->null_value;
02525   return value;
02526 }
02527 
02528 int64_t
02529 Item_func_nullif::val_int()
02530 {
02531   assert(fixed == 1);
02532   int64_t value;
02533   if (!cmp.compare())
02534   {
02535     null_value=1;
02536     return 0;
02537   }
02538   value=args[0]->val_int();
02539   null_value=args[0]->null_value;
02540   return value;
02541 }
02542 
02543 String *
02544 Item_func_nullif::val_str(String *str)
02545 {
02546   assert(fixed == 1);
02547   String *res;
02548   if (!cmp.compare())
02549   {
02550     null_value=1;
02551     return 0;
02552   }
02553   res=args[0]->val_str(str);
02554   null_value=args[0]->null_value;
02555   return res;
02556 }
02557 
02558 
02559 type::Decimal *
02560 Item_func_nullif::val_decimal(type::Decimal * decimal_value)
02561 {
02562   assert(fixed == 1);
02563   type::Decimal *res;
02564   if (!cmp.compare())
02565   {
02566     null_value=1;
02567     return 0;
02568   }
02569   res= args[0]->val_decimal(decimal_value);
02570   null_value= args[0]->null_value;
02571   return res;
02572 }
02573 
02574 
02575 bool
02576 Item_func_nullif::is_null()
02577 {
02578   return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
02579 }
02580 
02581 
02603 Item *Item_func_case::find_item(String *)
02604 {
02605   uint32_t value_added_map= 0;
02606 
02607   if (first_expr_num == -1)
02608   {
02609     for (uint32_t i=0 ; i < ncases ; i+=2)
02610     {
02611       // No expression between CASE and the first WHEN
02612       if (args[i]->val_bool())
02613   return args[i+1];
02614       continue;
02615     }
02616   }
02617   else
02618   {
02619     /* Compare every WHEN argument with it and return the first match */
02620     for (uint32_t i=0 ; i < ncases ; i+=2)
02621     {
02622       cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
02623       assert(cmp_type != ROW_RESULT);
02624       assert(cmp_items[(uint32_t)cmp_type]);
02625       if (!(value_added_map & (1<<(uint32_t)cmp_type)))
02626       {
02627         cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
02628         if ((null_value=args[first_expr_num]->null_value))
02629           return else_expr_num != -1 ? args[else_expr_num] : 0;
02630         value_added_map|= 1<<(uint32_t)cmp_type;
02631       }
02632       if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
02633         return args[i + 1];
02634     }
02635   }
02636   // No, WHEN clauses all missed, return ELSE expression
02637   return else_expr_num != -1 ? args[else_expr_num] : 0;
02638 }
02639 
02640 
02641 String *Item_func_case::val_str(String *str)
02642 {
02643   assert(fixed == 1);
02644   String *res;
02645   Item *item=find_item(str);
02646 
02647   if (!item)
02648   {
02649     null_value=1;
02650     return 0;
02651   }
02652   null_value= 0;
02653   if (!(res=item->val_str(str)))
02654     null_value= 1;
02655   return res;
02656 }
02657 
02658 
02659 int64_t Item_func_case::val_int()
02660 {
02661   assert(fixed == 1);
02662   char buff[MAX_FIELD_WIDTH];
02663   String dummy_str(buff,sizeof(buff),default_charset());
02664   Item *item=find_item(&dummy_str);
02665   int64_t res;
02666 
02667   if (!item)
02668   {
02669     null_value=1;
02670     return 0;
02671   }
02672   res=item->val_int();
02673   null_value=item->null_value;
02674   return res;
02675 }
02676 
02677 double Item_func_case::val_real()
02678 {
02679   assert(fixed == 1);
02680   char buff[MAX_FIELD_WIDTH];
02681   String dummy_str(buff,sizeof(buff),default_charset());
02682   Item *item=find_item(&dummy_str);
02683   double res;
02684 
02685   if (!item)
02686   {
02687     null_value=1;
02688     return 0;
02689   }
02690   res= item->val_real();
02691   null_value=item->null_value;
02692   return res;
02693 }
02694 
02695 
02696 type::Decimal *Item_func_case::val_decimal(type::Decimal *decimal_value)
02697 {
02698   assert(fixed == 1);
02699   char buff[MAX_FIELD_WIDTH];
02700   String dummy_str(buff, sizeof(buff), default_charset());
02701   Item *item= find_item(&dummy_str);
02702   type::Decimal *res;
02703 
02704   if (!item)
02705   {
02706     null_value=1;
02707     return 0;
02708   }
02709 
02710   res= item->val_decimal(decimal_value);
02711   null_value= item->null_value;
02712   return res;
02713 }
02714 
02715 
02716 bool Item_func_case::fix_fields(Session *session, Item **ref)
02717 {
02718   /*
02719     buff should match stack usage from
02720     Item_func_case::val_int() -> Item_func_case::find_item()
02721   */
02722   unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
02723                      +sizeof(double)*2+sizeof(int64_t)*2];
02724   bool res= Item_func::fix_fields(session, ref);
02725   /*
02726     Call check_stack_overrun after fix_fields to be sure that stack variable
02727     is not optimized away
02728   */
02729   if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
02730     return true;        // Fatal error flag is set!
02731   return res;
02732 }
02733 
02734 
02735 void Item_func_case::agg_str_lengths(Item* arg)
02736 {
02737   set_if_bigger(max_length, arg->max_length);
02738   set_if_bigger(decimals, arg->decimals);
02739   unsigned_flag= unsigned_flag && arg->unsigned_flag;
02740 }
02741 
02742 
02743 void Item_func_case::agg_num_lengths(Item *arg)
02744 {
02745   uint32_t len= class_decimal_length_to_precision(arg->max_length, arg->decimals,
02746                                            arg->unsigned_flag) - arg->decimals;
02747   set_if_bigger(max_length, len);
02748   set_if_bigger(decimals, arg->decimals);
02749   unsigned_flag= unsigned_flag && arg->unsigned_flag;
02750 }
02751 
02752 
02753 void Item_func_case::fix_length_and_dec()
02754 {
02755   Item **agg;
02756   uint32_t nagg;
02757   uint32_t found_types= 0;
02758   if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
02759     return;
02760 
02761   /*
02762     Aggregate all THEN and ELSE expression types
02763     and collations when string result
02764   */
02765 
02766   for (nagg= 0 ; nagg < ncases/2 ; nagg++)
02767     agg[nagg]= args[nagg*2+1];
02768 
02769   if (else_expr_num != -1)
02770     agg[nagg++]= args[else_expr_num];
02771 
02772   agg_result_type(&cached_result_type, agg, nagg);
02773   if ((cached_result_type == STRING_RESULT) &&
02774       agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
02775     return;
02776 
02777   cached_field_type= agg_field_type(agg, nagg);
02778   /*
02779     Aggregate first expression and all THEN expression types
02780     and collations when string comparison
02781   */
02782   if (first_expr_num != -1)
02783   {
02784     agg[0]= args[first_expr_num];
02785     left_result_type= agg[0]->result_type();
02786 
02787     for (nagg= 0; nagg < ncases/2 ; nagg++)
02788       agg[nagg+1]= args[nagg*2];
02789     nagg++;
02790     if (!(found_types= collect_cmp_types(agg, nagg)))
02791       return;
02792 
02793     for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
02794     {
02795       if (found_types & (1 << i) && !cmp_items[i])
02796       {
02797         assert((Item_result)i != ROW_RESULT);
02798         if ((Item_result)i == STRING_RESULT &&
02799             agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
02800           return;
02801         if (!(cmp_items[i]=
02802             cmp_item::get_comparator((Item_result)i,
02803                                      cmp_collation.collation)))
02804           return;
02805       }
02806     }
02807   }
02808 
02809   if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
02810     maybe_null=1;
02811 
02812   max_length=0;
02813   decimals=0;
02814   unsigned_flag= true;
02815   if (cached_result_type == STRING_RESULT)
02816   {
02817     for (uint32_t i= 0; i < ncases; i+= 2)
02818       agg_str_lengths(args[i + 1]);
02819     if (else_expr_num != -1)
02820       agg_str_lengths(args[else_expr_num]);
02821   }
02822   else
02823   {
02824     for (uint32_t i= 0; i < ncases; i+= 2)
02825       agg_num_lengths(args[i + 1]);
02826     if (else_expr_num != -1)
02827       agg_num_lengths(args[else_expr_num]);
02828     max_length= class_decimal_precision_to_length(max_length + decimals, decimals,
02829                                                unsigned_flag);
02830   }
02831 }
02832 
02833 
02834 uint32_t Item_func_case::decimal_precision() const
02835 {
02836   int max_int_part=0;
02837   for (uint32_t i=0 ; i < ncases ; i+=2)
02838     set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
02839 
02840   if (else_expr_num != -1)
02841     set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
02842   return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
02843 }
02844 
02845 
02851 void Item_func_case::print(String *str)
02852 {
02853   str->append(STRING_WITH_LEN("(case "));
02854   if (first_expr_num != -1)
02855   {
02856     args[first_expr_num]->print(str);
02857     str->append(' ');
02858   }
02859   for (uint32_t i=0 ; i < ncases ; i+=2)
02860   {
02861     str->append(STRING_WITH_LEN("when "));
02862     args[i]->print(str);
02863     str->append(STRING_WITH_LEN(" then "));
02864     args[i+1]->print(str);
02865     str->append(' ');
02866   }
02867   if (else_expr_num != -1)
02868   {
02869     str->append(STRING_WITH_LEN("else "));
02870     args[else_expr_num]->print(str);
02871     str->append(' ');
02872   }
02873   str->append(STRING_WITH_LEN("end)"));
02874 }
02875 
02876 
02877 void Item_func_case::cleanup()
02878 {
02879   Item_func::cleanup();
02880   for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
02881   {
02882     delete cmp_items[i];
02883     cmp_items[i]= 0;
02884   }
02885 }
02886 
02887 
02892 String *Item_func_coalesce::str_op(String *str)
02893 {
02894   assert(fixed == 1);
02895   null_value=0;
02896   for (uint32_t i=0 ; i < arg_count ; i++)
02897   {
02898     String *res;
02899     if ((res=args[i]->val_str(str)))
02900       return res;
02901   }
02902   null_value=1;
02903   return 0;
02904 }
02905 
02906 int64_t Item_func_coalesce::int_op()
02907 {
02908   assert(fixed == 1);
02909   null_value=0;
02910   for (uint32_t i=0 ; i < arg_count ; i++)
02911   {
02912     int64_t res=args[i]->val_int();
02913     if (!args[i]->null_value)
02914       return res;
02915   }
02916   null_value=1;
02917   return 0;
02918 }
02919 
02920 double Item_func_coalesce::real_op()
02921 {
02922   assert(fixed == 1);
02923   null_value=0;
02924   for (uint32_t i=0 ; i < arg_count ; i++)
02925   {
02926     double res= args[i]->val_real();
02927     if (!args[i]->null_value)
02928       return res;
02929   }
02930   null_value=1;
02931   return 0;
02932 }
02933 
02934 
02935 type::Decimal *Item_func_coalesce::decimal_op(type::Decimal *decimal_value)
02936 {
02937   assert(fixed == 1);
02938   null_value= 0;
02939   for (uint32_t i= 0; i < arg_count; i++)
02940   {
02941     type::Decimal *res= args[i]->val_decimal(decimal_value);
02942     if (!args[i]->null_value)
02943       return res;
02944   }
02945   null_value=1;
02946   return 0;
02947 }
02948 
02949 
02950 void Item_func_coalesce::fix_length_and_dec()
02951 {
02952   cached_field_type= agg_field_type(args, arg_count);
02953   agg_result_type(&hybrid_type, args, arg_count);
02954 
02955   switch (hybrid_type) {
02956   case STRING_RESULT:
02957     count_only_length();
02958     decimals= NOT_FIXED_DEC;
02959     agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
02960     break;
02961 
02962   case DECIMAL_RESULT:
02963     count_decimal_length();
02964     break;
02965 
02966   case REAL_RESULT:
02967     count_real_length();
02968     break;
02969 
02970   case INT_RESULT:
02971     count_only_length();
02972     decimals= 0;
02973     break;
02974 
02975   case ROW_RESULT:
02976     assert(0);
02977   }
02978 }
02979 
02980 /****************************************************************************
02981  Classes and function for the IN operator
02982 ****************************************************************************/
02983 
02984 /*
02985   Determine which of the signed int64_t arguments is bigger
02986 
02987   SYNOPSIS
02988     cmp_longs()
02989       a_val     left argument
02990       b_val     right argument
02991 
02992   DESCRIPTION
02993     This function will compare two signed int64_t arguments
02994     and will return -1, 0, or 1 if left argument is smaller than,
02995     equal to or greater than the right argument.
02996 
02997   RETURN VALUE
02998     -1          left argument is smaller than the right argument.
02999     0           left argument is equal to the right argument.
03000     1           left argument is greater than the right argument.
03001 */
03002 static inline int cmp_longs (int64_t a_val, int64_t b_val)
03003 {
03004   return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
03005 }
03006 
03007 
03008 /*
03009   Determine which of the unsigned int64_t arguments is bigger
03010 
03011   SYNOPSIS
03012     cmp_ulongs()
03013       a_val     left argument
03014       b_val     right argument
03015 
03016   DESCRIPTION
03017     This function will compare two unsigned int64_t arguments
03018     and will return -1, 0, or 1 if left argument is smaller than,
03019     equal to or greater than the right argument.
03020 
03021   RETURN VALUE
03022     -1          left argument is smaller than the right argument.
03023     0           left argument is equal to the right argument.
03024     1           left argument is greater than the right argument.
03025 */
03026 static inline int cmp_ulongs (uint64_t a_val, uint64_t b_val)
03027 {
03028   return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
03029 }
03030 
03031 
03032 /*
03033   Compare two integers in IN value list format (packed_int64_t)
03034 
03035   SYNOPSIS
03036     cmp_int64_t()
03037       cmp_arg   an argument passed to the calling function (my_qsort2)
03038       a         left argument
03039       b         right argument
03040 
03041   DESCRIPTION
03042     This function will compare two integer arguments in the IN value list
03043     format and will return -1, 0, or 1 if left argument is smaller than,
03044     equal to or greater than the right argument.
03045     It's used in sorting the IN values list and finding an element in it.
03046     Depending on the signedness of the arguments cmp_int64_t() will
03047     compare them as either signed (using cmp_longs()) or unsigned (using
03048     cmp_ulongs()).
03049 
03050   RETURN VALUE
03051     -1          left argument is smaller than the right argument.
03052     0           left argument is equal to the right argument.
03053     1           left argument is greater than the right argument.
03054 */
03055 int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
03056                 in_int64_t::packed_int64_t *b)
03057 {
03058   if (a->unsigned_flag != b->unsigned_flag)
03059   {
03060     /*
03061       One of the args is unsigned and is too big to fit into the
03062       positive signed range. Report no match.
03063     */
03064     if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
03065         (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
03066       return a->unsigned_flag ? 1 : -1;
03067     /*
03068       Although the signedness differs both args can fit into the signed
03069       positive range. Make them signed and compare as usual.
03070     */
03071     return cmp_longs (a->val, b->val);
03072   }
03073   if (a->unsigned_flag)
03074     return cmp_ulongs ((uint64_t) a->val, (uint64_t) b->val);
03075   else
03076     return cmp_longs (a->val, b->val);
03077 }
03078 
03079 static int cmp_double(void *, double *a, double *b)
03080 {
03081   return *a < *b ? -1 : *a == *b ? 0 : 1;
03082 }
03083 
03084 static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
03085 {
03086   return a->compare(b);
03087 }
03088 
03089 
03090 static int cmp_decimal(void *, type::Decimal *a, type::Decimal *b)
03091 {
03092   /*
03093     We need call of fixing buffer pointer, because fast sort just copy
03094     decimal buffers in memory and pointers left pointing on old buffer place
03095   */
03096   a->fix_buffer_pointer();
03097   b->fix_buffer_pointer();
03098   return class_decimal_cmp(a, b);
03099 }
03100 
03101 
03102 void in_vector::sort()
03103 {
03104   internal::my_qsort2(base,used_count,size,compare, (void *) collation);
03105 }
03106 
03107 
03108 int in_vector::find(Item *item)
03109 {
03110   unsigned char *result=get_value(item);
03111   if (!result || !used_count)
03112     return 0;       // Null value
03113 
03114   uint32_t start,end;
03115   start=0; end=used_count-1;
03116   while (start != end)
03117   {
03118     uint32_t mid=(start+end+1)/2;
03119     int res;
03120     if ((res=(*compare)(collation, base+mid*size, result)) == 0)
03121       return 1;
03122     if (res < 0)
03123       start=mid;
03124     else
03125       end=mid-1;
03126   }
03127   return (int) ((*compare)(collation, base+start*size, result) == 0);
03128 }
03129 
03130 in_string::in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
03131   :in_vector(elements, sizeof(String), cmp_func, cs),
03132    tmp(buff, sizeof(buff), &my_charset_bin)
03133 {}
03134 
03135 in_string::~in_string()
03136 {
03137   if (base)
03138   {
03139     // base was allocated with help of memory::sql_alloc => following is OK
03140     for (uint32_t i=0 ; i < count ; i++)
03141       ((String*) base)[i].free();
03142   }
03143 }
03144 
03145 void in_string::set(uint32_t pos,Item *item)
03146 {
03147   String *str=((String*) base)+pos;
03148   String *res=item->val_str(str);
03149   if (res && res != str)
03150   {
03151     if (res->uses_buffer_owned_by(str))
03152       res->copy();
03153     if (item->type() == Item::FUNC_ITEM)
03154       str->copy(*res);
03155     else
03156       *str= *res;
03157   }
03158   if (!str->charset())
03159   {
03160     const CHARSET_INFO *cs;
03161     if (!(cs= item->collation.collation))
03162       cs= &my_charset_bin;    // Should never happen for STR items
03163     str->set_charset(cs);
03164   }
03165 }
03166 
03167 
03168 unsigned char *in_string::get_value(Item *item)
03169 {
03170   return (unsigned char*) item->val_str(&tmp);
03171 }
03172 
03173 in_row::in_row(uint32_t elements, Item *)
03174 {
03175   base= (char*) new cmp_item_row[count= elements];
03176   size= sizeof(cmp_item_row);
03177   compare= (qsort2_cmp) cmp_row;
03178   /*
03179     We need to reset these as otherwise we will call sort() with
03180     uninitialized (even if not used) elements
03181   */
03182   used_count= elements;
03183   collation= 0;
03184 }
03185 
03186 in_row::~in_row()
03187 {
03188   if (base)
03189     delete [] (cmp_item_row*) base;
03190 }
03191 
03192 unsigned char *in_row::get_value(Item *item)
03193 {
03194   tmp.store_value(item);
03195   if (item->is_null())
03196     return 0;
03197   return (unsigned char *)&tmp;
03198 }
03199 
03200 void in_row::set(uint32_t pos, Item *item)
03201 {
03202   ((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
03203   return;
03204 }
03205 
03206 in_int64_t::in_int64_t(uint32_t elements) :
03207   in_vector(elements, sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
03208 {}
03209 
03210 void in_int64_t::set(uint32_t pos,Item *item)
03211 {
03212   struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
03213 
03214   buff->val= item->val_int();
03215   buff->unsigned_flag= item->unsigned_flag;
03216 }
03217 
03218 unsigned char *in_int64_t::get_value(Item *item)
03219 {
03220   tmp.val= item->val_int();
03221   if (item->null_value)
03222     return 0;
03223   tmp.unsigned_flag= item->unsigned_flag;
03224   return (unsigned char*) &tmp;
03225 }
03226 
03227 in_datetime::in_datetime(Item *warn_item_arg, uint32_t elements) :
03228   in_int64_t(elements),
03229   session(current_session),
03230   warn_item(warn_item_arg),
03231   lval_cache(0)
03232 {}
03233 
03234 void in_datetime::set(uint32_t pos, Item *item)
03235 {
03236   Item **tmp_item= &item;
03237   bool is_null;
03238   struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
03239 
03240   buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
03241   buff->unsigned_flag= 1L;
03242 }
03243 
03244 unsigned char *in_datetime::get_value(Item *item)
03245 {
03246   bool is_null;
03247   Item **tmp_item= lval_cache ? &lval_cache : &item;
03248   tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
03249   if (item->null_value)
03250     return 0;
03251   tmp.unsigned_flag= 1L;
03252   return (unsigned char*) &tmp;
03253 }
03254 
03255 in_double::in_double(uint32_t elements)
03256   :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
03257 {}
03258 
03259 void in_double::set(uint32_t pos,Item *item)
03260 {
03261   ((double*) base)[pos]= item->val_real();
03262 }
03263 
03264 unsigned char *in_double::get_value(Item *item)
03265 {
03266   tmp= item->val_real();
03267   if (item->null_value)
03268     return 0;
03269   return (unsigned char*) &tmp;
03270 }
03271 
03272 
03273 in_decimal::in_decimal(uint32_t elements)
03274   :in_vector(elements, sizeof(type::Decimal),(qsort2_cmp) cmp_decimal, 0)
03275 {}
03276 
03277 
03278 void in_decimal::set(uint32_t pos, Item *item)
03279 {
03280   /* as far as 'item' is constant, we can store reference on type::Decimal */
03281   type::Decimal *dec= ((type::Decimal *)base) + pos;
03282   dec->len= DECIMAL_BUFF_LENGTH;
03283   dec->fix_buffer_pointer();
03284   type::Decimal *res= item->val_decimal(dec);
03285   /* if item->val_decimal() is evaluated to NULL then res == 0 */
03286   if (!item->null_value && res != dec)
03287     class_decimal2decimal(res, dec);
03288 }
03289 
03290 
03291 unsigned char *in_decimal::get_value(Item *item)
03292 {
03293   type::Decimal *result= item->val_decimal(&val);
03294   if (item->null_value)
03295     return 0;
03296   return (unsigned char *)result;
03297 }
03298 
03299 
03300 cmp_item* cmp_item::get_comparator(Item_result type,
03301                                    const CHARSET_INFO * const cs)
03302 {
03303   switch (type) {
03304   case STRING_RESULT:
03305     return new cmp_item_sort_string(cs);
03306 
03307   case INT_RESULT:
03308     return new cmp_item_int;
03309 
03310   case REAL_RESULT:
03311     return new cmp_item_real;
03312 
03313   case ROW_RESULT:
03314     return new cmp_item_row;
03315 
03316   case DECIMAL_RESULT:
03317     return new cmp_item_decimal;
03318   }
03319 
03320   return 0; // to satisfy compiler :)
03321 }
03322 
03323 
03324 cmp_item* cmp_item_sort_string::make_same()
03325 {
03326   return new cmp_item_sort_string_in_static(cmp_charset);
03327 }
03328 
03329 cmp_item* cmp_item_int::make_same()
03330 {
03331   return new cmp_item_int();
03332 }
03333 
03334 cmp_item* cmp_item_real::make_same()
03335 {
03336   return new cmp_item_real();
03337 }
03338 
03339 cmp_item* cmp_item_row::make_same()
03340 {
03341   return new cmp_item_row();
03342 }
03343 
03344 
03345 cmp_item_row::~cmp_item_row()
03346 {
03347   if (comparators)
03348   {
03349     for (uint32_t i= 0; i < n; i++)
03350     {
03351       if (comparators[i])
03352   delete comparators[i];
03353     }
03354   }
03355   return;
03356 }
03357 
03358 
03359 void cmp_item_row::alloc_comparators()
03360 {
03361   if (!comparators)
03362     comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
03363 }
03364 
03365 
03366 void cmp_item_row::store_value(Item *item)
03367 {
03368   n= item->cols();
03369   alloc_comparators();
03370   if (comparators)
03371   {
03372     item->bring_value();
03373     item->null_value= 0;
03374     for (uint32_t i=0; i < n; i++)
03375     {
03376       if (!comparators[i])
03377         if (!(comparators[i]=
03378               cmp_item::get_comparator(item->element_index(i)->result_type(),
03379                                        item->element_index(i)->collation.collation)))
03380     break;          // new failed
03381       comparators[i]->store_value(item->element_index(i));
03382       item->null_value|= item->element_index(i)->null_value;
03383     }
03384   }
03385   return;
03386 }
03387 
03388 
03389 void cmp_item_row::store_value_by_template(cmp_item *t, Item *item)
03390 {
03391   cmp_item_row *tmpl= (cmp_item_row*) t;
03392   if (tmpl->n != item->cols())
03393   {
03394     my_error(ER_OPERAND_COLUMNS, MYF(0), tmpl->n);
03395     return;
03396   }
03397   n= tmpl->n;
03398   if ((comparators= (cmp_item **) memory::sql_alloc(sizeof(cmp_item *)*n)))
03399   {
03400     item->bring_value();
03401     item->null_value= 0;
03402     for (uint32_t i=0; i < n; i++)
03403     {
03404       if (!(comparators[i]= tmpl->comparators[i]->make_same()))
03405   break;          // new failed
03406       comparators[i]->store_value_by_template(tmpl->comparators[i],
03407                 item->element_index(i));
03408       item->null_value|= item->element_index(i)->null_value;
03409     }
03410   }
03411 }
03412 
03413 
03414 int cmp_item_row::cmp(Item *arg)
03415 {
03416   arg->null_value= 0;
03417   if (arg->cols() != n)
03418   {
03419     my_error(ER_OPERAND_COLUMNS, MYF(0), n);
03420     return 1;
03421   }
03422   bool was_null= 0;
03423   arg->bring_value();
03424   for (uint32_t i=0; i < n; i++)
03425   {
03426     if (comparators[i]->cmp(arg->element_index(i)))
03427     {
03428       if (!arg->element_index(i)->null_value)
03429   return 1;
03430       was_null= 1;
03431     }
03432   }
03433   return (arg->null_value= was_null);
03434 }
03435 
03436 
03437 int cmp_item_row::compare(cmp_item *c)
03438 {
03439   cmp_item_row *l_cmp= (cmp_item_row *) c;
03440   for (uint32_t i=0; i < n; i++)
03441   {
03442     int res;
03443     if ((res= comparators[i]->compare(l_cmp->comparators[i])))
03444       return res;
03445   }
03446   return 0;
03447 }
03448 
03449 
03450 void cmp_item_decimal::store_value(Item *item)
03451 {
03452   type::Decimal *val= item->val_decimal(&value);
03453   /* val may be zero if item is nnull */
03454   if (val && val != &value)
03455     class_decimal2decimal(val, &value);
03456 }
03457 
03458 
03459 int cmp_item_decimal::cmp(Item *arg)
03460 {
03461   type::Decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
03462   if (arg->null_value)
03463     return 1;
03464   return class_decimal_cmp(&value, tmp);
03465 }
03466 
03467 
03468 int cmp_item_decimal::compare(cmp_item *arg)
03469 {
03470   cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
03471   return class_decimal_cmp(&value, &l_cmp->value);
03472 }
03473 
03474 
03475 cmp_item* cmp_item_decimal::make_same()
03476 {
03477   return new cmp_item_decimal();
03478 }
03479 
03480 
03481 void cmp_item_datetime::store_value(Item *item)
03482 {
03483   bool is_null;
03484   Item **tmp_item= lval_cache ? &lval_cache : &item;
03485   value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
03486 }
03487 
03488 
03489 int cmp_item_datetime::cmp(Item *arg)
03490 {
03491   bool is_null;
03492   Item **tmp_item= &arg;
03493   return value !=
03494     get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
03495 }
03496 
03497 
03498 int cmp_item_datetime::compare(cmp_item *ci)
03499 {
03500   cmp_item_datetime *l_cmp= (cmp_item_datetime *)ci;
03501   return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
03502 }
03503 
03504 
03505 cmp_item *cmp_item_datetime::make_same()
03506 {
03507   return new cmp_item_datetime(warn_item);
03508 }
03509 
03510 
03511 bool Item_func_in::nulls_in_row()
03512 {
03513   Item **arg,**arg_end;
03514   for (arg= args+1, arg_end= args+arg_count; arg != arg_end ; arg++)
03515   {
03516     if ((*arg)->null_inside())
03517       return 1;
03518   }
03519   return 0;
03520 }
03521 
03522 
03551 bool
03552 Item_func_in::fix_fields(Session *session, Item **ref)
03553 {
03554   Item **arg, **arg_end;
03555 
03556   if (Item_func_opt_neg::fix_fields(session, ref))
03557     return 1;
03558 
03559   /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
03560   if (pred_level && negated)
03561     return 0;
03562 
03563   /* not_null_tables_cache = union(T1(e),intersection(T1(ei))) */
03564   not_null_tables_cache= ~(table_map) 0;
03565   for (arg= args + 1, arg_end= args + arg_count; arg != arg_end; arg++)
03566     not_null_tables_cache&= (*arg)->not_null_tables();
03567   not_null_tables_cache|= (*args)->not_null_tables();
03568   return 0;
03569 }
03570 
03571 
03572 static int srtcmp_in(const CHARSET_INFO * const cs, const String *x,const String *y)
03573 {
03574   return cs->coll->strnncollsp(cs,
03575                                (unsigned char *) x->ptr(),x->length(),
03576                                (unsigned char *) y->ptr(),y->length(), 0);
03577 }
03578 
03579 
03580 void Item_func_in::fix_length_and_dec()
03581 {
03582   Item **arg, **arg_end;
03583   bool const_itm= 1;
03584   bool datetime_found= false;
03585   /* true <=> arguments values will be compared as DATETIMEs. */
03586   bool compare_as_datetime= false;
03587   Item *date_arg= 0;
03588   uint32_t found_types= 0;
03589   uint32_t type_cnt= 0;
03590   Item_result cmp_type= STRING_RESULT;
03591   left_result_type= args[0]->result_type();
03592   if (!(found_types= collect_cmp_types(args, arg_count, true)))
03593     return;
03594 
03595   for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
03596   {
03597     if (!arg[0]->const_item())
03598     {
03599       const_itm= 0;
03600       break;
03601     }
03602   }
03603   for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
03604   {
03605     if (found_types & 1 << i)
03606     {
03607       (type_cnt)++;
03608       cmp_type= (Item_result) i;
03609     }
03610   }
03611 
03612   if (type_cnt == 1)
03613   {
03614     if (cmp_type == STRING_RESULT &&
03615         agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
03616       return;
03617     arg_types_compatible= true;
03618   }
03619   if (type_cnt == 1)
03620   {
03621     /*
03622       When comparing rows create the row comparator object beforehand to ease
03623       the DATETIME comparison detection procedure.
03624     */
03625     if (cmp_type == ROW_RESULT)
03626     {
03627       cmp_item_row *cmp= 0;
03628       if (const_itm && !nulls_in_row())
03629       {
03630         array= new in_row(arg_count-1, 0);
03631         cmp= &((in_row*)array)->tmp;
03632       }
03633       else
03634       {
03635         if (!(cmp= new cmp_item_row))
03636           return;
03637         cmp_items[ROW_RESULT]= cmp;
03638       }
03639       cmp->n= args[0]->cols();
03640       cmp->alloc_comparators();
03641     }
03642     /* All DATE/DATETIME fields/functions has the STRING result type. */
03643     if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
03644     {
03645       uint32_t col, num_cols= args[0]->cols();
03646 
03647       for (col= 0; col < num_cols; col++)
03648       {
03649         bool skip_column= false;
03650         /*
03651           Check that all items to be compared has the STRING result type and at
03652           least one of them is a DATE/DATETIME item.
03653         */
03654         for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++)
03655         {
03656           Item *itm= ((cmp_type == STRING_RESULT) ? arg[0] :
03657                       arg[0]->element_index(col));
03658           if (itm->result_type() != STRING_RESULT)
03659           {
03660             skip_column= true;
03661             break;
03662           }
03663           else if (itm->is_datetime())
03664           {
03665             datetime_found= true;
03666             /*
03667               Internally all DATE/DATETIME values are converted to the DATETIME
03668               type. So try to find a DATETIME item to issue correct warnings.
03669             */
03670             if (!date_arg)
03671               date_arg= itm;
03672             else if (itm->field_type() == DRIZZLE_TYPE_DATETIME)
03673             {
03674               date_arg= itm;
03675               /* All arguments are already checked to have the STRING result. */
03676               if (cmp_type == STRING_RESULT)
03677                 break;
03678             }
03679           }
03680         }
03681         if (skip_column)
03682           continue;
03683         if (datetime_found)
03684         {
03685           if (cmp_type == ROW_RESULT)
03686           {
03687             cmp_item **cmp= 0;
03688             if (array)
03689               cmp= ((in_row*)array)->tmp.comparators + col;
03690             else
03691               cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col;
03692             *cmp= new cmp_item_datetime(date_arg);
03693             /* Reset variables for the next column. */
03694             date_arg= 0;
03695             datetime_found= false;
03696           }
03697           else
03698             compare_as_datetime= true;
03699         }
03700       }
03701     }
03702   }
03703   /*
03704     Row item with NULLs inside can return NULL or false =>
03705     they can't be processed as static
03706   */
03707   if (type_cnt == 1 && const_itm && !nulls_in_row())
03708   {
03709     if (compare_as_datetime)
03710     {
03711       array= new in_datetime(date_arg, arg_count - 1);
03712     }
03713     else
03714     {
03715       /*
03716         IN must compare INT columns and constants as int values (the same
03717         way as equality does).
03718         So we must check here if the column on the left and all the constant
03719         values on the right can be compared as integers and adjust the
03720         comparison type accordingly.
03721       */
03722       if (args[0]->real_item()->type() == FIELD_ITEM &&
03723           cmp_type != INT_RESULT)
03724       {
03725         Item_field *field_item= (Item_field*) (args[0]->real_item());
03726         if (field_item->field->can_be_compared_as_int64_t())
03727         {
03728           bool all_converted= true;
03729           for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
03730           {
03731             if (!convert_constant_item (&getSession(), field_item, &arg[0]))
03732               all_converted= false;
03733           }
03734           if (all_converted)
03735             cmp_type= INT_RESULT;
03736         }
03737       }
03738 
03739       switch (cmp_type) {
03740       case STRING_RESULT:
03741         array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
03742                             cmp_collation.collation);
03743         break;
03744 
03745       case INT_RESULT:
03746         array= new in_int64_t(arg_count-1);
03747         break;
03748 
03749       case REAL_RESULT:
03750         array= new in_double(arg_count-1);
03751         break;
03752 
03753       case ROW_RESULT:
03754         /*
03755           The row comparator was created at the beginning but only DATETIME
03756           items comparators were initialized. Call store_value() to setup
03757           others.
03758         */
03759         ((in_row*)array)->tmp.store_value(args[0]);
03760         break;
03761 
03762       case DECIMAL_RESULT:
03763         array= new in_decimal(arg_count - 1);
03764         break;
03765       }
03766     }
03767 
03768     if (array && !(getSession().is_fatal_error))    // If not EOM
03769     {
03770       uint32_t j=0;
03771       for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
03772       {
03773         if (!args[arg_num]->null_value)     // Skip NULL values
03774         {
03775           array->set(j,args[arg_num]);
03776           j++;
03777         }
03778         else
03779           have_null= 1;
03780       }
03781       if ((array->used_count= j))
03782         array->sort();
03783     }
03784   }
03785   else
03786   {
03787     if (compare_as_datetime)
03788       cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
03789     else
03790     {
03791       for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
03792       {
03793         if (found_types & (1 << i) && !cmp_items[i])
03794         {
03795           if ((Item_result)i == STRING_RESULT &&
03796               agg_arg_charsets(cmp_collation, args, arg_count,
03797                                MY_COLL_CMP_CONV, 1))
03798             return;
03799           if (!cmp_items[i] && !(cmp_items[i]=
03800               cmp_item::get_comparator((Item_result)i,
03801                                        cmp_collation.collation)))
03802             return;
03803         }
03804       }
03805     }
03806   }
03807   max_length= 1;
03808 }
03809 
03810 
03811 void Item_func_in::print(String *str)
03812 {
03813   str->append('(');
03814   args[0]->print(str);
03815   if (negated)
03816     str->append(STRING_WITH_LEN(" not"));
03817   str->append(STRING_WITH_LEN(" in ("));
03818   print_args(str, 1);
03819   str->append(STRING_WITH_LEN("))"));
03820 }
03821 
03822 
03823 /*
03824   Evaluate the function and return its value.
03825 
03826   SYNOPSIS
03827     val_int()
03828 
03829   DESCRIPTION
03830     Evaluate the function and return its value.
03831 
03832   IMPLEMENTATION
03833     If the array object is defined then the value of the function is
03834     calculated by means of this array.
03835     Otherwise several cmp_item objects are used in order to do correct
03836     comparison of left expression and an expression from the values list.
03837     One cmp_item object correspond to one used comparison type. Left
03838     expression can be evaluated up to number of different used comparison
03839     types. A bit mapped variable value_added_map is used to check whether
03840     the left expression already was evaluated for a particular result type.
03841     Result types are mapped to it according to their integer values i.e.
03842     STRING_RESULT is mapped to bit 0, REAL_RESULT to bit 1, so on.
03843 
03844   RETURN
03845     Value of the function
03846 */
03847 
03848 int64_t Item_func_in::val_int()
03849 {
03850   cmp_item *in_item;
03851   assert(fixed == 1);
03852   uint32_t value_added_map= 0;
03853   if (array)
03854   {
03855     int tmp=array->find(args[0]);
03856     null_value=args[0]->null_value || (!tmp && have_null);
03857     return (int64_t) (!null_value && tmp != negated);
03858   }
03859 
03860   for (uint32_t i= 1 ; i < arg_count ; i++)
03861   {
03862     Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
03863     in_item= cmp_items[(uint32_t)cmp_type];
03864     assert(in_item);
03865     if (!(value_added_map & (1 << (uint32_t)cmp_type)))
03866     {
03867       in_item->store_value(args[0]);
03868       if ((null_value=args[0]->null_value))
03869         return 0;
03870       have_null= 0;
03871       value_added_map|= 1 << (uint32_t)cmp_type;
03872     }
03873     if (!in_item->cmp(args[i]) && !args[i]->null_value)
03874       return (int64_t) (!negated);
03875     have_null|= args[i]->null_value;
03876   }
03877 
03878   null_value= have_null;
03879   return (int64_t) (!null_value && negated);
03880 }
03881 
03882 
03883 Item_cond::Item_cond(Session *session, Item_cond *item)
03884   :item::function::Boolean(session, item),
03885    abort_on_null(item->abort_on_null),
03886    and_tables_cache(item->and_tables_cache)
03887 {
03888   /*
03889     item->list will be copied by copy_andor_arguments() call
03890   */
03891 }
03892 
03893 
03894 void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
03895 {
03896   List<Item>::iterator li(item->list.begin());
03897   while (Item *it= li++)
03898     list.push_back(it->copy_andor_structure(session));
03899 }
03900 
03901 
03902 bool
03903 Item_cond::fix_fields(Session *session, Item **)
03904 {
03905   assert(fixed == 0);
03906   List<Item>::iterator li(list.begin());
03907   Item *item;
03908   void *orig_session_marker= session->session_marker;
03909   unsigned char buff[sizeof(char*)];      // Max local vars in function
03910   not_null_tables_cache= used_tables_cache= 0;
03911   const_item_cache= true;
03912 
03913   if (functype() == COND_OR_FUNC)
03914     session->session_marker= 0;
03915   /*
03916     and_table_cache is the value that Item_cond_or() returns for
03917     not_null_tables()
03918   */
03919   and_tables_cache= ~(table_map) 0;
03920 
03921   if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
03922     return true;        // Fatal error flag is set!
03923   /*
03924     The following optimization reduces the depth of an AND-OR tree.
03925     E.g. a WHERE clause like
03926       F1 AND (F2 AND (F2 AND F4))
03927     is parsed into a tree with the same nested structure as defined
03928     by braces. This optimization will transform such tree into
03929       AND (F1, F2, F3, F4).
03930     Trees of OR items are flattened as well:
03931       ((F1 OR F2) OR (F3 OR F4))   =>   OR (F1, F2, F3, F4)
03932     Items for removed AND/OR levels will dangle until the death of the
03933     entire statement.
03934     The optimization is currently prepared statements and stored procedures
03935     friendly as it doesn't allocate any memory and its effects are durable
03936     (i.e. do not depend on PS/SP arguments).
03937   */
03938   while ((item=li++))
03939   {
03940     table_map tmp_table_map;
03941     while (item->type() == Item::COND_ITEM &&
03942      ((Item_cond*) item)->functype() == functype() &&
03943            !((Item_cond*) item)->list.is_empty())
03944     {           // Identical function
03945       li.replace(((Item_cond*) item)->list);
03946       ((Item_cond*) item)->list.clear();
03947       item= &*li;       // new current item
03948     }
03949     if (abort_on_null)
03950       item->top_level_item();
03951 
03952     // item can be substituted in fix_fields
03953     if ((!item->fixed &&
03954    item->fix_fields(session, li.ref())) ||
03955   (item= &*li)->check_cols(1))
03956       return true;
03957     used_tables_cache|=     item->used_tables();
03958     if (item->const_item())
03959       and_tables_cache= (table_map) 0;
03960     else
03961     {
03962       tmp_table_map= item->not_null_tables();
03963       not_null_tables_cache|= tmp_table_map;
03964       and_tables_cache&= tmp_table_map;
03965       const_item_cache= false;
03966     }
03967     with_sum_func=      with_sum_func || item->with_sum_func;
03968     with_subselect|=        item->with_subselect;
03969     if (item->maybe_null)
03970       maybe_null=1;
03971   }
03972   session->lex().current_select->cond_count+= list.size();
03973   session->session_marker= orig_session_marker;
03974   fix_length_and_dec();
03975   fixed= 1;
03976   return false;
03977 }
03978 
03979 
03980 void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
03981 {
03982   List<Item>::iterator li(list.begin());
03983   Item *item;
03984 
03985   used_tables_cache=0;
03986   const_item_cache= true;
03987 
03988   and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
03989   not_null_tables_cache= 0;
03990 
03991   while ((item=li++))
03992   {
03993     table_map tmp_table_map;
03994     item->fix_after_pullout(new_parent, li.ref());
03995     item= &*li;
03996     used_tables_cache|= item->used_tables();
03997     const_item_cache&= item->const_item();
03998 
03999     if (item->const_item())
04000       and_tables_cache= (table_map) 0;
04001     else
04002     {
04003       tmp_table_map= item->not_null_tables();
04004       not_null_tables_cache|= tmp_table_map;
04005       and_tables_cache&= tmp_table_map;
04006       const_item_cache= false;
04007     }
04008   }
04009 }
04010 
04011 
04012 bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
04013 {
04014   List<Item>::iterator li(list.begin());
04015   Item *item;
04016   while ((item= li++))
04017     if (item->walk(processor, walk_subquery, arg))
04018       return 1;
04019   return Item_func::walk(processor, walk_subquery, arg);
04020 }
04021 
04022 
04041 Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
04042 {
04043   List<Item>::iterator li(list.begin());
04044   Item *item;
04045   while ((item= li++))
04046   {
04047     Item *new_item= item->transform(transformer, arg);
04048     if (!new_item)
04049       return 0;
04050     *li.ref()= new_item;
04051   }
04052   return Item_func::transform(transformer, arg);
04053 }
04054 
04055 
04080 Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
04081                          Item_transformer transformer, unsigned char *arg_t)
04082 {
04083   if (!(this->*analyzer)(arg_p))
04084     return 0;
04085 
04086   List<Item>::iterator li(list.begin());
04087   Item *item;
04088   while ((item= li++))
04089   {
04090     /*
04091       The same parameter value of arg_p must be passed
04092       to analyze any argument of the condition formula.
04093     */
04094     unsigned char *arg_v= *arg_p;
04095     Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
04096     if (new_item && new_item != item)
04097       li.replace(new_item);
04098   }
04099   return Item_func::transform(transformer, arg_t);
04100 }
04101 
04102 void Item_cond::traverse_cond(Cond_traverser traverser,
04103                               void *arg, traverse_order order)
04104 {
04105   List<Item>::iterator li(list.begin());
04106   Item *item;
04107 
04108   switch (order) {
04109   case (T_PREFIX):
04110     (*traverser)(this, arg);
04111     while ((item= li++))
04112     {
04113       item->traverse_cond(traverser, arg, order);
04114     }
04115     (*traverser)(NULL, arg);
04116     break;
04117   case (T_POSTFIX):
04118     while ((item= li++))
04119     {
04120       item->traverse_cond(traverser, arg, order);
04121     }
04122     (*traverser)(this, arg);
04123   }
04124 }
04125 
04143 void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields)
04144 {
04145   List<Item>::iterator li(list.begin());
04146   Item *item;
04147   while ((item= li++))
04148     item->split_sum_func(session, ref_pointer_array, fields, li.ref(), true);
04149 }
04150 
04151 
04152 table_map
04153 Item_cond::used_tables() const
04154 {           // This caches used_tables
04155   return used_tables_cache;
04156 }
04157 
04158 
04159 void Item_cond::update_used_tables()
04160 {
04161   List<Item>::iterator li(list.begin());
04162   Item *item;
04163 
04164   used_tables_cache=0;
04165   const_item_cache= true;
04166   while ((item=li++))
04167   {
04168     item->update_used_tables();
04169     used_tables_cache|= item->used_tables();
04170     const_item_cache&= item->const_item();
04171   }
04172 }
04173 
04174 
04175 void Item_cond::print(String *str)
04176 {
04177   str->append('(');
04178   List<Item>::iterator li(list.begin());
04179   Item *item;
04180   if ((item=li++))
04181     item->print(str);
04182   while ((item=li++))
04183   {
04184     str->append(' ');
04185     str->append(func_name());
04186     str->append(' ');
04187     item->print(str);
04188   }
04189   str->append(')');
04190 }
04191 
04192 
04193 void Item_cond::neg_arguments(Session *session)
04194 {
04195   List<Item>::iterator li(list.begin());
04196   Item *item;
04197   while ((item= li++))    /* Apply not transformation to the arguments */
04198   {
04199     Item *new_item= item->neg_transformer(session);
04200     if (!new_item)
04201     {
04202       if (!(new_item= new Item_func_not(item)))
04203   return;         // Fatal OEM error
04204     }
04205     li.replace(new_item);
04206   }
04207 }
04208 
04209 
04230 int64_t Item_cond_and::val_int()
04231 {
04232   assert(fixed == 1);
04233   List<Item>::iterator li(list.begin());
04234   Item *item;
04235   null_value= 0;
04236   while ((item=li++))
04237   {
04238     if (!item->val_bool())
04239     {
04240       if (abort_on_null || !(null_value= item->null_value))
04241   return 0;       // return false
04242     }
04243   }
04244   return null_value ? 0 : 1;
04245 }
04246 
04247 
04248 int64_t Item_cond_or::val_int()
04249 {
04250   assert(fixed == 1);
04251   List<Item>::iterator li(list.begin());
04252   Item *item;
04253   null_value=0;
04254   while ((item=li++))
04255   {
04256     if (item->val_bool())
04257     {
04258       null_value=0;
04259       return 1;
04260     }
04261     if (item->null_value)
04262       null_value=1;
04263   }
04264   return 0;
04265 }
04266 
04287 Item *and_expressions(Item *a, Item *b, Item **org_item)
04288 {
04289   if (!a)
04290     return (*org_item= (Item*) b);
04291   if (a == *org_item)
04292   {
04293     Item_cond *res;
04294     if ((res= new Item_cond_and(a, (Item*) b)))
04295     {
04296       res->used_tables_cache= a->used_tables() | b->used_tables();
04297       res->not_null_tables_cache= a->not_null_tables() | b->not_null_tables();
04298     }
04299     return res;
04300   }
04301   if (((Item_cond_and*) a)->add((Item*) b))
04302     return 0;
04303   ((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
04304   ((Item_cond_and*) a)->not_null_tables_cache|= b->not_null_tables();
04305   return a;
04306 }
04307 
04308 
04309 int64_t Item_func_isnull::val_int()
04310 {
04311   assert(fixed == 1);
04312   /*
04313     Handle optimization if the argument can't be null
04314     This has to be here because of the test in update_used_tables().
04315   */
04316   if (!used_tables_cache && !with_subselect)
04317     return cached_value;
04318   return args[0]->is_null() ? 1: 0;
04319 }
04320 
04321 int64_t Item_is_not_null_test::val_int()
04322 {
04323   assert(fixed == 1);
04324   if (!used_tables_cache && !with_subselect)
04325   {
04326     owner->was_null|= (!cached_value);
04327     return(cached_value);
04328   }
04329   if (args[0]->is_null())
04330   {
04331     owner->was_null|= 1;
04332     return(0);
04333   }
04334   else
04335     return(1);
04336 }
04337 
04341 void Item_is_not_null_test::update_used_tables()
04342 {
04343   if (!args[0]->maybe_null)
04344   {
04345     used_tables_cache= 0;     /* is always true */
04346     cached_value= (int64_t) 1;
04347   }
04348   else
04349   {
04350     args[0]->update_used_tables();
04351     if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
04352     {
04353       /* Remember if the value is always NULL or never NULL */
04354       cached_value= (int64_t) !args[0]->is_null();
04355     }
04356   }
04357 }
04358 
04359 
04360 int64_t Item_func_isnotnull::val_int()
04361 {
04362   assert(fixed == 1);
04363   return args[0]->is_null() ? 0 : 1;
04364 }
04365 
04366 
04367 void Item_func_isnotnull::print(String *str)
04368 {
04369   str->append('(');
04370   args[0]->print(str);
04371   str->append(STRING_WITH_LEN(" is not null)"));
04372 }
04373 
04374 
04375 int64_t Item_func_like::val_int()
04376 {
04377   assert(fixed == 1);
04378   String* res = args[0]->val_str(&tmp_value1);
04379   if (args[0]->null_value)
04380   {
04381     null_value=1;
04382     return 0;
04383   }
04384   String* res2 = args[1]->val_str(&tmp_value2);
04385   if (args[1]->null_value)
04386   {
04387     null_value=1;
04388     return 0;
04389   }
04390   null_value=0;
04391   if (canDoTurboBM)
04392     return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
04393   return my_wildcmp(cmp.cmp_collation.collation,
04394         res->ptr(),res->ptr()+res->length(),
04395         res2->ptr(),res2->ptr()+res2->length(),
04396         make_escape_code(cmp.cmp_collation.collation, escape),
04397                     internal::wild_one,internal::wild_many) ? 0 : 1;
04398 }
04399 
04400 
04405 Item_func::optimize_type Item_func_like::select_optimize() const
04406 {
04407   if (args[1]->const_item())
04408   {
04409     String* res2= args[1]->val_str((String *)&tmp_value2);
04410 
04411     if (!res2)
04412       return OPTIMIZE_NONE;
04413 
04414     if (*res2->ptr() != internal::wild_many)
04415     {
04416       if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != internal::wild_one)
04417   return OPTIMIZE_OP;
04418     }
04419   }
04420   return OPTIMIZE_NONE;
04421 }
04422 
04423 
04424 bool Item_func_like::fix_fields(Session *session, Item **ref)
04425 {
04426   assert(fixed == 0);
04427   if (Item_bool_func2::fix_fields(session, ref) ||
04428       escape_item->fix_fields(session, &escape_item))
04429     return true;
04430 
04431   if (!escape_item->const_during_execution())
04432   {
04433     my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
04434     return true;
04435   }
04436 
04437   if (escape_item->const_item())
04438   {
04439     
04440     /* If we are on execution stage */
04441     String *escape_str= escape_item->val_str(&tmp_value1);
04442     if (escape_str)
04443     {
04444       escape= (char *)memory::sql_alloc(escape_str->length());
04445       strcpy(escape, escape_str->ptr()); 
04446     }
04447     else
04448     {
04449       escape= (char *)memory::sql_alloc(1);
04450       strcpy(escape, "\\");
04451     } 
04452    
04453     /*
04454       We could also do boyer-more for non-const items, but as we would have to
04455       recompute the tables for each row it's not worth it.
04456     */
04457     if (args[1]->const_item() && !use_strnxfrm(collation.collation))
04458     {
04459       String* res2 = args[1]->val_str(&tmp_value2);
04460       if (!res2)
04461         return false;       // Null argument
04462 
04463       const size_t len   = res2->length();
04464       const char*  first = res2->ptr();
04465       const char*  last  = first + len - 1;
04466       /*
04467         len must be > 2 ('%pattern%')
04468         heuristic: only do TurboBM for pattern_len > 2
04469       */
04470 
04471       if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
04472           *first == internal::wild_many &&
04473           *last  == internal::wild_many)
04474       {
04475         const char* tmp = first + 1;
04476         for (; *tmp != internal::wild_many && *tmp != internal::wild_one; tmp++)
04477         {
04478           if (escape == tmp)
04479             break;
04480         }
04481   
04482         canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
04483       }
04484       if (canDoTurboBM)
04485       {
04486         pattern     = first + 1;
04487         pattern_len = (int) len - 2;
04488         int *suff = (int*) session->getMemRoot()->allocate((int) (sizeof(int)*
04489                                                                   ((pattern_len + 1)*2+
04490                                                                    alphabet_size)));
04491         bmGs      = suff + pattern_len + 1;
04492         bmBc      = bmGs + pattern_len + 1;
04493         turboBM_compute_good_suffix_shifts(suff);
04494         turboBM_compute_bad_character_shifts();
04495       }
04496     }
04497   }
04498   return false;
04499 }
04500 
04501 void Item_func_like::cleanup()
04502 {
04503   canDoTurboBM= false;
04504   Item_bool_func2::cleanup();
04505 }
04506 
04507 static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
04508 {
04509 #ifdef LIKE_CMP_TOUPPER
04510   return cs->toupper(a);
04511 #else
04512   return cs->sort_order[a];
04513 #endif
04514 }
04515 
04520 void Item_func_like::turboBM_compute_suffixes(int *suff)
04521 {
04522   const int   plm1 = pattern_len - 1;
04523   int            f = 0;
04524   int            g = plm1;
04525   int *const splm1 = suff + plm1;
04526   const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
04527 
04528   *splm1 = pattern_len;
04529 
04530   if (!cs->sort_order)
04531   {
04532     for (int i = pattern_len - 2; i >= 0; i--)
04533     {
04534       int tmp = *(splm1 + i - f);
04535       if (g < i && tmp < i - g)
04536         suff[i] = tmp;
04537       else
04538       {
04539         if (i < g)
04540           g = i;
04541         f = i;
04542         while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
04543           g--;
04544         suff[i] = f - g;
04545       }
04546     }
04547   }
04548   else
04549   {
04550     for (int i = pattern_len - 2; 0 <= i; --i)
04551     {
04552       int tmp = *(splm1 + i - f);
04553       if (g < i && tmp < i - g)
04554         suff[i] = tmp;
04555       else
04556       {
04557         if (i < g)
04558           g = i;
04559         f = i;
04560         while (g >= 0 &&
04561                likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
04562           g--;
04563         suff[i] = f - g;
04564       }
04565     }
04566   }
04567 }
04568 
04569 
04574 void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
04575 {
04576   turboBM_compute_suffixes(suff);
04577 
04578   int *end = bmGs + pattern_len;
04579   int *k;
04580   for (k = bmGs; k < end; k++)
04581     *k = pattern_len;
04582 
04583   int tmp;
04584   int i;
04585   int j          = 0;
04586   const int plm1 = pattern_len - 1;
04587   for (i = plm1; i > -1; i--)
04588   {
04589     if (suff[i] == i + 1)
04590     {
04591       for (tmp = plm1 - i; j < tmp; j++)
04592       {
04593   int *tmp2 = bmGs + j;
04594   if (*tmp2 == pattern_len)
04595     *tmp2 = tmp;
04596       }
04597     }
04598   }
04599 
04600   int *tmp2;
04601   for (tmp = plm1 - i; j < tmp; j++)
04602   {
04603     tmp2 = bmGs + j;
04604     if (*tmp2 == pattern_len)
04605       *tmp2 = tmp;
04606   }
04607 
04608   tmp2 = bmGs + plm1;
04609   for (i = 0; i <= pattern_len - 2; i++)
04610     *(tmp2 - suff[i]) = plm1 - i;
04611 }
04612 
04613 
04618 void Item_func_like::turboBM_compute_bad_character_shifts()
04619 {
04620   int *i;
04621   int *end = bmBc + alphabet_size;
04622   int j;
04623   const int plm1 = pattern_len - 1;
04624   const CHARSET_INFO *const cs= cmp.cmp_collation.collation;
04625 
04626   for (i = bmBc; i < end; i++)
04627     *i = pattern_len;
04628 
04629   if (!cs->sort_order)
04630   {
04631     for (j = 0; j < plm1; j++)
04632       bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
04633   }
04634   else
04635   {
04636     for (j = 0; j < plm1; j++)
04637       bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
04638   }
04639 }
04640 
04641 
04649 bool Item_func_like::turboBM_matches(const char* text, int text_len) const
04650 {
04651   int bcShift;
04652   int turboShift;
04653   int shift = pattern_len;
04654   int j     = 0;
04655   int u     = 0;
04656   const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
04657 
04658   const int plm1=  pattern_len - 1;
04659   const int tlmpl= text_len - pattern_len;
04660 
04661   /* Searching */
04662   if (!cs->sort_order)
04663   {
04664     while (j <= tlmpl)
04665     {
04666       int i= plm1;
04667       while (i >= 0 && pattern[i] == text[i + j])
04668       {
04669   i--;
04670   if (i == plm1 - shift)
04671     i-= u;
04672       }
04673       if (i < 0)
04674   return 1;
04675 
04676       const int v = plm1 - i;
04677       turboShift = u - v;
04678       bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
04679       shift      = (turboShift > bcShift) ? turboShift : bcShift;
04680       shift      = (shift > bmGs[i]) ? shift : bmGs[i];
04681       if (shift == bmGs[i])
04682   u = (pattern_len - shift < v) ? pattern_len - shift : v;
04683       else
04684       {
04685         if (turboShift < bcShift)
04686           shift= max(shift, u + 1);
04687         u = 0;
04688       }
04689       j+= shift;
04690     }
04691     return 0;
04692   }
04693   else
04694   {
04695     while (j <= tlmpl)
04696     {
04697       int i = plm1;
04698       while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
04699       {
04700         i--;
04701         if (i == plm1 - shift)
04702           i-= u;
04703       }
04704 
04705       if (i < 0)
04706         return 1;
04707 
04708       const int v= plm1 - i;
04709       turboShift= u - v;
04710       bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
04711       shift= (turboShift > bcShift) ? turboShift : bcShift;
04712       shift= max(shift, bmGs[i]);
04713       
04714       if (shift == bmGs[i])
04715         u= (pattern_len - shift < v) ? pattern_len - shift : v;
04716       else
04717       {
04718         if (turboShift < bcShift)
04719           shift= max(shift, u + 1);
04720         u = 0;
04721       }
04722 
04723       j+= shift;
04724     }
04725     return 0;
04726   }
04727 }
04728 
04729 
04746 int64_t Item_cond_xor::val_int()
04747 {
04748   assert(fixed == 1);
04749   List<Item>::iterator li(list.begin());
04750   Item *item;
04751   int result=0;
04752   null_value=0;
04753   while ((item=li++))
04754   {
04755     result^= (item->val_int() != 0);
04756     if (item->null_value)
04757     {
04758       null_value=1;
04759       return 0;
04760     }
04761   }
04762   return (int64_t) result;
04763 }
04764 
04791 Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
04792 {
04793   return args[0];
04794 }
04795 
04796 
04797 Item *Item_bool_rowready_func2::neg_transformer(Session *)
04798 {
04799   Item *item= negated_item();
04800   return item;
04801 }
04802 
04803 
04807 Item *Item_func_isnull::neg_transformer(Session *)
04808 {
04809   Item *item= new Item_func_isnotnull(args[0]);
04810   return item;
04811 }
04812 
04813 
04817 Item *Item_func_isnotnull::neg_transformer(Session *)
04818 {
04819   Item *item= new Item_func_isnull(args[0]);
04820   return item;
04821 }
04822 
04823 
04824 Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
04825           /* NOT a OR NOT b OR ... */
04826 {
04827   neg_arguments(session);
04828   Item *item= new Item_cond_or(list);
04829   return item;
04830 }
04831 
04832 
04833 Item *Item_cond_or::neg_transformer(Session *session) /* NOT(a OR b OR ...)  -> */
04834           /* NOT a AND NOT b AND ... */
04835 {
04836   neg_arguments(session);
04837   Item *item= new Item_cond_and(list);
04838   return item;
04839 }
04840 
04841 
04842 Item *Item_func_nop_all::neg_transformer(Session *)
04843 {
04844   /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
04845   Item_func_not_all *new_item= new Item_func_not_all(args[0]);
04846   Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
04847   allany->func= allany->func_creator(false);
04848   allany->all= !allany->all;
04849   allany->upper_item= new_item;
04850   return new_item;
04851 }
04852 
04853 Item *Item_func_not_all::neg_transformer(Session *)
04854 {
04855   /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
04856   Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
04857   Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
04858   allany->all= !allany->all;
04859   allany->func= allany->func_creator(true);
04860   allany->upper_item= new_item;
04861   return new_item;
04862 }
04863 
04864 Item *Item_func_eq::negated_item()    /* a = b  ->  a != b */
04865 {
04866   return new Item_func_ne(args[0], args[1]);
04867 }
04868 
04869 
04870 Item *Item_func_ne::negated_item()    /* a != b  ->  a = b */
04871 {
04872   return new Item_func_eq(args[0], args[1]);
04873 }
04874 
04875 
04876 Item *Item_func_lt::negated_item()    /* a < b  ->  a >= b */
04877 {
04878   return new Item_func_ge(args[0], args[1]);
04879 }
04880 
04881 
04882 Item *Item_func_ge::negated_item()    /* a >= b  ->  a < b */
04883 {
04884   return new Item_func_lt(args[0], args[1]);
04885 }
04886 
04887 
04888 Item *Item_func_gt::negated_item()    /* a > b  ->  a <= b */
04889 {
04890   return new Item_func_le(args[0], args[1]);
04891 }
04892 
04893 
04894 Item *Item_func_le::negated_item()    /* a <= b  ->  a > b */
04895 {
04896   return new Item_func_gt(args[0], args[1]);
04897 }
04898 
04902 Item *Item_bool_rowready_func2::negated_item()
04903 {
04904   assert(0);
04905   return 0;
04906 }
04907 
04908 Item_equal::Item_equal(Item_field *f1, Item_field *f2)
04909   : item::function::Boolean(), const_item(0), eval_item(0), cond_false(0)
04910 {
04911   const_item_cache= false;
04912   fields.push_back(f1);
04913   fields.push_back(f2);
04914 }
04915 
04916 Item_equal::Item_equal(Item *c, Item_field *f)
04917   : item::function::Boolean(), eval_item(0), cond_false(0)
04918 {
04919   const_item_cache= false;
04920   fields.push_back(f);
04921   const_item= c;
04922 }
04923 
04924 
04925 Item_equal::Item_equal(Item_equal *item_equal)
04926   : item::function::Boolean(), eval_item(0), cond_false(0)
04927 {
04928   const_item_cache= false;
04929   List<Item_field>::iterator li(item_equal->fields.begin());
04930   Item_field *item;
04931   while ((item= li++))
04932   {
04933     fields.push_back(item);
04934   }
04935   const_item= item_equal->const_item;
04936   cond_false= item_equal->cond_false;
04937 }
04938 
04939 void Item_equal::add(Item *c)
04940 {
04941   if (cond_false)
04942     return;
04943   if (!const_item)
04944   {
04945     const_item= c;
04946     return;
04947   }
04948   Item_func_eq *func= new Item_func_eq(c, const_item);
04949   func->set_cmp_func();
04950   func->quick_fix_field();
04951   if ((cond_false= !func->val_int()))
04952     const_item_cache= true;
04953 }
04954 
04955 void Item_equal::add(Item_field *f)
04956 {
04957   fields.push_back(f);
04958 }
04959 
04960 uint32_t Item_equal::members()
04961 {
04962   return fields.size();
04963 }
04964 
04965 
04979 bool Item_equal::contains(Field *field)
04980 {
04981   List<Item_field>::iterator it(fields.begin());
04982   Item_field *item;
04983   while ((item= it++))
04984   {
04985     if (field->eq(item->field))
04986         return 1;
04987   }
04988   return 0;
04989 }
04990 
04991 
05003 void Item_equal::merge(Item_equal *item)
05004 {
05005   fields.concat(&item->fields);
05006   Item *c= item->const_item;
05007   if (c)
05008   {
05009     /*
05010       The flag cond_false will be set to 1 after this, if
05011       the multiple equality already contains a constant and its
05012       value is  not equal to the value of c.
05013     */
05014     add(c);
05015   }
05016   cond_false|= item->cond_false;
05017 }
05018 
05019 
05037 void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
05038 {
05039   bool swap;
05040   List<Item_field>::iterator it(fields.begin());
05041   do
05042   {
05043     Item_field *item1= it++;
05044     Item_field **ref1= it.ref();
05045     Item_field *item2;
05046 
05047     swap= false;
05048     while ((item2= it++))
05049     {
05050       Item_field **ref2= it.ref();
05051       if (cmp(item1, item2, arg) < 0)
05052       {
05053         Item_field *item= *ref1;
05054         *ref1= *ref2;
05055         *ref2= item;
05056         swap= true;
05057       }
05058       else
05059       {
05060         item1= item2;
05061         ref1= ref2;
05062       }
05063     }
05064     it= fields.begin();
05065   } while (swap);
05066 }
05067 
05068 
05079 void Item_equal::update_const()
05080 {
05081   List<Item_field>::iterator it(fields.begin());
05082   Item *item;
05083   while ((item= it++))
05084   {
05085     if (item->const_item())
05086     {
05087       it.remove();
05088       add(item);
05089     }
05090   }
05091 }
05092 
05093 bool Item_equal::fix_fields(Session *, Item **)
05094 {
05095   List<Item_field>::iterator li(fields.begin());
05096   Item *item;
05097   not_null_tables_cache= used_tables_cache= 0;
05098   const_item_cache= false;
05099   while ((item= li++))
05100   {
05101     table_map tmp_table_map;
05102     used_tables_cache|= item->used_tables();
05103     tmp_table_map= item->not_null_tables();
05104     not_null_tables_cache|= tmp_table_map;
05105     if (item->maybe_null)
05106       maybe_null=1;
05107   }
05108   fix_length_and_dec();
05109   fixed= 1;
05110   return 0;
05111 }
05112 
05113 void Item_equal::update_used_tables()
05114 {
05115   List<Item_field>::iterator li(fields.begin());
05116   Item *item;
05117   not_null_tables_cache= used_tables_cache= 0;
05118   if ((const_item_cache= cond_false))
05119     return;
05120   while ((item=li++))
05121   {
05122     item->update_used_tables();
05123     used_tables_cache|= item->used_tables();
05124     const_item_cache&= item->const_item();
05125   }
05126 }
05127 
05128 int64_t Item_equal::val_int()
05129 {
05130   Item_field *item_field;
05131   if (cond_false)
05132     return 0;
05133   List<Item_field>::iterator it(fields.begin());
05134   Item *item= const_item ? const_item : it++;
05135   eval_item->store_value(item);
05136   if ((null_value= item->null_value))
05137     return 0;
05138   while ((item_field= it++))
05139   {
05140     /* Skip fields of non-const tables. They haven't been read yet */
05141     if (item_field->field->getTable()->const_table)
05142     {
05143       if (eval_item->cmp(item_field) || (null_value= item_field->null_value))
05144         return 0;
05145     }
05146   }
05147   return 1;
05148 }
05149 
05150 void Item_equal::fix_length_and_dec()
05151 {
05152   Item *item= get_first();
05153   eval_item= cmp_item::get_comparator(item->result_type(),
05154                                       item->collation.collation);
05155 }
05156 
05157 bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
05158 {
05159   List<Item_field>::iterator it(fields.begin());
05160   Item *item;
05161   while ((item= it++))
05162   {
05163     if (item->walk(processor, walk_subquery, arg))
05164       return 1;
05165   }
05166   return Item_func::walk(processor, walk_subquery, arg);
05167 }
05168 
05169 Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
05170 {
05171   List<Item_field>::iterator it(fields.begin());
05172   Item *item;
05173   while ((item= it++))
05174   {
05175     Item *new_item= item->transform(transformer, arg);
05176     if (!new_item)
05177       return 0;
05178     *(Item **)it.ref()= new_item;
05179   }
05180   return Item_func::transform(transformer, arg);
05181 }
05182 
05183 void Item_equal::print(String *str)
05184 {
05185   str->append(func_name());
05186   str->append('(');
05187   List<Item_field>::iterator it(fields.begin());
05188   Item *item;
05189   if (const_item)
05190     const_item->print(str);
05191   else
05192   {
05193     item= it++;
05194     item->print(str);
05195   }
05196   while ((item= it++))
05197   {
05198     str->append(',');
05199     str->append(' ');
05200     item->print(str);
05201   }
05202   str->append(')');
05203 }
05204 
05205 cmp_item_datetime::cmp_item_datetime(Item *warn_item_arg) :
05206   session(current_session),
05207   warn_item(warn_item_arg),
05208   lval_cache(0)
05209 {}
05210 
05211 } /* namespace drizzled */