Drizzled Public API Documentation

field.cc

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <drizzled/session.h>
00023 #include <drizzled/table.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/join.h>
00026 #include <drizzled/sql_base.h>
00027 #include <drizzled/sql_select.h>
00028 #include <drizzled/item/cmpfunc.h>
00029 #include <drizzled/item/field.h>
00030 #include <drizzled/item/outer_ref.h>
00031 #include <drizzled/plugin/client.h>
00032 #include <drizzled/item/subselect.h>
00033 #include <drizzled/sql_lex.h>
00034 
00035 #include <boost/dynamic_bitset.hpp>
00036 
00037 namespace drizzled
00038 {
00039 
00058 bool Item_field::collect_item_field_processor(unsigned char *arg)
00059 {
00060   List<Item_field> *item_list= (List<Item_field>*) arg;
00061   List<Item_field>::iterator item_list_it(item_list->begin());
00062   Item_field *curr_item;
00063   while ((curr_item= item_list_it++))
00064   {
00065     if (curr_item->eq(this, 1))
00066       return(false); /* Already in the set. */
00067   }
00068   item_list->push_back(this);
00069   return(false);
00070 }
00071 
00072 
00089 bool Item_field::find_item_in_field_list_processor(unsigned char *arg)
00090 {
00091   KeyPartInfo *first_non_group_part= *((KeyPartInfo **) arg);
00092   KeyPartInfo *last_part= *(((KeyPartInfo **) arg) + 1);
00093   KeyPartInfo *cur_part;
00094 
00095   for (cur_part= first_non_group_part; cur_part != last_part; cur_part++)
00096   {
00097     if (field->eq(cur_part->field))
00098       return true;
00099   }
00100   return false;
00101 }
00102 
00103 
00104 /*
00105   Mark field in read_map
00106 
00107   NOTES
00108     This is used by filesort to register used fields in a a temporary
00109     column read set or to register used fields in a view
00110 */
00111 
00112 bool Item_field::register_field_in_read_map(unsigned char *arg)
00113 {
00114   Table *table= (Table *) arg;
00115   if (field->getTable() == table || !table)
00116     field->getTable()->setReadSet(field->position());
00117 
00118   return 0;
00119 }
00120 
00121 
00122 Item_field::Item_field(Field *f)
00123   :Item_ident(0, NULL, f->getTable()->getAlias(), f->field_name),
00124    item_equal(0), no_const_subst(0),
00125    have_privileges(0), any_privileges(0)
00126 {
00127   set_field(f);
00128   /*
00129     field_name and table_name should not point to garbage
00130     if this item is to be reused
00131   */
00132   orig_table_name= orig_field_name= "";
00133 }
00134 
00135 
00143 Item_field::Item_field(Session *,
00144                        Name_resolution_context *context_arg,
00145                        Field *f) :
00146   Item_ident(context_arg,
00147              f->getTable()->getShare()->getSchemaName(),
00148              f->getTable()->getAlias(),
00149              f->field_name),
00150    item_equal(0),
00151    no_const_subst(0),
00152    have_privileges(0),
00153    any_privileges(0)
00154 {
00155   set_field(f);
00156 }
00157 
00158 
00159 Item_field::Item_field(Name_resolution_context *context_arg,
00160                        const char *db_arg,const char *table_name_arg,
00161                        const char *field_name_arg) :
00162   Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
00163    field(0),
00164    result_field(0),
00165    item_equal(0),
00166    no_const_subst(0),
00167    have_privileges(0),
00168    any_privileges(0)
00169 {
00170   Select_Lex *select= getSession().lex().current_select;
00171   collation.set(DERIVATION_IMPLICIT);
00172 
00173   if (select && select->parsing_place != IN_HAVING)
00174       select->select_n_where_fields++;
00175 }
00176 
00181 Item_field::Item_field(Session *session, Item_field *item) :
00182   Item_ident(session, item),
00183   field(item->field),
00184   result_field(item->result_field),
00185   item_equal(item->item_equal),
00186   no_const_subst(item->no_const_subst),
00187   have_privileges(item->have_privileges),
00188   any_privileges(item->any_privileges)
00189 {
00190   collation.set(DERIVATION_IMPLICIT);
00191 }
00192 
00193 void Item_field::set_field(Field *field_par)
00194 {
00195   field=result_field=field_par;     // for easy coding with fields
00196   maybe_null=field->maybe_null();
00197   decimals= field->decimals();
00198   max_length= field_par->max_display_length();
00199   table_name= field_par->getTable()->getAlias();
00200   field_name= field_par->field_name;
00201   db_name= field_par->getTable()->getShare()->getSchemaName();
00202   alias_name_used= field_par->getTable()->alias_name_used;
00203   unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
00204   collation.set(field_par->charset(), field_par->derivation());
00205   fixed= 1;
00206 }
00207 
00208 
00215 void Item_field::reset_field(Field *f)
00216 {
00217   set_field(f);
00218   /* 'name' is pointing at field->field_name of old field */
00219   name= (char*) f->field_name;
00220 }
00221 
00222 /* ARGSUSED */
00223 String *Item_field::val_str(String *str)
00224 {
00225   assert(fixed == 1);
00226   if ((null_value=field->is_null()))
00227     return 0;
00228   str->set_charset(str_value.charset());
00229   return field->val_str(str,&str_value);
00230 }
00231 
00232 
00233 double Item_field::val_real()
00234 {
00235   assert(fixed == 1);
00236   if ((null_value=field->is_null()))
00237     return 0.0;
00238   return field->val_real();
00239 }
00240 
00241 
00242 int64_t Item_field::val_int()
00243 {
00244   assert(fixed == 1);
00245   if ((null_value=field->is_null()))
00246     return 0;
00247   return field->val_int();
00248 }
00249 
00250 
00251 type::Decimal *Item_field::val_decimal(type::Decimal *decimal_value)
00252 {
00253   if ((null_value= field->is_null()))
00254     return 0;
00255   return field->val_decimal(decimal_value);
00256 }
00257 
00258 
00259 String *Item_field::str_result(String *str)
00260 {
00261   if ((null_value=result_field->is_null()))
00262     return 0;
00263   str->set_charset(str_value.charset());
00264   return result_field->val_str(str,&str_value);
00265 }
00266 
00267 bool Item_field::get_date(type::Time &ltime,uint32_t fuzzydate)
00268 {
00269   if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
00270   {
00271     ltime.reset();
00272     return 1;
00273   }
00274   return 0;
00275 }
00276 
00277 bool Item_field::get_date_result(type::Time &ltime,uint32_t fuzzydate)
00278 {
00279   if ((null_value=result_field->is_null()) ||
00280       result_field->get_date(ltime,fuzzydate))
00281   {
00282     ltime.reset();
00283     return 1;
00284   }
00285   return 0;
00286 }
00287 
00288 bool Item_field::get_time(type::Time &ltime)
00289 {
00290   if ((null_value=field->is_null()) || field->get_time(ltime))
00291   {
00292     ltime.reset();
00293     return 1;
00294   }
00295   return 0;
00296 }
00297 
00298 double Item_field::val_result()
00299 {
00300   if ((null_value=result_field->is_null()))
00301     return 0.0;
00302   return result_field->val_real();
00303 }
00304 
00305 int64_t Item_field::val_int_result()
00306 {
00307   if ((null_value=result_field->is_null()))
00308     return 0;
00309   return result_field->val_int();
00310 }
00311 
00312 
00313 type::Decimal *Item_field::val_decimal_result(type::Decimal *decimal_value)
00314 {
00315   if ((null_value= result_field->is_null()))
00316     return 0;
00317   return result_field->val_decimal(decimal_value);
00318 }
00319 
00320 
00321 bool Item_field::val_bool_result()
00322 {
00323   if ((null_value= result_field->is_null()))
00324   {
00325     return false;
00326   }
00327 
00328   switch (result_field->result_type()) {
00329   case INT_RESULT:
00330     return result_field->val_int() != 0;
00331 
00332   case DECIMAL_RESULT:
00333     {
00334       type::Decimal decimal_value;
00335       type::Decimal *val= result_field->val_decimal(&decimal_value);
00336       if (val)
00337         return not val->isZero();
00338       return 0;
00339     }
00340 
00341   case REAL_RESULT:
00342   case STRING_RESULT:
00343     return result_field->val_real() != 0.0;
00344 
00345   case ROW_RESULT:
00346     assert(0);
00347     return 0;                                   // Shut up compiler
00348   }
00349 
00350   assert(0);
00351   return 0;                                   // Shut up compiler
00352 }
00353 
00354 
00355 bool Item_field::eq(const Item *item, bool) const
00356 {
00357   const Item *item_ptr= item->real_item();
00358   if (item_ptr->type() != FIELD_ITEM)
00359     return 0;
00360 
00361   const Item_field *item_field= static_cast<const Item_field *>(item_ptr);
00362   if (item_field->field && field)
00363     return item_field->field == field;
00364   /*
00365     We may come here when we are trying to find a function in a GROUP BY
00366     clause from the select list.
00367     In this case the '100 % correct' way to do this would be to first
00368     run fix_fields() on the GROUP BY item and then retry this function, but
00369     I think it's better to relax the checking a bit as we will in
00370     most cases do the correct thing by just checking the field name.
00371     (In cases where we would choose wrong we would have to generate a
00372     ER_NON_UNIQ_ERROR).
00373   */
00374   return (not my_strcasecmp(system_charset_info, item_field->name, field_name) &&
00375           (not item_field->table_name || not table_name ||
00376            (not my_strcasecmp(table_alias_charset, item_field->table_name, table_name) &&
00377             (not item_field->db_name || not db_name ||
00378              (item_field->db_name && not my_strcasecmp(system_charset_info, item_field->db_name, db_name))))));
00379 }
00380 
00381 
00382 table_map Item_field::used_tables() const
00383 {
00384   if (field->getTable()->const_table)
00385   {
00386     return 0;         // const item
00387   }
00388 
00389   return (depended_from ? OUTER_REF_TABLE_BIT : field->getTable()->map);
00390 }
00391 
00392 enum Item_result Item_field::result_type () const
00393 {
00394   return field->result_type();
00395 }
00396 
00397 
00398 Item_result Item_field::cast_to_int_type() const
00399 {
00400   return field->cast_to_int_type();
00401 }
00402 
00403 
00404 enum_field_types Item_field::field_type() const
00405 {
00406   return field->type();
00407 }
00408 
00409 
00410 void Item_field::fix_after_pullout(Select_Lex *new_parent, Item **)
00411 {
00412   if (new_parent == depended_from)
00413     depended_from= NULL;
00414   Name_resolution_context *ctx= new Name_resolution_context();
00415   ctx->outer_context= NULL; // We don't build a complete name resolver
00416   ctx->select_lex= new_parent;
00417   ctx->first_name_resolution_table= context->first_name_resolution_table;
00418   ctx->last_name_resolution_table=  context->last_name_resolution_table;
00419   this->context=ctx;
00420 }
00421 
00422 
00423 bool Item_field::is_null()
00424 {
00425   return field->is_null();
00426 }
00427 
00428 
00429 Item *Item_field::get_tmp_table_item(Session *session)
00430 {
00431   Item_field *new_item= new Item_field(session, this);
00432   if (new_item)
00433     new_item->field= new_item->result_field;
00434   return new_item;
00435 }
00436 
00437 int64_t Item_field::val_int_endpoint(bool, bool *)
00438 {
00439   int64_t res= val_int();
00440   return null_value? INT64_MIN : res;
00441 }
00442 
00443 
00483 int
00484 Item_field::fix_outer_field(Session *session, Field **from_field, Item **reference)
00485 {
00486   enum_parsing_place place= NO_MATTER;
00487   bool field_found= (*from_field != not_found_field);
00488   bool upward_lookup= false;
00489 
00490   /*
00491     If there are outer contexts (outer selects, but current select is
00492     not derived table or view) try to resolve this reference in the
00493     outer contexts.
00494 
00495     We treat each subselect as a separate namespace, so that different
00496     subselects may contain columns with the same names. The subselects
00497     are searched starting from the innermost.
00498   */
00499   Name_resolution_context *last_checked_context= context;
00500   Item **ref= (Item **) not_found_item;
00501   Select_Lex *current_sel= (Select_Lex *) session->lex().current_select;
00502   Name_resolution_context *outer_context= 0;
00503   Select_Lex *select= 0;
00504   /* Currently derived tables cannot be correlated */
00505   if (current_sel->master_unit()->first_select()->linkage !=
00506       DERIVED_TABLE_TYPE)
00507     outer_context= context->outer_context;
00508   for (;
00509        outer_context;
00510        outer_context= outer_context->outer_context)
00511   {
00512     select= outer_context->select_lex;
00513     Item_subselect *prev_subselect_item=
00514       last_checked_context->select_lex->master_unit()->item;
00515     last_checked_context= outer_context;
00516     upward_lookup= true;
00517 
00518     place= prev_subselect_item->parsing_place;
00519     /*
00520       If outer_field is set, field was already found by first call
00521       to find_field_in_tables(). Only need to find appropriate context.
00522     */
00523     if (field_found && outer_context->select_lex !=
00524         cached_table->select_lex)
00525       continue;
00526     /*
00527       In case of a view, find_field_in_tables() writes the pointer to
00528       the found view field into '*reference', in other words, it
00529       substitutes this Item_field with the found expression.
00530     */
00531     if (field_found || (*from_field= find_field_in_tables(session, this,
00532                                           outer_context->
00533                                             first_name_resolution_table,
00534                                           outer_context->
00535                                             last_name_resolution_table,
00536                                           reference,
00537                                           IGNORE_EXCEPT_NON_UNIQUE,
00538                                           true)) !=
00539         not_found_field)
00540     {
00541       if (*from_field)
00542       {
00543         if (*from_field != view_ref_found)
00544         {
00545           prev_subselect_item->used_tables_cache|= (*from_field)->getTable()->map;
00546           prev_subselect_item->const_item_cache= false;
00547           set_field(*from_field);
00548           if (!last_checked_context->select_lex->having_fix_field &&
00549               select->group_list.elements &&
00550               (place == SELECT_LIST || place == IN_HAVING))
00551           {
00552             Item_outer_ref *rf;
00553             /*
00554               If an outer field is resolved in a grouping select then it
00555               is replaced for an Item_outer_ref object. Otherwise an
00556               Item_field object is used.
00557               The new Item_outer_ref object is saved in the inner_refs_list of
00558               the outer select. Here it is only created. It can be fixed only
00559               after the original field has been fixed and this is done in the
00560               fix_inner_refs() function.
00561             */
00562             ;
00563             if (!(rf= new Item_outer_ref(context, this)))
00564               return -1;
00565             *reference= rf;
00566             select->inner_refs_list.push_back(rf);
00567             rf->in_sum_func= session->lex().in_sum_func;
00568           }
00569           /*
00570             A reference is resolved to a nest level that's outer or the same as
00571             the nest level of the enclosing set function : adjust the value of
00572             max_arg_level for the function if it's needed.
00573           */
00574           if (session->lex().in_sum_func &&
00575               session->lex().in_sum_func->nest_level >= select->nest_level)
00576           {
00577             Item::Type ref_type= (*reference)->type();
00578             set_if_bigger(session->lex().in_sum_func->max_arg_level,
00579                           select->nest_level);
00580             set_field(*from_field);
00581             fixed= 1;
00582             mark_as_dependent(session, last_checked_context->select_lex,
00583                               context->select_lex, this,
00584                               ((ref_type == REF_ITEM ||
00585                                 ref_type == FIELD_ITEM) ?
00586                                (Item_ident*) (*reference) : 0));
00587             return 0;
00588           }
00589         }
00590         else
00591         {
00592           Item::Type ref_type= (*reference)->type();
00593           prev_subselect_item->used_tables_cache|=
00594             (*reference)->used_tables();
00595           prev_subselect_item->const_item_cache&=
00596             (*reference)->const_item();
00597           mark_as_dependent(session, last_checked_context->select_lex,
00598                             context->select_lex, this,
00599                             ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
00600                              (Item_ident*) (*reference) :
00601                              0));
00602           /*
00603             A reference to a view field had been found and we
00604             substituted it instead of this Item (find_field_in_tables
00605             does it by assigning the new value to *reference), so now
00606             we can return from this function.
00607           */
00608           return 0;
00609         }
00610       }
00611       break;
00612     }
00613 
00614     /* Search in SELECT and GROUP lists of the outer select. */
00615     if (place != IN_WHERE && place != IN_ON)
00616     {
00617       if (!(ref= resolve_ref_in_select_and_group(session, this, select)))
00618         return -1; /* Some error occurred (e.g. ambiguous names). */
00619       if (ref != not_found_item)
00620       {
00621         assert(*ref && (*ref)->fixed);
00622         prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
00623         prev_subselect_item->const_item_cache&= (*ref)->const_item();
00624         break;
00625       }
00626     }
00627 
00628     /*
00629       Reference is not found in this select => this subquery depend on
00630       outer select (or we just trying to find wrong identifier, in this
00631       case it does not matter which used tables bits we set)
00632     */
00633     prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
00634     prev_subselect_item->const_item_cache= false;
00635   }
00636 
00637   assert(ref != 0);
00638   if (!*from_field)
00639     return -1;
00640   if (ref == not_found_item && *from_field == not_found_field)
00641   {
00642     if (upward_lookup)
00643     {
00644       // We can't say exactly what absent table or field
00645       my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), session->where());
00646     }
00647     else
00648     {
00649       /* Call find_field_in_tables only to report the error */
00650       find_field_in_tables(session, this,
00651                            context->first_name_resolution_table,
00652                            context->last_name_resolution_table,
00653                            reference, REPORT_ALL_ERRORS, true);
00654     }
00655     return -1;
00656   }
00657   else if (ref != not_found_item)
00658   {
00659     Item *save;
00660     Item_ref *rf;
00661 
00662     /* Should have been checked in resolve_ref_in_select_and_group(). */
00663     assert(*ref && (*ref)->fixed);
00664     /*
00665       Here, a subset of actions performed by Item_ref::set_properties
00666       is not enough. So we pass ptr to NULL into Item_[direct]_ref
00667       constructor, so no initialization is performed, and call
00668       fix_fields() below.
00669     */
00670     save= *ref;
00671     *ref= NULL;                             // Don't call set_properties()
00672     rf= (place == IN_HAVING ?
00673          new Item_ref(context, ref, (char*) table_name,
00674                       (char*) field_name, alias_name_used) :
00675          (!select->group_list.elements ?
00676          new Item_direct_ref(context, ref, (char*) table_name,
00677                              (char*) field_name, alias_name_used) :
00678          new Item_outer_ref(context, ref, (char*) table_name,
00679                             (char*) field_name, alias_name_used)));
00680     *ref= save;
00681     if (!rf)
00682       return -1;
00683 
00684     if (place != IN_HAVING && select->group_list.elements)
00685     {
00686       outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf);
00687       ((Item_outer_ref*)rf)->in_sum_func= session->lex().in_sum_func;
00688     }
00689     *reference= rf;
00690     /*
00691       rf is Item_ref => never substitute other items (in this case)
00692       during fix_fields() => we can use rf after fix_fields()
00693     */
00694     assert(!rf->fixed);                // Assured by Item_ref()
00695     if (rf->fix_fields(session, reference) || rf->check_cols(1))
00696       return -1;
00697 
00698     mark_as_dependent(session, last_checked_context->select_lex,
00699                       context->select_lex, this,
00700                       rf);
00701     return 0;
00702   }
00703   else
00704   {
00705     mark_as_dependent(session, last_checked_context->select_lex,
00706                       context->select_lex,
00707                       this, (Item_ident*)*reference);
00708     if (last_checked_context->select_lex->having_fix_field)
00709     {
00710       Item_ref *rf;
00711       rf= new Item_ref(context,
00712                        (cached_table->getSchemaName()[0] ? cached_table->getSchemaName() : 0),
00713                        (char*) cached_table->alias, (char*) field_name);
00714       if (!rf)
00715         return -1;
00716       *reference= rf;
00717       /*
00718         rf is Item_ref => never substitute other items (in this case)
00719         during fix_fields() => we can use rf after fix_fields()
00720       */
00721       assert(!rf->fixed);                // Assured by Item_ref()
00722       if (rf->fix_fields(session, reference) || rf->check_cols(1))
00723         return -1;
00724       return 0;
00725     }
00726   }
00727   return 1;
00728 }
00729 
00730 
00776 bool Item_field::fix_fields(Session *session, Item **reference)
00777 {
00778   assert(fixed == 0);
00779   Field *from_field= (Field *)not_found_field;
00780   bool outer_fixed= false;
00781 
00782   if (!field)         // If field is not checked
00783   {
00784     /*
00785       In case of view, find_field_in_tables() write pointer to view field
00786       expression to 'reference', i.e. it substitute that expression instead
00787       of this Item_field
00788     */
00789     if ((from_field= find_field_in_tables(session, this,
00790                                           context->first_name_resolution_table,
00791                                           context->last_name_resolution_table,
00792                                           reference,
00793                                           session->lex().use_only_table_context ?
00794                                             REPORT_ALL_ERRORS :
00795                                             IGNORE_EXCEPT_NON_UNIQUE, true)) ==
00796         not_found_field)
00797     {
00798       int ret;
00799       /* Look up in current select's item_list to find aliased fields */
00800       if (session->lex().current_select->is_item_list_lookup)
00801       {
00802         uint32_t counter;
00803         enum_resolution_type resolution;
00804         Item** res= find_item_in_list(session,
00805                                       this, session->lex().current_select->item_list,
00806                                       &counter, REPORT_EXCEPT_NOT_FOUND,
00807                                       &resolution);
00808         if (!res)
00809           return 1;
00810         if (resolution == RESOLVED_AGAINST_ALIAS)
00811           alias_name_used= true;
00812         if (res != (Item **)not_found_item)
00813         {
00814           if ((*res)->type() == Item::FIELD_ITEM)
00815           {
00816             /*
00817               It's an Item_field referencing another Item_field in the select
00818               list.
00819               Use the field from the Item_field in the select list and leave
00820               the Item_field instance in place.
00821             */
00822 
00823             Field *new_field= (*((Item_field**)res))->field;
00824 
00825             if (new_field == NULL)
00826             {
00827               /* The column to which we link isn't valid. */
00828               my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name,
00829                        session->where());
00830               return(1);
00831             }
00832 
00833             set_field(new_field);
00834             return 0;
00835           }
00836           else
00837           {
00838             /*
00839               It's not an Item_field in the select list so we must make a new
00840               Item_ref to point to the Item in the select list and replace the
00841               Item_field created by the parser with the new Item_ref.
00842             */
00843             Item_ref *rf= new Item_ref(context, db_name,table_name,field_name);
00844             if (!rf)
00845               return 1;
00846             *reference= rf;
00847             /*
00848               Because Item_ref never substitutes itself with other items
00849               in Item_ref::fix_fields(), we can safely use the original
00850               pointer to it even after fix_fields()
00851              */
00852             return rf->fix_fields(session, reference) ||  rf->check_cols(1);
00853           }
00854         }
00855       }
00856       if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
00857         goto error;
00858       outer_fixed= true;
00859       if (!ret)
00860         goto mark_non_agg_field;
00861     }
00862     else if (!from_field)
00863       goto error;
00864 
00865     if (!outer_fixed && cached_table && cached_table->select_lex &&
00866         context->select_lex &&
00867         cached_table->select_lex != context->select_lex)
00868     {
00869       int ret;
00870       if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
00871         goto error;
00872       outer_fixed= 1;
00873       if (!ret)
00874         goto mark_non_agg_field;
00875     }
00876 
00877     /*
00878       if it is not expression from merged VIEW we will set this field.
00879 
00880       We can leave expression substituted from view for next PS/SP rexecution
00881       (i.e. do not register this substitution for reverting on cleanup()
00882       (register_item_tree_changing())), because this subtree will be
00883       fix_field'ed during setup_tables()->setup_underlying() (i.e. before
00884       all other expressions of query, and references on tables which do
00885       not present in query will not make problems.
00886 
00887       Also we suppose that view can't be changed during PS/SP life.
00888     */
00889     if (from_field == view_ref_found)
00890       return false;
00891 
00892     set_field(from_field);
00893     if (session->lex().in_sum_func &&
00894         session->lex().in_sum_func->nest_level ==
00895         session->lex().current_select->nest_level)
00896     {
00897       set_if_bigger(session->lex().in_sum_func->max_arg_level,
00898                     session->lex().current_select->nest_level);
00899     }
00900   }
00901   else if (session->mark_used_columns != MARK_COLUMNS_NONE)
00902   {
00903     Table *table= field->getTable();
00904     boost::dynamic_bitset<> *current_bitmap, *other_bitmap;
00905     if (session->mark_used_columns == MARK_COLUMNS_READ)
00906     {
00907       current_bitmap= table->read_set;
00908       other_bitmap=   table->write_set;
00909     }
00910     else
00911     {
00912       current_bitmap= table->write_set;
00913       other_bitmap=   table->read_set;
00914     }
00915     //if (! current_bitmap->testAndSet(field->position()))
00916     if (! current_bitmap->test(field->position()))
00917     {
00918       if (! other_bitmap->test(field->position()))
00919       {
00920         /* First usage of column */
00921         table->used_fields++;                     // Used to optimize loops
00922         table->covering_keys&= field->part_of_key;
00923       }
00924     }
00925   }
00926   fixed= 1;
00927 mark_non_agg_field:
00928   return false;
00929 
00930 error:
00931   context->process_error(session);
00932   return true;
00933 }
00934 
00935 Item *Item_field::safe_charset_converter(const CHARSET_INFO * const tocs)
00936 {
00937   no_const_subst= 1;
00938   return Item::safe_charset_converter(tocs);
00939 }
00940 
00941 
00942 void Item_field::cleanup()
00943 {
00944   Item_ident::cleanup();
00945   /*
00946     Even if this object was created by direct link to field in setup_wild()
00947     it will be linked correctly next time by name of field and table alias.
00948     I.e. we can drop 'field'.
00949    */
00950   field= result_field= 0;
00951   null_value= false;
00952   return;
00953 }
00954 
00955 
00956 bool Item_field::result_as_int64_t()
00957 {
00958   return field->can_be_compared_as_int64_t();
00959 }
00960 
00961 
00980 Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
00981 {
00982   Item_equal *item= 0;
00983   while (cond_equal)
00984   {
00985     List<Item_equal>::iterator li(cond_equal->current_level.begin());
00986     while ((item= li++))
00987     {
00988       if (item->contains(field))
00989         return item;
00990     }
00991     /*
00992       The field is not found in any of the multiple equalities
00993       of the current level. Look for it in upper levels
00994     */
00995     cond_equal= cond_equal->upper_levels;
00996   }
00997   return 0;
00998 }
00999 
01000 
01031 bool Item_field::subst_argument_checker(unsigned char **arg)
01032 {
01033   return (result_type() != STRING_RESULT) || (*arg);
01034 }
01035 
01036 
01061 Item *Item_field::equal_fields_propagator(unsigned char *arg)
01062 {
01063   if (no_const_subst)
01064     return this;
01065   item_equal= find_item_equal((COND_EQUAL *) arg);
01066   Item *item= 0;
01067   if (item_equal)
01068     item= item_equal->get_const();
01069   /*
01070     Disable const propagation for items used in different comparison contexts.
01071     This must be done because, for example, Item_hex_string->val_int() is not
01072     the same as (Item_hex_string->val_str() in BINARY column)->val_int().
01073     We cannot simply disable the replacement in a particular context (
01074     e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
01075     Items don't know the context they are in and there are functions like
01076     IF (<hex_string>, 'yes', 'no').
01077     The same problem occurs when comparing a DATE/TIME field with a
01078     DATE/TIME represented as an int and as a string.
01079   */
01080   if (!item ||
01081       (cmp_context != (Item_result)-1 && item->cmp_context != cmp_context))
01082     item= this;
01083 
01084   return item;
01085 }
01086 
01087 
01094 bool Item_field::set_no_const_sub(unsigned char *)
01095 {
01096   if (field->charset() != &my_charset_bin)
01097     no_const_subst=1;
01098   return false;
01099 }
01100 
01101 
01127 Item *Item_field::replace_equal_field(unsigned char *)
01128 {
01129   if (item_equal)
01130   {
01131     Item *const_item_ptr= item_equal->get_const();
01132     if (const_item_ptr)
01133     {
01134       if (cmp_context != (Item_result)-1 &&
01135           const_item_ptr->cmp_context != cmp_context)
01136         return this;
01137       return const_item_ptr;
01138     }
01139     Item_field *subst= item_equal->get_first();
01140     if (subst && !field->eq(subst->field))
01141       return subst;
01142   }
01143   return this;
01144 }
01145 
01146 
01147 uint32_t Item_field::max_disp_length()
01148 {
01149   return field->max_display_length();
01150 }
01151 
01152 
01153 /* ARGSUSED */
01154 void Item_field::make_field(SendField *tmp_field)
01155 {
01156   field->make_field(tmp_field);
01157   assert(tmp_field->table_name != 0);
01158   if (name)
01159     tmp_field->col_name=name;     // Use user supplied name
01160   if (table_name)
01161     tmp_field->table_name= table_name;
01162   if (db_name)
01163     tmp_field->db_name= db_name;
01164 }
01165 
01166 
01171 void Item_field::save_org_in_field(Field *to)
01172 {
01173   if (field->is_null())
01174   {
01175     null_value=1;
01176     set_field_to_null_with_conversions(to, 1);
01177   }
01178   else
01179   {
01180     to->set_notnull();
01181     field_conv(to,field);
01182     null_value=0;
01183   }
01184 }
01185 
01186 int Item_field::save_in_field(Field *to, bool no_conversions)
01187 {
01188   int res;
01189   if (result_field->is_null())
01190   {
01191     null_value=1;
01192     res= set_field_to_null_with_conversions(to, no_conversions);
01193   }
01194   else
01195   {
01196     to->set_notnull();
01197     res= field_conv(to,result_field);
01198     null_value=0;
01199   }
01200   return(res);
01201 }
01202 
01203 
01204 bool Item_field::send(plugin::Client *client, String *)
01205 {
01206   return client->store(result_field);
01207 }
01208 
01209 
01210 void Item_field::update_null_value()
01211 {
01212   /*
01213     need to set no_errors to prevent warnings about type conversion
01214     popping up.
01215   */
01216   Session *session= field->getTable()->in_use;
01217   int no_errors;
01218 
01219   no_errors= session->no_errors;
01220   session->no_errors= 1;
01221   Item::update_null_value();
01222   session->no_errors= no_errors;
01223 }
01224 
01225 
01226 /*
01227   Add the field to the select list and substitute it for the reference to
01228   the field.
01229 
01230   SYNOPSIS
01231     Item_field::update_value_transformer()
01232     select_arg      current select
01233 
01234   DESCRIPTION
01235     If the field doesn't belong to the table being inserted into then it is
01236     added to the select list, pointer to it is stored in the ref_pointer_array
01237     of the select and the field itself is substituted for the Item_ref object.
01238     This is done in order to get correct values from update fields that
01239     belongs to the SELECT part in the INSERT .. SELECT .. ON DUPLICATE KEY
01240     UPDATE statement.
01241 
01242   RETURN
01243     0             if error occured
01244     ref           if all conditions are met
01245     this field    otherwise
01246 */
01247 
01248 Item *Item_field::update_value_transformer(unsigned char *select_arg)
01249 {
01250   Select_Lex *select= (Select_Lex*)select_arg;
01251   assert(fixed);
01252 
01253   if (field->getTable() != select->context.table_list->table)
01254   {
01255     List<Item> *all_fields= &select->join->all_fields;
01256     Item **ref_pointer_array= select->ref_pointer_array;
01257     int el= all_fields->size();
01258     Item_ref *ref;
01259 
01260     ref_pointer_array[el]= (Item*)this;
01261     all_fields->push_front((Item*)this);
01262     ref= new Item_ref(&select->context, ref_pointer_array + el,
01263                       table_name, field_name);
01264     return ref;
01265   }
01266   return this;
01267 }
01268 
01269 
01270 void Item_field::print(String *str)
01271 {
01272   if (field && field->getTable()->const_table)
01273   {
01274     char buff[MAX_FIELD_WIDTH];
01275     String tmp(buff,sizeof(buff),str->charset());
01276     field->val_str_internal(&tmp);
01277     if (field->is_null())  {
01278       str->append("NULL");
01279     }
01280     else {
01281       str->append('\'');
01282       str->append(tmp);
01283       str->append('\'');
01284     }
01285     return;
01286   }
01287   Item_ident::print(str);
01288 }
01289 
01290 
01291 } /* namespace drizzled */