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
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
20
#include <drizzled/server_includes.h>
22
#include <drizzled/session.h>
23
#include <drizzled/table.h>
24
#include <drizzled/error.h>
25
#include <drizzled/virtual_column_info.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>
33
Store the pointer to this item field into a list if not already there.
35
The method is used by Item::walk to collect all unique Item_field objects
36
from a tree of Items into a set of items represented as a list.
38
Item_cond::walk() and Item_func::walk() stop the evaluation of the
39
processor function for its arguments once the processor returns
40
true.Therefore in order to force this method being called for all item
41
arguments in a condition the method must return false.
43
@param arg pointer to a List<Item_field>
46
false to force the evaluation of collect_item_field_processor
47
for the subsequent items.
50
bool Item_field::collect_item_field_processor(unsigned char *arg)
52
List<Item_field> *item_list= (List<Item_field>*) arg;
53
List_iterator<Item_field> item_list_it(*item_list);
54
Item_field *curr_item;
55
while ((curr_item= item_list_it++))
57
if (curr_item->eq(this, 1))
58
return(false); /* Already in the set. */
60
item_list->push_back(this);
66
Check if an Item_field references some field from a list of fields.
68
Check whether the Item_field represented by 'this' references any
69
of the fields in the keyparts passed via 'arg'. Used with the
70
method Item::walk() to test whether any keypart in a sequence of
71
keyparts is referenced in an expression.
73
@param arg Field being compared, arg must be of type Field
76
true if 'this' references the field 'arg'
81
bool Item_field::find_item_in_field_list_processor(unsigned char *arg)
83
KEY_PART_INFO *first_non_group_part= *((KEY_PART_INFO **) arg);
84
KEY_PART_INFO *last_part= *(((KEY_PART_INFO **) arg) + 1);
85
KEY_PART_INFO *cur_part;
87
for (cur_part= first_non_group_part; cur_part != last_part; cur_part++)
89
if (field->eq(cur_part->field))
97
Mark field in read_map
100
This is used by filesort to register used fields in a a temporary
101
column read set or to register used fields in a view
104
bool Item_field::register_field_in_read_map(unsigned char *arg)
106
Table *table= (Table *) arg;
107
if (field->table == table || !table)
108
bitmap_set_bit(field->table->read_set, field->field_index);
109
if (field->vcol_info && field->vcol_info->expr_item)
110
return field->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
116
Mark field in bitmap supplied as *arg
120
bool Item_field::register_field_in_bitmap(unsigned char *arg)
122
MY_BITMAP *bitmap= (MY_BITMAP *) arg;
124
bitmap_set_bit(bitmap, field->field_index);
128
Item_field *Item::filed_for_view_update()
133
Item_field::Item_field(Field *f)
134
:Item_ident(0, NULL, *f->table_name, f->field_name),
135
item_equal(0), no_const_subst(0),
136
have_privileges(0), any_privileges(0)
140
field_name and table_name should not point to garbage
141
if this item is to be reused
143
orig_table_name= orig_field_name= "";
148
Constructor used inside setup_wild().
150
Ensures that field, table, and database names will live as long as
151
Item_field (this is important in prepared statements).
154
Item_field::Item_field(Session *, Name_resolution_context *context_arg,
156
:Item_ident(context_arg, f->table->s->db.str, *f->table_name, f->field_name),
157
item_equal(0), no_const_subst(0),
158
have_privileges(0), any_privileges(0)
164
Item_field::Item_field(Name_resolution_context *context_arg,
165
const char *db_arg,const char *table_name_arg,
166
const char *field_name_arg)
167
:Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
168
field(0), result_field(0), item_equal(0), no_const_subst(0),
169
have_privileges(0), any_privileges(0)
171
SELECT_LEX *select= current_session->lex->current_select;
172
collation.set(DERIVATION_IMPLICIT);
173
if (select && select->parsing_place != IN_HAVING)
174
select->select_n_where_fields++;
178
Constructor need to process subselect with temporary tables (see Item)
181
Item_field::Item_field(Session *session, Item_field *item)
182
:Item_ident(session, item),
184
result_field(item->result_field),
185
item_equal(item->item_equal),
186
no_const_subst(item->no_const_subst),
187
have_privileges(item->have_privileges),
188
any_privileges(item->any_privileges)
190
collation.set(DERIVATION_IMPLICIT);
193
void Item_field::set_field(Field *field_par)
195
field=result_field=field_par; // for easy coding with fields
196
maybe_null=field->maybe_null();
197
decimals= field->decimals();
198
max_length= field_par->max_display_length();
199
table_name= *field_par->table_name;
200
field_name= field_par->field_name;
201
db_name= field_par->table->s->db.str;
202
alias_name_used= field_par->table->alias_name_used;
203
unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
204
collation.set(field_par->charset(), field_par->derivation());
206
if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
212
Reset this item to point to a field from the new temporary table.
213
This is used when we create a new temporary table for each execution
214
of prepared statement.
217
void Item_field::reset_field(Field *f)
220
/* 'name' is pointing at field->field_name of old field */
221
name= (char*) f->field_name;
225
String *Item_field::val_str(String *str)
228
if ((null_value=field->is_null()))
230
str->set_charset(str_value.charset());
231
return field->val_str(str,&str_value);
235
double Item_field::val_real()
238
if ((null_value=field->is_null()))
240
return field->val_real();
244
int64_t Item_field::val_int()
247
if ((null_value=field->is_null()))
249
return field->val_int();
253
my_decimal *Item_field::val_decimal(my_decimal *decimal_value)
255
if ((null_value= field->is_null()))
257
return field->val_decimal(decimal_value);
261
String *Item_field::str_result(String *str)
263
if ((null_value=result_field->is_null()))
265
str->set_charset(str_value.charset());
266
return result_field->val_str(str,&str_value);
269
bool Item_field::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
271
if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
273
memset(ltime, 0, sizeof(*ltime));
279
bool Item_field::get_date_result(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
281
if ((null_value=result_field->is_null()) ||
282
result_field->get_date(ltime,fuzzydate))
284
memset(ltime, 0, sizeof(*ltime));
290
bool Item_field::get_time(DRIZZLE_TIME *ltime)
292
if ((null_value=field->is_null()) || field->get_time(ltime))
294
memset(ltime, 0, sizeof(*ltime));
300
double Item_field::val_result()
302
if ((null_value=result_field->is_null()))
304
return result_field->val_real();
307
int64_t Item_field::val_int_result()
309
if ((null_value=result_field->is_null()))
311
return result_field->val_int();
315
my_decimal *Item_field::val_decimal_result(my_decimal *decimal_value)
317
if ((null_value= result_field->is_null()))
319
return result_field->val_decimal(decimal_value);
323
bool Item_field::val_bool_result()
325
if ((null_value= result_field->is_null()))
327
switch (result_field->result_type()) {
329
return result_field->val_int() != 0;
332
my_decimal decimal_value;
333
my_decimal *val= result_field->val_decimal(&decimal_value);
335
return !my_decimal_is_zero(val);
340
return result_field->val_real() != 0.0;
344
return 0; // Shut up compiler
349
bool Item_field::eq(const Item *item, bool) const
351
Item *real_item= ((Item *) item)->real_item();
352
if (real_item->type() != FIELD_ITEM)
355
Item_field *item_field= (Item_field*) real_item;
356
if (item_field->field && field)
357
return item_field->field == field;
359
We may come here when we are trying to find a function in a GROUP BY
360
clause from the select list.
361
In this case the '100 % correct' way to do this would be to first
362
run fix_fields() on the GROUP BY item and then retry this function, but
363
I think it's better to relax the checking a bit as we will in
364
most cases do the correct thing by just checking the field name.
365
(In cases where we would choose wrong we would have to generate a
368
return (!my_strcasecmp(system_charset_info, item_field->name,
370
(!item_field->table_name || !table_name ||
371
(!my_strcasecmp(table_alias_charset, item_field->table_name,
373
(!item_field->db_name || !db_name ||
374
(item_field->db_name && !strcmp(item_field->db_name,
379
table_map Item_field::used_tables() const
381
if (field->table->const_table)
382
return 0; // const item
383
return (depended_from ? OUTER_REF_TABLE_BIT : field->table->map);
386
enum Item_result Item_field::result_type () const
388
return field->result_type();
392
Item_result Item_field::cast_to_int_type() const
394
return field->cast_to_int_type();
398
enum_field_types Item_field::field_type() const
400
return field->type();
404
void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **)
406
if (new_parent == depended_from)
408
Name_resolution_context *ctx= new Name_resolution_context();
409
ctx->outer_context= NULL; // We don't build a complete name resolver
410
ctx->select_lex= new_parent;
411
ctx->first_name_resolution_table= context->first_name_resolution_table;
412
ctx->last_name_resolution_table= context->last_name_resolution_table;
417
bool Item_field::is_null()
419
return field->is_null();
423
Item *Item_field::get_tmp_table_item(Session *session)
425
Item_field *new_item= new Item_field(session, this);
427
new_item->field= new_item->result_field;
431
int64_t Item_field::val_int_endpoint(bool, bool *)
433
int64_t res= val_int();
434
return null_value? INT64_MIN : res;
439
Resolve the name of an outer select column reference.
441
The method resolves the column reference represented by 'this' as a column
442
present in outer selects that contain current select.
444
In prepared statements, because of cache, find_field_in_tables()
445
can resolve fields even if they don't belong to current context.
446
In this case this method only finds appropriate context and marks
447
current select as dependent. The found reference of field should be
448
provided in 'from_field'.
450
@param[in] session current thread
451
@param[in,out] from_field found field reference or (Field*)not_found_field
452
@param[in,out] reference view column if this item was resolved to a
456
This is the inner loop of Item_field::fix_fields:
458
for each outer query Q_k beginning from the inner-most one
460
search for a column or derived column named col_ref_i
461
[in table T_j] in the FROM clause of Q_k;
463
if such a column is not found
464
Search for a column or derived column named col_ref_i
465
[in table T_j] in the SELECT and GROUP clauses of Q_k.
470
1 column succefully resolved and fix_fields() should continue.
472
0 column fully fixed and fix_fields() should return false
478
Item_field::fix_outer_field(Session *session, Field **from_field, Item **reference)
480
enum_parsing_place place= NO_MATTER;
481
bool field_found= (*from_field != not_found_field);
482
bool upward_lookup= false;
485
If there are outer contexts (outer selects, but current select is
486
not derived table or view) try to resolve this reference in the
489
We treat each subselect as a separate namespace, so that different
490
subselects may contain columns with the same names. The subselects
491
are searched starting from the innermost.
493
Name_resolution_context *last_checked_context= context;
494
Item **ref= (Item **) not_found_item;
495
SELECT_LEX *current_sel= (SELECT_LEX *) session->lex->current_select;
496
Name_resolution_context *outer_context= 0;
497
SELECT_LEX *select= 0;
498
/* Currently derived tables cannot be correlated */
499
if (current_sel->master_unit()->first_select()->linkage !=
501
outer_context= context->outer_context;
504
outer_context= outer_context->outer_context)
506
select= outer_context->select_lex;
507
Item_subselect *prev_subselect_item=
508
last_checked_context->select_lex->master_unit()->item;
509
last_checked_context= outer_context;
512
place= prev_subselect_item->parsing_place;
514
If outer_field is set, field was already found by first call
515
to find_field_in_tables(). Only need to find appropriate context.
517
if (field_found && outer_context->select_lex !=
518
cached_table->select_lex)
521
In case of a view, find_field_in_tables() writes the pointer to
522
the found view field into '*reference', in other words, it
523
substitutes this Item_field with the found expression.
525
if (field_found || (*from_field= find_field_in_tables(session, this,
527
first_name_resolution_table,
529
last_name_resolution_table,
531
IGNORE_EXCEPT_NON_UNIQUE,
537
if (*from_field != view_ref_found)
539
prev_subselect_item->used_tables_cache|= (*from_field)->table->map;
540
prev_subselect_item->const_item_cache= 0;
541
set_field(*from_field);
542
if (!last_checked_context->select_lex->having_fix_field &&
543
select->group_list.elements &&
544
(place == SELECT_LIST || place == IN_HAVING))
548
If an outer field is resolved in a grouping select then it
549
is replaced for an Item_outer_ref object. Otherwise an
550
Item_field object is used.
551
The new Item_outer_ref object is saved in the inner_refs_list of
552
the outer select. Here it is only created. It can be fixed only
553
after the original field has been fixed and this is done in the
554
fix_inner_refs() function.
557
if (!(rf= new Item_outer_ref(context, this)))
559
session->change_item_tree(reference, rf);
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|=
588
(*reference)->used_tables();
589
prev_subselect_item->const_item_cache&=
590
(*reference)->const_item();
591
mark_as_dependent(session, last_checked_context->select_lex,
592
context->select_lex, this,
593
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
594
(Item_ident*) (*reference) :
597
A reference to a view field had been found and we
598
substituted it instead of this Item (find_field_in_tables
599
does it by assigning the new value to *reference), so now
600
we can return from this function.
608
/* Search in SELECT and GROUP lists of the outer select. */
609
if (place != IN_WHERE && place != IN_ON)
611
if (!(ref= resolve_ref_in_select_and_group(session, this, select)))
612
return -1; /* Some error occurred (e.g. ambiguous names). */
613
if (ref != not_found_item)
615
assert(*ref && (*ref)->fixed);
616
prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
617
prev_subselect_item->const_item_cache&= (*ref)->const_item();
623
Reference is not found in this select => this subquery depend on
624
outer select (or we just trying to find wrong identifier, in this
625
case it does not matter which used tables bits we set)
627
prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
628
prev_subselect_item->const_item_cache= 0;
634
if (ref == not_found_item && *from_field == not_found_field)
638
// We can't say exactly what absent table or field
639
my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), session->where);
643
/* Call find_field_in_tables only to report the error */
644
find_field_in_tables(session, this,
645
context->first_name_resolution_table,
646
context->last_name_resolution_table,
647
reference, REPORT_ALL_ERRORS,
653
else if (ref != not_found_item)
658
/* Should have been checked in resolve_ref_in_select_and_group(). */
659
assert(*ref && (*ref)->fixed);
661
Here, a subset of actions performed by Item_ref::set_properties
662
is not enough. So we pass ptr to NULL into Item_[direct]_ref
663
constructor, so no initialization is performed, and call
667
*ref= NULL; // Don't call set_properties()
668
rf= (place == IN_HAVING ?
669
new Item_ref(context, ref, (char*) table_name,
670
(char*) field_name, alias_name_used) :
671
(!select->group_list.elements ?
672
new Item_direct_ref(context, ref, (char*) table_name,
673
(char*) field_name, alias_name_used) :
674
new Item_outer_ref(context, ref, (char*) table_name,
675
(char*) field_name, alias_name_used)));
680
if (place != IN_HAVING && select->group_list.elements)
682
outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf);
683
((Item_outer_ref*)rf)->in_sum_func= session->lex->in_sum_func;
685
session->change_item_tree(reference, rf);
687
rf is Item_ref => never substitute other items (in this case)
688
during fix_fields() => we can use rf after fix_fields()
690
assert(!rf->fixed); // Assured by Item_ref()
691
if (rf->fix_fields(session, reference) || rf->check_cols(1))
694
mark_as_dependent(session, last_checked_context->select_lex,
695
context->select_lex, this,
701
mark_as_dependent(session, last_checked_context->select_lex,
703
this, (Item_ident*)*reference);
704
if (last_checked_context->select_lex->having_fix_field)
707
rf= new Item_ref(context,
708
(cached_table->db[0] ? cached_table->db : 0),
709
(char*) cached_table->alias, (char*) field_name);
712
session->change_item_tree(reference, rf);
714
rf is Item_ref => never substitute other items (in this case)
715
during fix_fields() => we can use rf after fix_fields()
717
assert(!rf->fixed); // Assured by Item_ref()
718
if (rf->fix_fields(session, reference) || rf->check_cols(1))
728
Resolve the name of a column reference.
730
The method resolves the column reference represented by 'this' as a column
731
present in one of: FROM clause, SELECT clause, GROUP BY clause of a query
732
Q, or in outer queries that contain Q.
734
The name resolution algorithm used is (where [T_j] is an optional table
735
name that qualifies the column name):
738
resolve_column_reference([T_j].col_ref_i)
740
search for a column or derived column named col_ref_i
741
[in table T_j] in the FROM clause of Q;
743
if such a column is NOT found AND // Lookup in outer queries.
744
there are outer queries
746
for each outer query Q_k beginning from the inner-most one
748
search for a column or derived column named col_ref_i
749
[in table T_j] in the FROM clause of Q_k;
751
if such a column is not found
752
Search for a column or derived column named col_ref_i
753
[in table T_j] in the SELECT and GROUP clauses of Q_k.
759
Notice that compared to Item_ref::fix_fields, here we first search the FROM
760
clause, and then we search the SELECT and GROUP BY clauses.
762
@param[in] session current thread
763
@param[in,out] reference view column if this item was resolved to a
772
bool Item_field::fix_fields(Session *session, Item **reference)
775
Field *from_field= (Field *)not_found_field;
776
bool outer_fixed= false;
778
if (!field) // If field is not checked
781
In case of view, find_field_in_tables() write pointer to view field
782
expression to 'reference', i.e. it substitute that expression instead
785
if ((from_field= find_field_in_tables(session, this,
786
context->first_name_resolution_table,
787
context->last_name_resolution_table,
789
session->lex->use_only_table_context ?
791
IGNORE_EXCEPT_NON_UNIQUE,
797
/* Look up in current select's item_list to find aliased fields */
798
if (session->lex->current_select->is_item_list_lookup)
801
enum_resolution_type resolution;
802
Item** res= find_item_in_list(this, session->lex->current_select->item_list,
803
&counter, REPORT_EXCEPT_NOT_FOUND,
807
if (resolution == RESOLVED_AGAINST_ALIAS)
808
alias_name_used= true;
809
if (res != (Item **)not_found_item)
811
if ((*res)->type() == Item::FIELD_ITEM)
814
It's an Item_field referencing another Item_field in the select
816
Use the field from the Item_field in the select list and leave
817
the Item_field instance in place.
820
Field *new_field= (*((Item_field**)res))->field;
822
if (new_field == NULL)
824
/* The column to which we link isn't valid. */
825
my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name,
826
current_session->where);
830
set_field(new_field);
836
It's not an Item_field in the select list so we must make a new
837
Item_ref to point to the Item in the select list and replace the
838
Item_field created by the parser with the new Item_ref.
840
Item_ref *rf= new Item_ref(context, db_name,table_name,field_name);
843
session->change_item_tree(reference, rf);
845
Because Item_ref never substitutes itself with other items
846
in Item_ref::fix_fields(), we can safely use the original
847
pointer to it even after fix_fields()
849
return rf->fix_fields(session, reference) || rf->check_cols(1);
853
if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
857
goto mark_non_agg_field;
859
else if (!from_field)
862
if (!outer_fixed && cached_table && cached_table->select_lex &&
863
context->select_lex &&
864
cached_table->select_lex != context->select_lex)
867
if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
871
goto mark_non_agg_field;
875
if it is not expression from merged VIEW we will set this field.
877
We can leave expression substituted from view for next PS/SP rexecution
878
(i.e. do not register this substitution for reverting on cleanup()
879
(register_item_tree_changing())), because this subtree will be
880
fix_field'ed during setup_tables()->setup_underlying() (i.e. before
881
all other expressions of query, and references on tables which do
882
not present in query will not make problems.
884
Also we suppose that view can't be changed during PS/SP life.
886
if (from_field == view_ref_found)
889
set_field(from_field);
890
if (session->lex->in_sum_func &&
891
session->lex->in_sum_func->nest_level ==
892
session->lex->current_select->nest_level)
893
set_if_bigger(session->lex->in_sum_func->max_arg_level,
894
session->lex->current_select->nest_level);
896
else if (session->mark_used_columns != MARK_COLUMNS_NONE)
898
Table *table= field->table;
899
MY_BITMAP *current_bitmap, *other_bitmap;
900
if (session->mark_used_columns == MARK_COLUMNS_READ)
902
current_bitmap= table->read_set;
903
other_bitmap= table->write_set;
907
current_bitmap= table->write_set;
908
other_bitmap= table->read_set;
910
if (!bitmap_fast_test_and_set(current_bitmap, field->field_index))
912
if (!bitmap_is_set(other_bitmap, field->field_index))
914
/* First usage of column */
915
table->used_fields++; // Used to optimize loops
916
/* purecov: begin inspected */
917
table->covering_keys.intersect(field->part_of_key);
927
context->process_error(session);
931
Item *Item_field::safe_charset_converter(const CHARSET_INFO * const tocs)
934
return Item::safe_charset_converter(tocs);
938
void Item_field::cleanup()
940
Item_ident::cleanup();
942
Even if this object was created by direct link to field in setup_wild()
943
it will be linked correctly next time by name of field and table alias.
944
I.e. we can drop 'field'.
946
field= result_field= 0;
952
bool Item_field::result_as_int64_t()
954
return field->can_be_compared_as_int64_t();
959
Find a field among specified multiple equalities.
961
The function first searches the field among multiple equalities
962
of the current level (in the cond_equal->current_level list).
963
If it fails, it continues searching in upper levels accessed
964
through a pointer cond_equal->upper_levels.
965
The search terminates as soon as a multiple equality containing
968
@param cond_equal reference to list of multiple equalities where
969
the field (this object) is to be looked for
972
- First Item_equal containing the field, if success
976
Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
981
List_iterator_fast<Item_equal> li(cond_equal->current_level);
984
if (item->contains(field))
988
The field is not found in any of the multiple equalities
989
of the current level. Look for it in upper levels
991
cond_equal= cond_equal->upper_levels;
998
Check whether a field can be substituted by an equal item.
1000
The function checks whether a substitution of the field
1001
occurrence for an equal item is valid.
1003
@param arg *arg != NULL <-> the field is in the context where
1004
substitution for an equal item is valid
1007
The following statement is not always true:
1011
This means substitution of an item for an equal item not always
1012
yields an equavalent condition. Here's an example:
1015
(LENGTH('a')=1) != (LENGTH('a ')=2)
1017
Such a substitution is surely valid if either the substituted
1018
field is not of a STRING type or if it is an argument of
1019
a comparison predicate.
1022
true substitution is valid
1027
bool Item_field::subst_argument_checker(unsigned char **arg)
1029
return (result_type() != STRING_RESULT) || (*arg);
1034
Set a pointer to the multiple equality the field reference belongs to
1037
The function looks for a multiple equality containing the field item
1038
among those referenced by arg.
1039
In the case such equality exists the function does the following.
1040
If the found multiple equality contains a constant, then the field
1041
reference is substituted for this constant, otherwise it sets a pointer
1042
to the multiple equality in the field item.
1045
@param arg reference to list of multiple equalities where
1046
the field (this object) is to be looked for
1049
This function is supposed to be called as a callback parameter in calls
1050
of the compile method.
1053
- pointer to the replacing constant item, if the field item was substituted
1054
- pointer to the field item, otherwise.
1057
Item *Item_field::equal_fields_propagator(unsigned char *arg)
1061
item_equal= find_item_equal((COND_EQUAL *) arg);
1064
item= item_equal->get_const();
1066
Disable const propagation for items used in different comparison contexts.
1067
This must be done because, for example, Item_hex_string->val_int() is not
1068
the same as (Item_hex_string->val_str() in BINARY column)->val_int().
1069
We cannot simply disable the replacement in a particular context (
1070
e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
1071
Items don't know the context they are in and there are functions like
1072
IF (<hex_string>, 'yes', 'no').
1073
The same problem occurs when comparing a DATE/TIME field with a
1074
DATE/TIME represented as an int and as a string.
1077
(cmp_context != (Item_result)-1 && item->cmp_context != cmp_context))
1085
Mark the item to not be part of substitution if it's not a binary item.
1087
See comments in Arg_comparator::set_compare_func() for details.
1090
bool Item_field::set_no_const_sub(unsigned char *)
1092
if (field->charset() != &my_charset_bin)
1099
Replace an Item_field for an equal Item_field that evaluated earlier
1102
The function returns a pointer to an item that is taken from
1103
the very beginning of the item_equal list which the Item_field
1104
object refers to (belongs to) unless item_equal contains a constant
1105
item. In this case the function returns this constant item,
1106
(if the substitution does not require conversion).
1107
If the Item_field object does not refer any Item_equal object
1108
'this' is returned .
1110
@param arg a dummy parameter, is not used here
1114
This function is supposed to be called as a callback parameter in calls
1115
of the thransformer method.
1118
- pointer to a replacement Item_field if there is a better equal item or
1119
a pointer to a constant equal item;
1123
Item *Item_field::replace_equal_field(unsigned char *)
1127
Item *const_item= item_equal->get_const();
1130
if (cmp_context != (Item_result)-1 &&
1131
const_item->cmp_context != cmp_context)
1135
Item_field *subst= item_equal->get_first();
1136
if (subst && !field->eq(subst->field))
1143
uint32_t Item_field::max_disp_length()
1145
return field->max_display_length();
1150
void Item_field::make_field(Send_field *tmp_field)
1152
field->make_field(tmp_field);
1153
assert(tmp_field->table_name != 0);
1155
tmp_field->col_name=name; // Use user supplied name
1157
tmp_field->table_name= table_name;
1159
tmp_field->db_name= db_name;
1164
Set a field's value from a item.
1167
void Item_field::save_org_in_field(Field *to)
1169
if (field->is_null())
1172
set_field_to_null_with_conversions(to, 1);
1177
field_conv(to,field);
1182
int Item_field::save_in_field(Field *to, bool no_conversions)
1185
if (result_field->is_null())
1188
res= set_field_to_null_with_conversions(to, no_conversions);
1193
res= field_conv(to,result_field);
1200
bool Item_field::send(Protocol *protocol, String *)
1202
return protocol->store(result_field);
1206
void Item_field::update_null_value()
1209
need to set no_errors to prevent warnings about type conversion
1212
Session *session= field->table->in_use;
1215
no_errors= session->no_errors;
1216
session->no_errors= 1;
1217
Item::update_null_value();
1218
session->no_errors= no_errors;
1223
Add the field to the select list and substitute it for the reference to
1227
Item_field::update_value_transformer()
1228
select_arg current select
1231
If the field doesn't belong to the table being inserted into then it is
1232
added to the select list, pointer to it is stored in the ref_pointer_array
1233
of the select and the field itself is substituted for the Item_ref object.
1234
This is done in order to get correct values from update fields that
1235
belongs to the SELECT part in the INSERT .. SELECT .. ON DUPLICATE KEY
1240
ref if all conditions are met
1241
this field otherwise
1244
Item *Item_field::update_value_transformer(unsigned char *select_arg)
1246
SELECT_LEX *select= (SELECT_LEX*)select_arg;
1249
if (field->table != select->context.table_list->table)
1251
List<Item> *all_fields= &select->join->all_fields;
1252
Item **ref_pointer_array= select->ref_pointer_array;
1253
int el= all_fields->elements;
1256
ref_pointer_array[el]= (Item*)this;
1257
all_fields->push_front((Item*)this);
1258
ref= new Item_ref(&select->context, ref_pointer_array + el,
1259
table_name, field_name);
1266
void Item_field::print(String *str, enum_query_type query_type)
1268
if (field && field->table->const_table)
1270
char buff[MAX_FIELD_WIDTH];
1271
String tmp(buff,sizeof(buff),str->charset());
1272
field->val_str(&tmp);
1278
Item_ident::print(str, query_type);