1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
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.
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.
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
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>
35
#include <boost/dynamic_bitset.hpp>
40
Store the pointer to this item field into a list if not already there.
42
The method is used by Item::walk to collect all unique Item_field objects
43
from a tree of Items into a set of items represented as a list.
45
Item_cond::walk() and Item_func::walk() stop the evaluation of the
46
processor function for its arguments once the processor returns
47
true.Therefore in order to force this method being called for all item
48
arguments in a condition the method must return false.
50
@param arg pointer to a List<Item_field>
53
false to force the evaluation of collect_item_field_processor
54
for the subsequent items.
57
bool Item_field::collect_item_field_processor(unsigned char *arg)
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++)
63
if (curr_item->eq(this, 1))
64
return false; /* Already in the set. */
66
item_list->push_back(this);
72
Check if an Item_field references some field from a list of fields.
74
Check whether the Item_field represented by 'this' references any
75
of the fields in the keyparts passed via 'arg'. Used with the
76
method Item::walk() to test whether any keypart in a sequence of
77
keyparts is referenced in an expression.
79
@param arg Field being compared, arg must be of type Field
82
true if 'this' references the field 'arg'
87
bool Item_field::find_item_in_field_list_processor(unsigned char *arg)
89
KeyPartInfo *first_non_group_part= *((KeyPartInfo **) arg);
90
KeyPartInfo *last_part= *(((KeyPartInfo **) arg) + 1);
92
for (KeyPartInfo* cur_part= first_non_group_part; cur_part != last_part; cur_part++)
94
if (field->eq(cur_part->field))
102
Mark field in read_map
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
109
bool Item_field::register_field_in_read_map(unsigned char *arg)
111
Table *table= (Table *) arg;
112
if (field->getTable() == table || !table)
113
field->getTable()->setReadSet(field->position());
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)
126
field_name and table_name should not point to garbage
127
if this item is to be reused
129
orig_table_name= orig_field_name= "";
134
Constructor used inside setup_wild().
136
Ensures that field, table, and database names will live as long as
137
Item_field (this is important in prepared statements).
140
Item_field::Item_field(Session *,
141
Name_resolution_context *context_arg,
143
Item_ident(context_arg,
144
f->getTable()->getShare()->getSchemaName(),
145
f->getTable()->getAlias(),
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),
167
Select_Lex *select= getSession().lex().current_select;
168
collation.set(DERIVATION_IMPLICIT);
170
if (select && select->parsing_place != IN_HAVING)
171
select->select_n_where_fields++;
175
Constructor need to process subselect with temporary tables (see Item)
178
Item_field::Item_field(Session *session, Item_field *item) :
179
Item_ident(session, item),
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)
187
collation.set(DERIVATION_IMPLICIT);
190
void Item_field::set_field(Field *field_par)
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());
207
Reset this item to point to a field from the new temporary table.
208
This is used when we create a new temporary table for each execution
209
of prepared statement.
212
void Item_field::reset_field(Field *f)
215
/* 'name' is pointing at field->field_name of old field */
220
String *Item_field::val_str(String *str)
223
if ((null_value=field->is_null()))
225
str->set_charset(str_value.charset());
226
return field->val_str(str,&str_value);
230
double Item_field::val_real()
233
if ((null_value=field->is_null()))
235
return field->val_real();
239
int64_t Item_field::val_int()
242
if ((null_value=field->is_null()))
244
return field->val_int();
248
type::Decimal *Item_field::val_decimal(type::Decimal *decimal_value)
250
if ((null_value= field->is_null()))
252
return field->val_decimal(decimal_value);
256
String *Item_field::str_result(String *str)
258
if ((null_value=result_field->is_null()))
260
str->set_charset(str_value.charset());
261
return result_field->val_str(str,&str_value);
264
bool Item_field::get_date(type::Time <ime,uint32_t fuzzydate)
266
if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
274
bool Item_field::get_date_result(type::Time <ime,uint32_t fuzzydate)
276
if ((null_value=result_field->is_null()) ||
277
result_field->get_date(ltime,fuzzydate))
285
bool Item_field::get_time(type::Time <ime)
287
if ((null_value=field->is_null()) || field->get_time(ltime))
295
double Item_field::val_result()
297
if ((null_value=result_field->is_null()))
299
return result_field->val_real();
302
int64_t Item_field::val_int_result()
304
if ((null_value=result_field->is_null()))
306
return result_field->val_int();
310
type::Decimal *Item_field::val_decimal_result(type::Decimal *decimal_value)
312
if ((null_value= result_field->is_null()))
314
return result_field->val_decimal(decimal_value);
318
bool Item_field::val_bool_result()
320
if ((null_value= result_field->is_null()))
325
switch (result_field->result_type())
328
return result_field->val_int() != 0;
332
type::Decimal decimal_value;
333
type::Decimal *val= result_field->val_decimal(&decimal_value);
335
return not val->isZero();
341
return result_field->val_real() != 0.0;
353
bool Item_field::eq(const Item *item, bool) const
355
const Item *item_ptr= item->real_item();
356
if (item_ptr->type() != FIELD_ITEM)
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;
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
372
return (not my_strcasecmp(system_charset_info, item_field->name, field_name) &&
373
(not item_field->table_name || not table_name ||
374
(not my_strcasecmp(table_alias_charset, item_field->table_name, table_name) &&
375
(not item_field->db_name || not db_name ||
376
(item_field->db_name && not my_strcasecmp(system_charset_info, item_field->db_name, db_name))))));
380
table_map Item_field::used_tables() const
382
if (field->getTable()->const_table)
384
return 0; // const item
387
return depended_from ? OUTER_REF_TABLE_BIT : field->getTable()->map;
390
enum Item_result Item_field::result_type () const
392
return field->result_type();
396
Item_result Item_field::cast_to_int_type() const
398
return field->cast_to_int_type();
402
enum_field_types Item_field::field_type() const
404
return field->type();
408
void Item_field::fix_after_pullout(Select_Lex *new_parent, Item **)
410
if (new_parent == depended_from)
412
Name_resolution_context *ctx= new Name_resolution_context();
413
ctx->outer_context= NULL; // We don't build a complete name resolver
414
ctx->select_lex= new_parent;
415
ctx->first_name_resolution_table= context->first_name_resolution_table;
416
ctx->last_name_resolution_table= context->last_name_resolution_table;
421
bool Item_field::is_null()
423
return field->is_null();
427
Item *Item_field::get_tmp_table_item(Session *session)
429
Item_field *new_item= new Item_field(session, this);
430
new_item->field= new_item->result_field;
434
int64_t Item_field::val_int_endpoint(bool, bool *)
436
int64_t res= val_int();
437
return null_value? INT64_MIN : res;
442
Resolve the name of an outer select column reference.
444
The method resolves the column reference represented by 'this' as a column
445
present in outer selects that contain current select.
447
In prepared statements, because of cache, find_field_in_tables()
448
can resolve fields even if they don't belong to current context.
449
In this case this method only finds appropriate context and marks
450
current select as dependent. The found reference of field should be
451
provided in 'from_field'.
453
@param[in] session current thread
454
@param[in,out] from_field found field reference or (Field*)not_found_field
455
@param[in,out] reference view column if this item was resolved to a
459
This is the inner loop of Item_field::fix_fields:
461
for each outer query Q_k beginning from the inner-most one
463
search for a column or derived column named col_ref_i
464
[in table T_j] in the FROM clause of Q_k;
466
if such a column is not found
467
Search for a column or derived column named col_ref_i
468
[in table T_j] in the SELECT and GROUP clauses of Q_k.
473
1 column succefully resolved and fix_fields() should continue.
475
0 column fully fixed and fix_fields() should return false
481
Item_field::fix_outer_field(Session *session, Field **from_field, Item **reference)
483
enum_parsing_place place= NO_MATTER;
484
bool field_found= (*from_field != not_found_field);
485
bool upward_lookup= false;
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
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.
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 !=
504
outer_context= context->outer_context;
507
outer_context= outer_context->outer_context)
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;
515
place= prev_subselect_item->parsing_place;
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.
520
if (field_found && outer_context->select_lex !=
521
cached_table->select_lex)
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.
528
if (field_found || (*from_field= find_field_in_tables(session, this,
530
first_name_resolution_table,
532
last_name_resolution_table,
534
IGNORE_EXCEPT_NON_UNIQUE,
540
if (*from_field != view_ref_found)
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))
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.
558
Item_outer_ref* rf= new Item_outer_ref(context, this);
560
select->inner_refs_list.push_back(rf);
561
rf->in_sum_func= session->lex().in_sum_func;
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.
568
if (session->lex().in_sum_func &&
569
session->lex().in_sum_func->nest_level >= select->nest_level)
571
Item::Type ref_type= (*reference)->type();
572
set_if_bigger(session->lex().in_sum_func->max_arg_level,
574
set_field(*from_field);
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));
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));
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.
603
/* Search in SELECT and GROUP lists of the outer select. */
604
if (place != IN_WHERE && place != IN_ON)
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)
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();
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)
622
prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
623
prev_subselect_item->const_item_cache= false;
629
if (ref == not_found_item && *from_field == not_found_field)
633
// We can't say exactly what absent table or field
634
my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), session->where());
638
/* Call find_field_in_tables only to report the error */
639
find_field_in_tables(session, this,
640
context->first_name_resolution_table,
641
context->last_name_resolution_table,
642
reference, REPORT_ALL_ERRORS, true);
646
else if (ref != not_found_item)
648
/* Should have been checked in resolve_ref_in_select_and_group(). */
649
assert(*ref && (*ref)->fixed);
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
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)));
667
if (place != IN_HAVING && select->group_list.elements)
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;
674
rf is Item_ref => never substitute other items (in this case)
675
during fix_fields() => we can use rf after fix_fields()
677
assert(!rf->fixed); // Assured by Item_ref()
678
if (rf->fix_fields(session, reference) || rf->check_cols(1))
681
mark_as_dependent(session, last_checked_context->select_lex, context->select_lex, this, rf);
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)
689
Item_ref* rf= new Item_ref(context, (cached_table->getSchemaName()[0] ? cached_table->getSchemaName() : 0), cached_table->alias, field_name);
692
rf is Item_ref => never substitute other items (in this case)
693
during fix_fields() => we can use rf after fix_fields()
695
assert(!rf->fixed); // Assured by Item_ref()
696
if (rf->fix_fields(session, reference) || rf->check_cols(1))
706
Resolve the name of a column reference.
708
The method resolves the column reference represented by 'this' as a column
709
present in one of: FROM clause, SELECT clause, GROUP BY clause of a query
710
Q, or in outer queries that contain Q.
712
The name resolution algorithm used is (where [T_j] is an optional table
713
name that qualifies the column name):
716
resolve_column_reference([T_j].col_ref_i)
718
search for a column or derived column named col_ref_i
719
[in table T_j] in the FROM clause of Q;
721
if such a column is NOT found AND // Lookup in outer queries.
722
there are outer queries
724
for each outer query Q_k beginning from the inner-most one
726
search for a column or derived column named col_ref_i
727
[in table T_j] in the FROM clause of Q_k;
729
if such a column is not found
730
Search for a column or derived column named col_ref_i
731
[in table T_j] in the SELECT and GROUP clauses of Q_k.
737
Notice that compared to Item_ref::fix_fields, here we first search the FROM
738
clause, and then we search the SELECT and GROUP BY clauses.
740
@param[in] session current thread
741
@param[in,out] reference view column if this item was resolved to a
750
bool Item_field::fix_fields(Session *session, Item **reference)
753
Field *from_field= (Field *)not_found_field;
754
bool outer_fixed= false;
756
if (!field) // If field is not checked
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
763
if ((from_field= find_field_in_tables(session, this,
764
context->first_name_resolution_table,
765
context->last_name_resolution_table,
767
session->lex().use_only_table_context ?
769
IGNORE_EXCEPT_NON_UNIQUE, true)) ==
773
/* Look up in current select's item_list to find aliased fields */
774
if (session->lex().current_select->is_item_list_lookup)
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,
784
if (resolution == RESOLVED_AGAINST_ALIAS)
785
alias_name_used= true;
786
if (res != (Item **)not_found_item)
788
if ((*res)->type() == Item::FIELD_ITEM)
791
It's an Item_field referencing another Item_field in the select
793
Use the field from the Item_field in the select list and leave
794
the Item_field instance in place.
797
Field *new_field= (*((Item_field**)res))->field;
799
if (new_field == NULL)
801
/* The column to which we link isn't valid. */
802
my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name,
807
set_field(new_field);
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.
817
Item_ref *rf= new Item_ref(context, db_name,table_name,field_name);
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()
824
return rf->fix_fields(session, reference) || rf->check_cols(1);
828
if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
832
goto mark_non_agg_field;
834
else if (!from_field)
837
if (!outer_fixed && cached_table && cached_table->select_lex &&
838
context->select_lex &&
839
cached_table->select_lex != context->select_lex)
842
if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
846
goto mark_non_agg_field;
850
if it is not expression from merged VIEW we will set this field.
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.
859
Also we suppose that view can't be changed during PS/SP life.
861
if (from_field == view_ref_found)
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)
869
set_if_bigger(session->lex().in_sum_func->max_arg_level,
870
session->lex().current_select->nest_level);
873
else if (session->mark_used_columns != MARK_COLUMNS_NONE)
875
Table *table= field->getTable();
876
boost::dynamic_bitset<> *current_bitmap, *other_bitmap;
877
if (session->mark_used_columns == MARK_COLUMNS_READ)
879
current_bitmap= table->read_set;
880
other_bitmap= table->write_set;
884
current_bitmap= table->write_set;
885
other_bitmap= table->read_set;
887
//if (! current_bitmap->testAndSet(field->position()))
888
if (! current_bitmap->test(field->position()))
890
if (! other_bitmap->test(field->position()))
892
/* First usage of column */
893
table->used_fields++; // Used to optimize loops
894
table->covering_keys&= field->part_of_key;
903
Item *Item_field::safe_charset_converter(const charset_info_st * const tocs)
906
return Item::safe_charset_converter(tocs);
910
void Item_field::cleanup()
912
Item_ident::cleanup();
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'.
918
field= result_field= 0;
923
bool Item_field::result_as_int64_t()
925
return field->can_be_compared_as_int64_t();
930
Find a field among specified multiple equalities.
932
The function first searches the field among multiple equalities
933
of the current level (in the cond_equal->current_level list).
934
If it fails, it continues searching in upper levels accessed
935
through a pointer cond_equal->upper_levels.
936
The search terminates as soon as a multiple equality containing
939
@param cond_equal reference to list of multiple equalities where
940
the field (this object) is to be looked for
943
- First Item_equal containing the field, if success
947
Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
951
List<Item_equal>::iterator li(cond_equal->current_level.begin());
952
while (Item_equal* item= li++)
954
if (item->contains(field))
958
The field is not found in any of the multiple equalities
959
of the current level. Look for it in upper levels
961
cond_equal= cond_equal->upper_levels;
968
Check whether a field can be substituted by an equal item.
970
The function checks whether a substitution of the field
971
occurrence for an equal item is valid.
973
@param arg *arg != NULL <-> the field is in the context where
974
substitution for an equal item is valid
977
The following statement is not always true:
981
This means substitution of an item for an equal item not always
982
yields an equavalent condition. Here's an example:
985
(LENGTH('a')=1) != (LENGTH('a ')=2)
987
Such a substitution is surely valid if either the substituted
988
field is not of a STRING type or if it is an argument of
989
a comparison predicate.
992
true substitution is valid
997
bool Item_field::subst_argument_checker(unsigned char **arg)
999
return (result_type() != STRING_RESULT) || (*arg);
1004
Set a pointer to the multiple equality the field reference belongs to
1007
The function looks for a multiple equality containing the field item
1008
among those referenced by arg.
1009
In the case such equality exists the function does the following.
1010
If the found multiple equality contains a constant, then the field
1011
reference is substituted for this constant, otherwise it sets a pointer
1012
to the multiple equality in the field item.
1015
@param arg reference to list of multiple equalities where
1016
the field (this object) is to be looked for
1019
This function is supposed to be called as a callback parameter in calls
1020
of the compile method.
1023
- pointer to the replacing constant item, if the field item was substituted
1024
- pointer to the field item, otherwise.
1027
Item *Item_field::equal_fields_propagator(unsigned char *arg)
1031
item_equal= find_item_equal((COND_EQUAL *) arg);
1034
item= item_equal->get_const();
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.
1047
(cmp_context != (Item_result)-1 && item->cmp_context != cmp_context))
1055
Mark the item to not be part of substitution if it's not a binary item.
1057
See comments in Arg_comparator::set_compare_func() for details.
1060
bool Item_field::set_no_const_sub(unsigned char *)
1062
if (field->charset() != &my_charset_bin)
1069
Replace an Item_field for an equal Item_field that evaluated earlier
1072
The function returns a pointer to an item that is taken from
1073
the very beginning of the item_equal list which the Item_field
1074
object refers to (belongs to) unless item_equal contains a constant
1075
item. In this case the function returns this constant item,
1076
(if the substitution does not require conversion).
1077
If the Item_field object does not refer any Item_equal object
1078
'this' is returned .
1080
@param arg a dummy parameter, is not used here
1084
This function is supposed to be called as a callback parameter in calls
1085
of the thransformer method.
1088
- pointer to a replacement Item_field if there is a better equal item or
1089
a pointer to a constant equal item;
1093
Item *Item_field::replace_equal_field(unsigned char *)
1097
Item *const_item_ptr= item_equal->get_const();
1100
if (cmp_context != (Item_result)-1 &&
1101
const_item_ptr->cmp_context != cmp_context)
1103
return const_item_ptr;
1105
Item_field *subst= item_equal->get_first();
1106
if (subst && !field->eq(subst->field))
1113
uint32_t Item_field::max_disp_length()
1115
return field->max_display_length();
1120
void Item_field::make_field(SendField *tmp_field)
1122
field->make_field(tmp_field);
1123
assert(tmp_field->table_name != 0);
1125
tmp_field->col_name=name; // Use user supplied name
1127
tmp_field->table_name= table_name;
1129
tmp_field->db_name= db_name;
1134
Set a field's value from a item.
1137
void Item_field::save_org_in_field(Field *to)
1139
if (field->is_null())
1142
set_field_to_null_with_conversions(to, 1);
1147
field_conv(to,field);
1152
int Item_field::save_in_field(Field *to, bool no_conversions)
1155
if (result_field->is_null())
1158
res= set_field_to_null_with_conversions(to, no_conversions);
1163
res= field_conv(to,result_field);
1170
void Item_field::send(plugin::Client *client, String *)
1172
client->store(result_field);
1176
void Item_field::update_null_value()
1179
need to set no_errors to prevent warnings about type conversion
1182
Session *session= field->getTable()->in_use;
1183
int no_errors= session->no_errors;
1184
session->no_errors= 1;
1185
Item::update_null_value();
1186
session->no_errors= no_errors;
1191
Add the field to the select list and substitute it for the reference to
1195
Item_field::update_value_transformer()
1196
select_arg current select
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
1208
ref if all conditions are met
1209
this field otherwise
1212
Item *Item_field::update_value_transformer(unsigned char *select_arg)
1214
Select_Lex *select= (Select_Lex*)select_arg;
1217
if (field->getTable() != select->context.table_list->table)
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);
1231
void Item_field::print(String *str)
1233
if (field && field->getTable()->const_table)
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("NULL");
1248
Item_ident::print(str);
1252
} /* namespace drizzled */