Drizzled Public API Documentation

field.cc
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #include <config.h>
21 
22 #include <drizzled/session.h>
23 #include <drizzled/table.h>
24 #include <drizzled/error.h>
25 #include <drizzled/join.h>
26 #include <drizzled/sql_base.h>
27 #include <drizzled/sql_select.h>
28 #include <drizzled/item/cmpfunc.h>
29 #include <drizzled/item/field.h>
30 #include <drizzled/item/outer_ref.h>
31 #include <drizzled/plugin/client.h>
32 #include <drizzled/item/subselect.h>
33 #include <drizzled/sql_lex.h>
34 
35 #include <boost/dynamic_bitset.hpp>
36 
37 namespace drizzled {
38 
58 {
59  List<Item_field> *item_list= (List<Item_field>*) arg;
60  List<Item_field>::iterator item_list_it(item_list->begin());
61  while (Item_field* curr_item= item_list_it++)
62  {
63  if (curr_item->eq(this, 1))
64  return false; /* Already in the set. */
65  }
66  item_list->push_back(this);
67  return false;
68 }
69 
70 
88 {
89  KeyPartInfo *first_non_group_part= *((KeyPartInfo **) arg);
90  KeyPartInfo *last_part= *(((KeyPartInfo **) arg) + 1);
91 
92  for (KeyPartInfo* cur_part= first_non_group_part; cur_part != last_part; cur_part++)
93  {
94  if (field->eq(cur_part->field))
95  return true;
96  }
97  return false;
98 }
99 
100 
101 /*
102  Mark field in read_map
103 
104  NOTES
105  This is used by filesort to register used fields in a a temporary
106  column read set or to register used fields in a view
107 */
108 
109 bool Item_field::register_field_in_read_map(unsigned char *arg)
110 {
111  Table *table= (Table *) arg;
112  if (field->getTable() == table || !table)
113  field->getTable()->setReadSet(field->position());
114 
115  return 0;
116 }
117 
118 
119 Item_field::Item_field(Field *f)
120  :Item_ident(0, NULL, f->getTable()->getAlias(), f->field_name),
121  item_equal(0), no_const_subst(0),
122  have_privileges(0), any_privileges(0)
123 {
124  set_field(f);
125  /*
126  field_name and table_name should not point to garbage
127  if this item is to be reused
128  */
129  orig_table_name= orig_field_name= "";
130 }
131 
132 
140 Item_field::Item_field(Session *,
141  Name_resolution_context *context_arg,
142  Field *f) :
143  Item_ident(context_arg,
144  f->getTable()->getShare()->getSchemaName(),
145  f->getTable()->getAlias(),
146  f->field_name),
147  item_equal(0),
148  no_const_subst(0),
149  have_privileges(0),
150  any_privileges(0)
151 {
152  set_field(f);
153 }
154 
155 
156 Item_field::Item_field(Name_resolution_context *context_arg,
157  const char *db_arg,const char *table_name_arg,
158  const char *field_name_arg) :
159  Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
160  field(0),
161  result_field(0),
162  item_equal(0),
163  no_const_subst(0),
164  have_privileges(0),
165  any_privileges(0)
166 {
167  Select_Lex *select= getSession().lex().current_select;
168  collation.set(DERIVATION_IMPLICIT);
169 
170  if (select && select->parsing_place != IN_HAVING)
171  select->select_n_where_fields++;
172 }
173 
178 Item_field::Item_field(Session *session, Item_field *item) :
179  Item_ident(session, item),
180  field(item->field),
181  result_field(item->result_field),
182  item_equal(item->item_equal),
183  no_const_subst(item->no_const_subst),
184  have_privileges(item->have_privileges),
185  any_privileges(item->any_privileges)
186 {
187  collation.set(DERIVATION_IMPLICIT);
188 }
189 
190 void Item_field::set_field(Field *field_par)
191 {
192  field=result_field=field_par; // for easy coding with fields
193  maybe_null=field->maybe_null();
194  decimals= field->decimals();
195  max_length= field_par->max_display_length();
196  table_name= field_par->getTable()->getAlias();
197  field_name= field_par->field_name;
198  db_name= field_par->getTable()->getShare()->getSchemaName();
199  alias_name_used= field_par->getTable()->alias_name_used;
200  unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
201  collation.set(field_par->charset(), field_par->derivation());
202  fixed= 1;
203 }
204 
205 
213 {
214  set_field(f);
215  /* 'name' is pointing at field->field_name of old field */
216  name= f->field_name;
217 }
218 
219 /* ARGSUSED */
221 {
222  assert(fixed == 1);
223  if ((null_value=field->is_null()))
224  return 0;
225  str->set_charset(str_value.charset());
226  return field->val_str(str,&str_value);
227 }
228 
229 
231 {
232  assert(fixed == 1);
233  if ((null_value=field->is_null()))
234  return 0.0;
235  return field->val_real();
236 }
237 
238 
240 {
241  assert(fixed == 1);
242  if ((null_value=field->is_null()))
243  return 0;
244  return field->val_int();
245 }
246 
247 
249 {
250  if ((null_value= field->is_null()))
251  return 0;
252  return field->val_decimal(decimal_value);
253 }
254 
255 
256 String *Item_field::str_result(String *str)
257 {
258  if ((null_value=result_field->is_null()))
259  return 0;
260  str->set_charset(str_value.charset());
261  return result_field->val_str(str,&str_value);
262 }
263 
264 bool Item_field::get_date(type::Time &ltime,uint32_t fuzzydate)
265 {
266  if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
267  {
268  ltime.reset();
269  return 1;
270  }
271  return 0;
272 }
273 
274 bool Item_field::get_date_result(type::Time &ltime,uint32_t fuzzydate)
275 {
276  if ((null_value=result_field->is_null()) ||
277  result_field->get_date(ltime,fuzzydate))
278  {
279  ltime.reset();
280  return 1;
281  }
282  return 0;
283 }
284 
286 {
287  if ((null_value=field->is_null()) || field->get_time(ltime))
288  {
289  ltime.reset();
290  return 1;
291  }
292  return 0;
293 }
294 
295 double Item_field::val_result()
296 {
297  if ((null_value=result_field->is_null()))
298  return 0.0;
299  return result_field->val_real();
300 }
301 
302 int64_t Item_field::val_int_result()
303 {
304  if ((null_value=result_field->is_null()))
305  return 0;
306  return result_field->val_int();
307 }
308 
309 
310 type::Decimal *Item_field::val_decimal_result(type::Decimal *decimal_value)
311 {
312  if ((null_value= result_field->is_null()))
313  return 0;
314  return result_field->val_decimal(decimal_value);
315 }
316 
317 
318 bool Item_field::val_bool_result()
319 {
320  if ((null_value= result_field->is_null()))
321  {
322  return false;
323  }
324 
325  switch (result_field->result_type())
326  {
327  case INT_RESULT:
328  return result_field->val_int() != 0;
329 
330  case DECIMAL_RESULT:
331  {
332  type::Decimal decimal_value;
333  type::Decimal *val= result_field->val_decimal(&decimal_value);
334  if (val)
335  return not val->isZero();
336  return 0;
337  }
338 
339  case REAL_RESULT:
340  case STRING_RESULT:
341  return result_field->val_real() != 0.0;
342 
343  case ROW_RESULT:
344  assert(false);
345  return 0;
346  }
347 
348  assert(false);
349  return 0;
350 }
351 
352 
353 bool Item_field::eq(const Item *item, bool) const
354 {
355  const Item *item_ptr= item->real_item();
356  if (item_ptr->type() != FIELD_ITEM)
357  return 0;
358 
359  const Item_field *item_field= static_cast<const Item_field *>(item_ptr);
360  if (item_field->field && field)
361  return item_field->field == field;
362  /*
363  We may come here when we are trying to find a function in a GROUP BY
364  clause from the select list.
365  In this case the '100 % correct' way to do this would be to first
366  run fix_fields() on the GROUP BY item and then retry this function, but
367  I think it's better to relax the checking a bit as we will in
368  most cases do the correct thing by just checking the field name.
369  (In cases where we would choose wrong we would have to generate a
370  ER_NON_UNIQ_ERROR).
371  */
372  return (not system_charset_info->strcasecmp(item_field->name, field_name) &&
373  (not item_field->table_name || not table_name ||
374  (not table_alias_charset->strcasecmp(item_field->table_name, table_name) &&
375  (not item_field->db_name || not db_name ||
376  (item_field->db_name && not system_charset_info->strcasecmp(item_field->db_name, db_name))))));
377 }
378 
379 
380 table_map Item_field::used_tables() const
381 {
382  if (field->getTable()->const_table)
383  {
384  return 0; // const item
385  }
386 
387  return depended_from ? OUTER_REF_TABLE_BIT : field->getTable()->map;
388 }
389 
390 enum Item_result Item_field::result_type () const
391 {
392  return field->result_type();
393 }
394 
395 
396 Item_result Item_field::cast_to_int_type() const
397 {
398  return field->cast_to_int_type();
399 }
400 
401 
402 enum_field_types Item_field::field_type() const
403 {
404  return field->type();
405 }
406 
407 
408 void Item_field::fix_after_pullout(Select_Lex *new_parent, Item **)
409 {
410  if (new_parent == depended_from)
411  depended_from= NULL;
413  ctx->outer_context= NULL; // We don't build a complete name resolver
414  ctx->select_lex= new_parent;
417  this->context=ctx;
418 }
419 
420 
422 {
423  return field->is_null();
424 }
425 
426 
427 Item *Item_field::get_tmp_table_item(Session *session)
428 {
429  Item_field *new_item= new Item_field(session, this);
430  new_item->field= new_item->result_field;
431  return new_item;
432 }
433 
434 int64_t Item_field::val_int_endpoint(bool, bool *)
435 {
436  int64_t res= val_int();
437  return null_value? INT64_MIN : res;
438 }
439 
440 
480 int
481 Item_field::fix_outer_field(Session *session, Field **from_field, Item **reference)
482 {
483  enum_parsing_place place= NO_MATTER;
484  bool field_found= (*from_field != not_found_field);
485  bool upward_lookup= false;
486 
487  /*
488  If there are outer contexts (outer selects, but current select is
489  not derived table or view) try to resolve this reference in the
490  outer contexts.
491 
492  We treat each subselect as a separate namespace, so that different
493  subselects may contain columns with the same names. The subselects
494  are searched starting from the innermost.
495  */
496  Name_resolution_context *last_checked_context= context;
497  Item **ref= (Item **) not_found_item;
498  Select_Lex *current_sel= (Select_Lex *) session->lex().current_select;
499  Name_resolution_context *outer_context= 0;
500  Select_Lex *select= 0;
501  /* Currently derived tables cannot be correlated */
502  if (current_sel->master_unit()->first_select()->linkage !=
503  DERIVED_TABLE_TYPE)
504  outer_context= context->outer_context;
505  for (;
506  outer_context;
507  outer_context= outer_context->outer_context)
508  {
509  select= outer_context->select_lex;
510  Item_subselect *prev_subselect_item=
511  last_checked_context->select_lex->master_unit()->item;
512  last_checked_context= outer_context;
513  upward_lookup= true;
514 
515  place= prev_subselect_item->parsing_place;
516  /*
517  If outer_field is set, field was already found by first call
518  to find_field_in_tables(). Only need to find appropriate context.
519  */
520  if (field_found && outer_context->select_lex !=
521  cached_table->select_lex)
522  continue;
523  /*
524  In case of a view, find_field_in_tables() writes the pointer to
525  the found view field into '*reference', in other words, it
526  substitutes this Item_field with the found expression.
527  */
528  if (field_found || (*from_field= find_field_in_tables(session, this,
529  outer_context->
530  first_name_resolution_table,
531  outer_context->
532  last_name_resolution_table,
533  reference,
534  IGNORE_EXCEPT_NON_UNIQUE,
535  true)) !=
536  not_found_field)
537  {
538  if (*from_field)
539  {
540  if (*from_field != view_ref_found)
541  {
542  prev_subselect_item->used_tables_cache|= (*from_field)->getTable()->map;
543  prev_subselect_item->const_item_cache= false;
544  set_field(*from_field);
545  if (!last_checked_context->select_lex->having_fix_field &&
546  select->group_list.elements &&
547  (place == SELECT_LIST || place == IN_HAVING))
548  {
549  /*
550  If an outer field is resolved in a grouping select then it
551  is replaced for an Item_outer_ref object. Otherwise an
552  Item_field object is used.
553  The new Item_outer_ref object is saved in the inner_refs_list of
554  the outer select. Here it is only created. It can be fixed only
555  after the original field has been fixed and this is done in the
556  fix_inner_refs() function.
557  */
558  Item_outer_ref* rf= new Item_outer_ref(context, this);
559  *reference= rf;
560  select->inner_refs_list.push_back(rf);
561  rf->in_sum_func= session->lex().in_sum_func;
562  }
563  /*
564  A reference is resolved to a nest level that's outer or the same as
565  the nest level of the enclosing set function : adjust the value of
566  max_arg_level for the function if it's needed.
567  */
568  if (session->lex().in_sum_func &&
569  session->lex().in_sum_func->nest_level >= select->nest_level)
570  {
571  Item::Type ref_type= (*reference)->type();
572  set_if_bigger(session->lex().in_sum_func->max_arg_level,
573  select->nest_level);
574  set_field(*from_field);
575  fixed= 1;
576  mark_as_dependent(session, last_checked_context->select_lex,
577  context->select_lex, this,
578  ((ref_type == REF_ITEM ||
579  ref_type == FIELD_ITEM) ?
580  (Item_ident*) (*reference) : 0));
581  return 0;
582  }
583  }
584  else
585  {
586  Item::Type ref_type= (*reference)->type();
587  prev_subselect_item->used_tables_cache|= (*reference)->used_tables();
588  prev_subselect_item->const_item_cache&= (*reference)->const_item();
589  mark_as_dependent(session, last_checked_context->select_lex,
590  context->select_lex, this, ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ? (Item_ident*) (*reference) : 0));
591  /*
592  A reference to a view field had been found and we
593  substituted it instead of this Item (find_field_in_tables
594  does it by assigning the new value to *reference), so now
595  we can return from this function.
596  */
597  return 0;
598  }
599  }
600  break;
601  }
602 
603  /* Search in SELECT and GROUP lists of the outer select. */
604  if (place != IN_WHERE && place != IN_ON)
605  {
606  if (!(ref= resolve_ref_in_select_and_group(session, this, select)))
607  return -1; /* Some error occurred (e.g. ambiguous names). */
608  if (ref != not_found_item)
609  {
610  assert(*ref && (*ref)->fixed);
611  prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
612  prev_subselect_item->const_item_cache&= (*ref)->const_item();
613  break;
614  }
615  }
616 
617  /*
618  Reference is not found in this select => this subquery depend on
619  outer select (or we just trying to find wrong identifier, in this
620  case it does not matter which used tables bits we set)
621  */
622  prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
623  prev_subselect_item->const_item_cache= false;
624  }
625 
626  assert(ref != 0);
627  if (!*from_field)
628  return -1;
629  if (ref == not_found_item && *from_field == not_found_field)
630  {
631  if (upward_lookup)
632  {
633  // We can't say exactly what absent table or field
634  my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), session->where());
635  }
636  else
637  {
638  /* Call find_field_in_tables only to report the error */
639  find_field_in_tables(session, this,
642  reference, REPORT_ALL_ERRORS, true);
643  }
644  return -1;
645  }
646  else if (ref != not_found_item)
647  {
648  /* Should have been checked in resolve_ref_in_select_and_group(). */
649  assert(*ref && (*ref)->fixed);
650  /*
651  Here, a subset of actions performed by Item_ref::set_properties
652  is not enough. So we pass ptr to NULL into Item_[direct]_ref
653  constructor, so no initialization is performed, and call
654  fix_fields() below.
655  */
656  Item* save= *ref;
657  *ref= NULL; // Don't call set_properties()
658  Item_ref* rf= (place == IN_HAVING ?
659  new Item_ref(context, ref, table_name, field_name, alias_name_used) :
660  (!select->group_list.elements ?
661  new Item_direct_ref(context, ref, table_name, field_name, alias_name_used) :
662  new Item_outer_ref(context, ref, table_name, field_name, alias_name_used)));
663  *ref= save;
664  if (!rf)
665  return -1;
666 
667  if (place != IN_HAVING && select->group_list.elements)
668  {
669  outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf);
670  ((Item_outer_ref*)rf)->in_sum_func= session->lex().in_sum_func;
671  }
672  *reference= rf;
673  /*
674  rf is Item_ref => never substitute other items (in this case)
675  during fix_fields() => we can use rf after fix_fields()
676  */
677  assert(!rf->fixed); // Assured by Item_ref()
678  if (rf->fix_fields(session, reference) || rf->check_cols(1))
679  return -1;
680 
681  mark_as_dependent(session, last_checked_context->select_lex, context->select_lex, this, rf);
682  return 0;
683  }
684  else
685  {
686  mark_as_dependent(session, last_checked_context->select_lex, context->select_lex, this, (Item_ident*)*reference);
687  if (last_checked_context->select_lex->having_fix_field)
688  {
689  Item_ref* rf= new Item_ref(context, (cached_table->getSchemaName()[0] ? cached_table->getSchemaName() : 0), cached_table->alias, field_name);
690  *reference= rf;
691  /*
692  rf is Item_ref => never substitute other items (in this case)
693  during fix_fields() => we can use rf after fix_fields()
694  */
695  assert(!rf->fixed); // Assured by Item_ref()
696  if (rf->fix_fields(session, reference) || rf->check_cols(1))
697  return -1;
698  return 0;
699  }
700  }
701  return 1;
702 }
703 
704 
750 bool Item_field::fix_fields(Session *session, Item **reference)
751 {
752  assert(fixed == 0);
753  Field *from_field= (Field *)not_found_field;
754  bool outer_fixed= false;
755 
756  if (!field) // If field is not checked
757  {
758  /*
759  In case of view, find_field_in_tables() write pointer to view field
760  expression to 'reference', i.e. it substitute that expression instead
761  of this Item_field
762  */
763  if ((from_field= find_field_in_tables(session, this,
766  reference,
767  session->lex().use_only_table_context ?
768  REPORT_ALL_ERRORS :
769  IGNORE_EXCEPT_NON_UNIQUE, true)) ==
770  not_found_field)
771  {
772  int ret;
773  /* Look up in current select's item_list to find aliased fields */
774  if (session->lex().current_select->is_item_list_lookup)
775  {
776  uint32_t counter;
777  enum_resolution_type resolution;
778  Item** res= find_item_in_list(session,
779  this, session->lex().current_select->item_list,
780  &counter, REPORT_EXCEPT_NOT_FOUND,
781  &resolution);
782  if (!res)
783  return 1;
784  if (resolution == RESOLVED_AGAINST_ALIAS)
785  alias_name_used= true;
786  if (res != (Item **)not_found_item)
787  {
788  if ((*res)->type() == Item::FIELD_ITEM)
789  {
790  /*
791  It's an Item_field referencing another Item_field in the select
792  list.
793  Use the field from the Item_field in the select list and leave
794  the Item_field instance in place.
795  */
796 
797  Field *new_field= (*((Item_field**)res))->field;
798 
799  if (new_field == NULL)
800  {
801  /* The column to which we link isn't valid. */
802  my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name,
803  session->where());
804  return 1;
805  }
806 
807  set_field(new_field);
808  return 0;
809  }
810  else
811  {
812  /*
813  It's not an Item_field in the select list so we must make a new
814  Item_ref to point to the Item in the select list and replace the
815  Item_field created by the parser with the new Item_ref.
816  */
817  Item_ref *rf= new Item_ref(context, db_name,table_name,field_name);
818  *reference= rf;
819  /*
820  Because Item_ref never substitutes itself with other items
821  in Item_ref::fix_fields(), we can safely use the original
822  pointer to it even after fix_fields()
823  */
824  return rf->fix_fields(session, reference) || rf->check_cols(1);
825  }
826  }
827  }
828  if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
829  return true;
830  outer_fixed= true;
831  if (!ret)
832  goto mark_non_agg_field;
833  }
834  else if (!from_field)
835  return true;
836 
837  if (!outer_fixed && cached_table && cached_table->select_lex &&
838  context->select_lex &&
839  cached_table->select_lex != context->select_lex)
840  {
841  int ret;
842  if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
843  return true;
844  outer_fixed= 1;
845  if (!ret)
846  goto mark_non_agg_field;
847  }
848 
849  /*
850  if it is not expression from merged VIEW we will set this field.
851 
852  We can leave expression substituted from view for next PS/SP rexecution
853  (i.e. do not register this substitution for reverting on cleanup()
854  (register_item_tree_changing())), because this subtree will be
855  fix_field'ed during setup_tables()->setup_underlying() (i.e. before
856  all other expressions of query, and references on tables which do
857  not present in query will not make problems.
858 
859  Also we suppose that view can't be changed during PS/SP life.
860  */
861  if (from_field == view_ref_found)
862  return false;
863 
864  set_field(from_field);
865  if (session->lex().in_sum_func &&
866  session->lex().in_sum_func->nest_level ==
867  session->lex().current_select->nest_level)
868  {
869  set_if_bigger(session->lex().in_sum_func->max_arg_level,
870  session->lex().current_select->nest_level);
871  }
872  }
873  else if (session->mark_used_columns != MARK_COLUMNS_NONE)
874  {
875  Table *table= field->getTable();
876  boost::dynamic_bitset<> *current_bitmap, *other_bitmap;
877  if (session->mark_used_columns == MARK_COLUMNS_READ)
878  {
879  current_bitmap= table->read_set;
880  other_bitmap= table->write_set;
881  }
882  else
883  {
884  current_bitmap= table->write_set;
885  other_bitmap= table->read_set;
886  }
887  //if (! current_bitmap->testAndSet(field->position()))
888  if (! current_bitmap->test(field->position()))
889  {
890  if (! other_bitmap->test(field->position()))
891  {
892  /* First usage of column */
893  table->used_fields++; // Used to optimize loops
894  table->covering_keys&= field->part_of_key;
895  }
896  }
897  }
898  fixed= 1;
899 mark_non_agg_field:
900  return false;
901 }
902 
903 Item *Item_field::safe_charset_converter(const charset_info_st * const tocs)
904 {
905  no_const_subst= 1;
906  return Item::safe_charset_converter(tocs);
907 }
908 
909 
910 void Item_field::cleanup()
911 {
912  Item_ident::cleanup();
913  /*
914  Even if this object was created by direct link to field in setup_wild()
915  it will be linked correctly next time by name of field and table alias.
916  I.e. we can drop 'field'.
917  */
918  field= result_field= 0;
919  null_value= false;
920 }
921 
922 
924 {
925  return field->can_be_compared_as_int64_t();
926 }
927 
928 
948 {
949  while (cond_equal)
950  {
951  List<Item_equal>::iterator li(cond_equal->current_level.begin());
952  while (Item_equal* item= li++)
953  {
954  if (item->contains(field))
955  return item;
956  }
957  /*
958  The field is not found in any of the multiple equalities
959  of the current level. Look for it in upper levels
960  */
961  cond_equal= cond_equal->upper_levels;
962  }
963  return 0;
964 }
965 
966 
997 bool Item_field::subst_argument_checker(unsigned char **arg)
998 {
999  return (result_type() != STRING_RESULT) || (*arg);
1000 }
1001 
1002 
1028 {
1029  if (no_const_subst)
1030  return this;
1031  item_equal= find_item_equal((COND_EQUAL *) arg);
1032  Item *item= 0;
1033  if (item_equal)
1034  item= item_equal->get_const();
1035  /*
1036  Disable const propagation for items used in different comparison contexts.
1037  This must be done because, for example, Item_hex_string->val_int() is not
1038  the same as (Item_hex_string->val_str() in BINARY column)->val_int().
1039  We cannot simply disable the replacement in a particular context (
1040  e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
1041  Items don't know the context they are in and there are functions like
1042  IF (<hex_string>, 'yes', 'no').
1043  The same problem occurs when comparing a DATE/TIME field with a
1044  DATE/TIME represented as an int and as a string.
1045  */
1046  if (!item ||
1047  (cmp_context != (Item_result)-1 && item->cmp_context != cmp_context))
1048  item= this;
1049 
1050  return item;
1051 }
1052 
1053 
1060 bool Item_field::set_no_const_sub(unsigned char *)
1061 {
1062  if (field->charset() != &my_charset_bin)
1063  no_const_subst=1;
1064  return false;
1065 }
1066 
1067 
1094 {
1095  if (item_equal)
1096  {
1097  Item *const_item_ptr= item_equal->get_const();
1098  if (const_item_ptr)
1099  {
1100  if (cmp_context != (Item_result)-1 &&
1101  const_item_ptr->cmp_context != cmp_context)
1102  return this;
1103  return const_item_ptr;
1104  }
1105  Item_field *subst= item_equal->get_first();
1106  if (subst && !field->eq(subst->field))
1107  return subst;
1108  }
1109  return this;
1110 }
1111 
1112 
1113 uint32_t Item_field::max_disp_length()
1114 {
1115  return field->max_display_length();
1116 }
1117 
1118 
1119 /* ARGSUSED */
1120 void Item_field::make_field(SendField *tmp_field)
1121 {
1122  field->make_field(tmp_field);
1123  assert(tmp_field->table_name != 0);
1124  if (name)
1125  tmp_field->col_name=name; // Use user supplied name
1126  if (table_name)
1127  tmp_field->table_name= table_name;
1128  if (db_name)
1129  tmp_field->db_name= db_name;
1130 }
1131 
1132 
1138 {
1139  if (field->is_null())
1140  {
1141  null_value=1;
1143  }
1144  else
1145  {
1146  to->set_notnull();
1147  field_conv(to,field);
1148  null_value=0;
1149  }
1150 }
1151 
1152 int Item_field::save_in_field(Field *to, bool no_conversions)
1153 {
1154  int res;
1155  if (result_field->is_null())
1156  {
1157  null_value=1;
1158  res= set_field_to_null_with_conversions(to, no_conversions);
1159  }
1160  else
1161  {
1162  to->set_notnull();
1163  res= field_conv(to,result_field);
1164  null_value=0;
1165  }
1166  return res;
1167 }
1168 
1169 
1171 {
1172  client->store(result_field);
1173 }
1174 
1175 
1177 {
1178  /*
1179  need to set no_errors to prevent warnings about type conversion
1180  popping up.
1181  */
1182  Session *session= field->getTable()->in_use;
1183  int no_errors= session->no_errors;
1184  session->no_errors= 1;
1186  session->no_errors= no_errors;
1187 }
1188 
1189 
1190 /*
1191  Add the field to the select list and substitute it for the reference to
1192  the field.
1193 
1194  SYNOPSIS
1195  Item_field::update_value_transformer()
1196  select_arg current select
1197 
1198  DESCRIPTION
1199  If the field doesn't belong to the table being inserted into then it is
1200  added to the select list, pointer to it is stored in the ref_pointer_array
1201  of the select and the field itself is substituted for the Item_ref object.
1202  This is done in order to get correct values from update fields that
1203  belongs to the SELECT part in the INSERT .. SELECT .. ON DUPLICATE KEY
1204  UPDATE statement.
1205 
1206  RETURN
1207  0 if error occured
1208  ref if all conditions are met
1209  this field otherwise
1210 */
1211 
1212 Item *Item_field::update_value_transformer(unsigned char *select_arg)
1213 {
1214  Select_Lex *select= (Select_Lex*)select_arg;
1215  assert(fixed);
1216 
1217  if (field->getTable() != select->context.table_list->table)
1218  {
1219  List<Item> *all_fields= &select->join->all_fields;
1220  Item **ref_pointer_array= select->ref_pointer_array;
1221  int el= all_fields->size();
1222  ref_pointer_array[el]= (Item*)this;
1223  all_fields->push_front((Item*)this);
1224  Item_ref* ref= new Item_ref(&select->context, ref_pointer_array + el, table_name, field_name);
1225  return ref;
1226  }
1227  return this;
1228 }
1229 
1230 
1232 {
1233  if (field && field->getTable()->const_table)
1234  {
1235  char buff[MAX_FIELD_WIDTH];
1236  String tmp(buff,sizeof(buff),str->charset());
1237  field->val_str_internal(&tmp);
1238  if (field->is_null()) {
1239  str->append(STRING_WITH_LEN("NULL"));
1240  }
1241  else {
1242  str->append('\'');
1243  str->append(tmp);
1244  str->append('\'');
1245  }
1246  return;
1247  }
1248  Item_ident::print(str);
1249 }
1250 
1251 
1252 } /* namespace drizzled */
const char * name
Definition: item.h:110
Select_Lex * select_lex
Definition: table_list.h:208
table_map map
ID bit of table (1,2,4,8,16...)
Definition: table.h:270
type::Decimal * val_decimal(type::Decimal *)
Definition: field.cc:248
virtual void print(String *str)
Definition: ident.cc:103
Item_equal * find_item_equal(COND_EQUAL *cond_equal)
Definition: field.cc:947
double val_real()
Definition: field.cc:230
Item ** resolve_ref_in_select_and_group(Session *session, Item_ident *ref, Select_Lex *select)
Definition: item.cc:940
virtual void print(String *str)
Definition: field.cc:1231
bool fixed
Definition: item.h:120
void save_org_in_field(Field *field)
Definition: field.cc:1137
bool find_item_in_field_list_processor(unsigned char *arg)
Definition: field.cc:87
table_map used_tables() const
Definition: field.cc:380
bool get_time(type::Time &ltime)
Definition: field.cc:285
bool get_date(type::Time &ltime, uint32_t fuzzydate)
Definition: field.cc:264
bool fix_fields(Session *, Item **)
Definition: ref.cc:113
bool null_value
Definition: item.h:122
Item_result cmp_context
Definition: item.h:144
bool set_no_const_sub(unsigned char *arg)
Definition: field.cc:1060
virtual void update_null_value()
Definition: item.cc:518
bool subst_argument_checker(unsigned char **arg)
Definition: field.cc:997
String * val_str(String *)
Definition: field.cc:220
void fix_after_pullout(Select_Lex *new_parent, Item **ref)
Definition: field.cc:408
bool maybe_null
Definition: item.h:121
bool fix_fields(Session *, Item **)
Definition: field.cc:750
bool collect_item_field_processor(unsigned char *arg)
Definition: field.cc:57
virtual bool can_be_compared_as_int64_t() const
Definition: field.h:359
void reset_field(Field *f)
Definition: field.cc:212
int field_conv(Field *to, Field *from)
Definition: field_conv.cc:795
int set_field_to_null_with_conversions(Field *field, bool no_conversions)
Definition: field_conv.cc:179
void mark_as_dependent(Session *session, Select_Lex *last, Select_Lex *current, Item_ident *resolved_item, Item_ident *mark_item)
Definition: item.cc:772
int64_t val_int()
Definition: field.cc:239
Session * in_use
Definition: table.h:123
bool result_as_int64_t()
Definition: field.cc:923
void send(plugin::Client *client, String *str_arg)
Definition: field.cc:1170
void update_null_value()
Definition: field.cc:1176
enum_resolution_type
Definition: sql_base.h:82
Item * equal_fields_propagator(unsigned char *arg)
Definition: field.cc:1027
String str_value
Definition: item.h:107
const char * field_name
Definition: field.h:102
bool eq(const Item *item, bool binary_cmp) const
Definition: field.cc:353
Item * replace_equal_field(unsigned char *arg)
Definition: field.cc:1093
int fix_outer_field(Session *session, Field **field, Item **reference)
Definition: field.cc:481
int64_t val_int_endpoint(bool left_endp, bool *incl_endp)
Definition: field.cc:434
Name_resolution_context * outer_context