~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/field.cc

  • Committer: Monty Taylor
  • Date: 2008-09-16 00:00:48 UTC
  • mto: This revision was merged to the branch mainline in revision 391.
  • Revision ID: monty@inaugust.com-20080916000048-3rvrv3gv9l0ad3gs
Fixed copyright headers in drizzled/

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
33
 
#include <boost/dynamic_bitset.hpp>
34
 
 
35
 
namespace drizzled
36
 
{
37
 
 
38
 
/**
39
 
  Store the pointer to this item field into a list if not already there.
40
 
 
41
 
  The method is used by Item::walk to collect all unique Item_field objects
42
 
  from a tree of Items into a set of items represented as a list.
43
 
 
44
 
  Item_cond::walk() and Item_func::walk() stop the evaluation of the
45
 
  processor function for its arguments once the processor returns
46
 
  true.Therefore in order to force this method being called for all item
47
 
  arguments in a condition the method must return false.
48
 
 
49
 
  @param arg  pointer to a List<Item_field>
50
 
 
51
 
  @return
52
 
    false to force the evaluation of collect_item_field_processor
53
 
    for the subsequent items.
54
 
*/
55
 
 
56
 
bool Item_field::collect_item_field_processor(unsigned char *arg)
57
 
{
58
 
  List<Item_field> *item_list= (List<Item_field>*) arg;
59
 
  List_iterator<Item_field> item_list_it(*item_list);
60
 
  Item_field *curr_item;
61
 
  while ((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
 
 
71
 
/**
72
 
  Check if an Item_field references some field from a list of fields.
73
 
 
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.
78
 
 
79
 
  @param arg   Field being compared, arg must be of type Field
80
 
 
81
 
  @retval
82
 
    true  if 'this' references the field 'arg'
83
 
  @retval
84
 
    false otherwise
85
 
*/
86
 
 
87
 
bool Item_field::find_item_in_field_list_processor(unsigned char *arg)
88
 
{
89
 
  KeyPartInfo *first_non_group_part= *((KeyPartInfo **) arg);
90
 
  KeyPartInfo *last_part= *(((KeyPartInfo **) arg) + 1);
91
 
  KeyPartInfo *cur_part;
92
 
 
93
 
  for (cur_part= first_non_group_part; cur_part != last_part; cur_part++)
94
 
  {
95
 
    if (field->eq(cur_part->field))
96
 
      return true;
97
 
  }
98
 
  return false;
99
 
}
100
 
 
101
 
 
102
 
/*
103
 
  Mark field in read_map
104
 
 
105
 
  NOTES
106
 
    This is used by filesort to register used fields in a a temporary
107
 
    column read set or to register used fields in a view
108
 
*/
109
 
 
110
 
bool Item_field::register_field_in_read_map(unsigned char *arg)
111
 
{
112
 
  Table *table= (Table *) arg;
113
 
  if (field->getTable() == table || !table)
114
 
    field->getTable()->setReadSet(field->position());
115
 
 
116
 
  return 0;
117
 
}
118
 
 
119
 
 
120
 
Item_field::Item_field(Field *f)
121
 
  :Item_ident(0, NULL, f->getTable()->getAlias(), f->field_name),
122
 
   item_equal(0), no_const_subst(0),
123
 
   have_privileges(0), any_privileges(0)
124
 
{
125
 
  set_field(f);
126
 
  /*
127
 
    field_name and table_name should not point to garbage
128
 
    if this item is to be reused
129
 
  */
130
 
  orig_table_name= orig_field_name= "";
131
 
}
132
 
 
133
 
 
134
 
/**
135
 
  Constructor used inside setup_wild().
136
 
 
137
 
  Ensures that field, table, and database names will live as long as
138
 
  Item_field (this is important in prepared statements).
139
 
*/
140
 
 
141
 
Item_field::Item_field(Session *,
142
 
                       Name_resolution_context *context_arg,
143
 
                       Field *f) :
144
 
  Item_ident(context_arg,
145
 
             f->getTable()->getShare()->getSchemaName(),
146
 
             f->getTable()->getAlias(),
147
 
             f->field_name),
148
 
   item_equal(0),
149
 
   no_const_subst(0),
150
 
   have_privileges(0),
151
 
   any_privileges(0)
152
 
{
153
 
  set_field(f);
154
 
}
155
 
 
156
 
 
157
 
Item_field::Item_field(Name_resolution_context *context_arg,
158
 
                       const char *db_arg,const char *table_name_arg,
159
 
                       const char *field_name_arg) :
160
 
  Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
161
 
   field(0),
162
 
   result_field(0),
163
 
   item_equal(0),
164
 
   no_const_subst(0),
165
 
   have_privileges(0),
166
 
   any_privileges(0)
167
 
{
168
 
  Select_Lex *select= getSession().getLex()->current_select;
169
 
  collation.set(DERIVATION_IMPLICIT);
170
 
 
171
 
  if (select && select->parsing_place != IN_HAVING)
172
 
      select->select_n_where_fields++;
173
 
}
174
 
 
175
 
/**
176
 
  Constructor need to process subselect with temporary tables (see Item)
177
 
*/
178
 
 
179
 
Item_field::Item_field(Session *session, Item_field *item) :
180
 
  Item_ident(session, item),
181
 
  field(item->field),
182
 
  result_field(item->result_field),
183
 
  item_equal(item->item_equal),
184
 
  no_const_subst(item->no_const_subst),
185
 
  have_privileges(item->have_privileges),
186
 
  any_privileges(item->any_privileges)
187
 
{
188
 
  collation.set(DERIVATION_IMPLICIT);
189
 
}
190
 
 
191
 
void Item_field::set_field(Field *field_par)
192
 
{
193
 
  field=result_field=field_par;                 // for easy coding with fields
194
 
  maybe_null=field->maybe_null();
195
 
  decimals= field->decimals();
196
 
  max_length= field_par->max_display_length();
197
 
  table_name= field_par->getTable()->getAlias();
198
 
  field_name= field_par->field_name;
199
 
  db_name= field_par->getTable()->getShare()->getSchemaName();
200
 
  alias_name_used= field_par->getTable()->alias_name_used;
201
 
  unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
202
 
  collation.set(field_par->charset(), field_par->derivation());
203
 
  fixed= 1;
204
 
}
205
 
 
206
 
 
207
 
/**
208
 
  Reset this item to point to a field from the new temporary table.
209
 
  This is used when we create a new temporary table for each execution
210
 
  of prepared statement.
211
 
*/
212
 
 
213
 
void Item_field::reset_field(Field *f)
214
 
{
215
 
  set_field(f);
216
 
  /* 'name' is pointing at field->field_name of old field */
217
 
  name= (char*) f->field_name;
218
 
}
219
 
 
220
 
/* ARGSUSED */
221
 
String *Item_field::val_str(String *str)
222
 
{
223
 
  assert(fixed == 1);
224
 
  if ((null_value=field->is_null()))
225
 
    return 0;
226
 
  str->set_charset(str_value.charset());
227
 
  return field->val_str(str,&str_value);
228
 
}
229
 
 
230
 
 
231
 
double Item_field::val_real()
232
 
{
233
 
  assert(fixed == 1);
234
 
  if ((null_value=field->is_null()))
235
 
    return 0.0;
236
 
  return field->val_real();
237
 
}
238
 
 
239
 
 
240
 
int64_t Item_field::val_int()
241
 
{
242
 
  assert(fixed == 1);
243
 
  if ((null_value=field->is_null()))
244
 
    return 0;
245
 
  return field->val_int();
246
 
}
247
 
 
248
 
 
249
 
type::Decimal *Item_field::val_decimal(type::Decimal *decimal_value)
250
 
{
251
 
  if ((null_value= field->is_null()))
252
 
    return 0;
253
 
  return field->val_decimal(decimal_value);
254
 
}
255
 
 
256
 
 
257
 
String *Item_field::str_result(String *str)
258
 
{
259
 
  if ((null_value=result_field->is_null()))
260
 
    return 0;
261
 
  str->set_charset(str_value.charset());
262
 
  return result_field->val_str(str,&str_value);
263
 
}
264
 
 
265
 
bool Item_field::get_date(type::Time &ltime,uint32_t fuzzydate)
266
 
{
267
 
  if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
268
 
  {
269
 
    ltime.reset();
270
 
    return 1;
271
 
  }
272
 
  return 0;
273
 
}
274
 
 
275
 
bool Item_field::get_date_result(type::Time &ltime,uint32_t fuzzydate)
276
 
{
277
 
  if ((null_value=result_field->is_null()) ||
278
 
      result_field->get_date(ltime,fuzzydate))
279
 
  {
280
 
    ltime.reset();
281
 
    return 1;
282
 
  }
283
 
  return 0;
284
 
}
285
 
 
286
 
bool Item_field::get_time(type::Time &ltime)
287
 
{
288
 
  if ((null_value=field->is_null()) || field->get_time(ltime))
289
 
  {
290
 
    ltime.reset();
291
 
    return 1;
292
 
  }
293
 
  return 0;
294
 
}
295
 
 
296
 
double Item_field::val_result()
297
 
{
298
 
  if ((null_value=result_field->is_null()))
299
 
    return 0.0;
300
 
  return result_field->val_real();
301
 
}
302
 
 
303
 
int64_t Item_field::val_int_result()
304
 
{
305
 
  if ((null_value=result_field->is_null()))
306
 
    return 0;
307
 
  return result_field->val_int();
308
 
}
309
 
 
310
 
 
311
 
type::Decimal *Item_field::val_decimal_result(type::Decimal *decimal_value)
312
 
{
313
 
  if ((null_value= result_field->is_null()))
314
 
    return 0;
315
 
  return result_field->val_decimal(decimal_value);
316
 
}
317
 
 
318
 
 
319
 
bool Item_field::val_bool_result()
320
 
{
321
 
  if ((null_value= result_field->is_null()))
322
 
  {
323
 
    return false;
324
 
  }
325
 
 
326
 
  switch (result_field->result_type()) {
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(0);
345
 
    return 0;                                   // Shut up compiler
346
 
  }
347
 
 
348
 
  assert(0);
349
 
  return 0;                                   // Shut up compiler
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 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))))));
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;
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;
417
 
  this->context=ctx;
418
 
}
419
 
 
420
 
 
421
 
bool Item_field::is_null()
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
 
  if (new_item)
431
 
    new_item->field= new_item->result_field;
432
 
  return new_item;
433
 
}
434
 
 
435
 
int64_t Item_field::val_int_endpoint(bool, bool *)
436
 
{
437
 
  int64_t res= val_int();
438
 
  return null_value? INT64_MIN : res;
439
 
}
440
 
 
441
 
 
442
 
/**
443
 
  Resolve the name of an outer select column reference.
444
 
 
445
 
  The method resolves the column reference represented by 'this' as a column
446
 
  present in outer selects that contain current select.
447
 
 
448
 
  In prepared statements, because of cache, find_field_in_tables()
449
 
  can resolve fields even if they don't belong to current context.
450
 
  In this case this method only finds appropriate context and marks
451
 
  current select as dependent. The found reference of field should be
452
 
  provided in 'from_field'.
453
 
 
454
 
  @param[in] session             current thread
455
 
  @param[in,out] from_field  found field reference or (Field*)not_found_field
456
 
  @param[in,out] reference   view column if this item was resolved to a
457
 
    view column
458
 
 
459
 
  @note
460
 
    This is the inner loop of Item_field::fix_fields:
461
 
  @code
462
 
        for each outer query Q_k beginning from the inner-most one
463
 
        {
464
 
          search for a column or derived column named col_ref_i
465
 
          [in table T_j] in the FROM clause of Q_k;
466
 
 
467
 
          if such a column is not found
468
 
            Search for a column or derived column named col_ref_i
469
 
            [in table T_j] in the SELECT and GROUP clauses of Q_k.
470
 
        }
471
 
  @endcode
472
 
 
473
 
  @retval
474
 
    1   column succefully resolved and fix_fields() should continue.
475
 
  @retval
476
 
    0   column fully fixed and fix_fields() should return false
477
 
  @retval
478
 
    -1  error occured
479
 
*/
480
 
 
481
 
int
482
 
Item_field::fix_outer_field(Session *session, Field **from_field, Item **reference)
483
 
{
484
 
  enum_parsing_place place= NO_MATTER;
485
 
  bool field_found= (*from_field != not_found_field);
486
 
  bool upward_lookup= false;
487
 
 
488
 
  /*
489
 
    If there are outer contexts (outer selects, but current select is
490
 
    not derived table or view) try to resolve this reference in the
491
 
    outer contexts.
492
 
 
493
 
    We treat each subselect as a separate namespace, so that different
494
 
    subselects may contain columns with the same names. The subselects
495
 
    are searched starting from the innermost.
496
 
  */
497
 
  Name_resolution_context *last_checked_context= context;
498
 
  Item **ref= (Item **) not_found_item;
499
 
  Select_Lex *current_sel= (Select_Lex *) session->lex->current_select;
500
 
  Name_resolution_context *outer_context= 0;
501
 
  Select_Lex *select= 0;
502
 
  /* Currently derived tables cannot be correlated */
503
 
  if (current_sel->master_unit()->first_select()->linkage !=
504
 
      DERIVED_TABLE_TYPE)
505
 
    outer_context= context->outer_context;
506
 
  for (;
507
 
       outer_context;
508
 
       outer_context= outer_context->outer_context)
509
 
  {
510
 
    select= outer_context->select_lex;
511
 
    Item_subselect *prev_subselect_item=
512
 
      last_checked_context->select_lex->master_unit()->item;
513
 
    last_checked_context= outer_context;
514
 
    upward_lookup= true;
515
 
 
516
 
    place= prev_subselect_item->parsing_place;
517
 
    /*
518
 
      If outer_field is set, field was already found by first call
519
 
      to find_field_in_tables(). Only need to find appropriate context.
520
 
    */
521
 
    if (field_found && outer_context->select_lex !=
522
 
        cached_table->select_lex)
523
 
      continue;
524
 
    /*
525
 
      In case of a view, find_field_in_tables() writes the pointer to
526
 
      the found view field into '*reference', in other words, it
527
 
      substitutes this Item_field with the found expression.
528
 
    */
529
 
    if (field_found || (*from_field= find_field_in_tables(session, this,
530
 
                                          outer_context->
531
 
                                            first_name_resolution_table,
532
 
                                          outer_context->
533
 
                                            last_name_resolution_table,
534
 
                                          reference,
535
 
                                          IGNORE_EXCEPT_NON_UNIQUE,
536
 
                                          true)) !=
537
 
        not_found_field)
538
 
    {
539
 
      if (*from_field)
540
 
      {
541
 
        if (*from_field != view_ref_found)
542
 
        {
543
 
          prev_subselect_item->used_tables_cache|= (*from_field)->getTable()->map;
544
 
          prev_subselect_item->const_item_cache= false;
545
 
          set_field(*from_field);
546
 
          if (!last_checked_context->select_lex->having_fix_field &&
547
 
              select->group_list.elements &&
548
 
              (place == SELECT_LIST || place == IN_HAVING))
549
 
          {
550
 
            Item_outer_ref *rf;
551
 
            /*
552
 
              If an outer field is resolved in a grouping select then it
553
 
              is replaced for an Item_outer_ref object. Otherwise an
554
 
              Item_field object is used.
555
 
              The new Item_outer_ref object is saved in the inner_refs_list of
556
 
              the outer select. Here it is only created. It can be fixed only
557
 
              after the original field has been fixed and this is done in the
558
 
              fix_inner_refs() function.
559
 
            */
560
 
            ;
561
 
            if (!(rf= new Item_outer_ref(context, this)))
562
 
              return -1;
563
 
            session->change_item_tree(reference, rf);
564
 
            select->inner_refs_list.push_back(rf);
565
 
            rf->in_sum_func= session->lex->in_sum_func;
566
 
          }
567
 
          /*
568
 
            A reference is resolved to a nest level that's outer or the same as
569
 
            the nest level of the enclosing set function : adjust the value of
570
 
            max_arg_level for the function if it's needed.
571
 
          */
572
 
          if (session->lex->in_sum_func &&
573
 
              session->lex->in_sum_func->nest_level >= select->nest_level)
574
 
          {
575
 
            Item::Type ref_type= (*reference)->type();
576
 
            set_if_bigger(session->lex->in_sum_func->max_arg_level,
577
 
                          select->nest_level);
578
 
            set_field(*from_field);
579
 
            fixed= 1;
580
 
            mark_as_dependent(session, last_checked_context->select_lex,
581
 
                              context->select_lex, this,
582
 
                              ((ref_type == REF_ITEM ||
583
 
                                ref_type == FIELD_ITEM) ?
584
 
                               (Item_ident*) (*reference) : 0));
585
 
            return 0;
586
 
          }
587
 
        }
588
 
        else
589
 
        {
590
 
          Item::Type ref_type= (*reference)->type();
591
 
          prev_subselect_item->used_tables_cache|=
592
 
            (*reference)->used_tables();
593
 
          prev_subselect_item->const_item_cache&=
594
 
            (*reference)->const_item();
595
 
          mark_as_dependent(session, last_checked_context->select_lex,
596
 
                            context->select_lex, this,
597
 
                            ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
598
 
                             (Item_ident*) (*reference) :
599
 
                             0));
600
 
          /*
601
 
            A reference to a view field had been found and we
602
 
            substituted it instead of this Item (find_field_in_tables
603
 
            does it by assigning the new value to *reference), so now
604
 
            we can return from this function.
605
 
          */
606
 
          return 0;
607
 
        }
608
 
      }
609
 
      break;
610
 
    }
611
 
 
612
 
    /* Search in SELECT and GROUP lists of the outer select. */
613
 
    if (place != IN_WHERE && place != IN_ON)
614
 
    {
615
 
      if (!(ref= resolve_ref_in_select_and_group(session, this, select)))
616
 
        return -1; /* Some error occurred (e.g. ambiguous names). */
617
 
      if (ref != not_found_item)
618
 
      {
619
 
        assert(*ref && (*ref)->fixed);
620
 
        prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
621
 
        prev_subselect_item->const_item_cache&= (*ref)->const_item();
622
 
        break;
623
 
      }
624
 
    }
625
 
 
626
 
    /*
627
 
      Reference is not found in this select => this subquery depend on
628
 
      outer select (or we just trying to find wrong identifier, in this
629
 
      case it does not matter which used tables bits we set)
630
 
    */
631
 
    prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
632
 
    prev_subselect_item->const_item_cache= false;
633
 
  }
634
 
 
635
 
  assert(ref != 0);
636
 
  if (!*from_field)
637
 
    return -1;
638
 
  if (ref == not_found_item && *from_field == not_found_field)
639
 
  {
640
 
    if (upward_lookup)
641
 
    {
642
 
      // We can't say exactly what absent table or field
643
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), session->where());
644
 
    }
645
 
    else
646
 
    {
647
 
      /* Call find_field_in_tables only to report the error */
648
 
      find_field_in_tables(session, this,
649
 
                           context->first_name_resolution_table,
650
 
                           context->last_name_resolution_table,
651
 
                           reference, REPORT_ALL_ERRORS, true);
652
 
    }
653
 
    return -1;
654
 
  }
655
 
  else if (ref != not_found_item)
656
 
  {
657
 
    Item *save;
658
 
    Item_ref *rf;
659
 
 
660
 
    /* Should have been checked in resolve_ref_in_select_and_group(). */
661
 
    assert(*ref && (*ref)->fixed);
662
 
    /*
663
 
      Here, a subset of actions performed by Item_ref::set_properties
664
 
      is not enough. So we pass ptr to NULL into Item_[direct]_ref
665
 
      constructor, so no initialization is performed, and call
666
 
      fix_fields() below.
667
 
    */
668
 
    save= *ref;
669
 
    *ref= NULL;                             // Don't call set_properties()
670
 
    rf= (place == IN_HAVING ?
671
 
         new Item_ref(context, ref, (char*) table_name,
672
 
                      (char*) field_name, alias_name_used) :
673
 
         (!select->group_list.elements ?
674
 
         new Item_direct_ref(context, ref, (char*) table_name,
675
 
                             (char*) field_name, alias_name_used) :
676
 
         new Item_outer_ref(context, ref, (char*) table_name,
677
 
                            (char*) field_name, alias_name_used)));
678
 
    *ref= save;
679
 
    if (!rf)
680
 
      return -1;
681
 
 
682
 
    if (place != IN_HAVING && select->group_list.elements)
683
 
    {
684
 
      outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf);
685
 
      ((Item_outer_ref*)rf)->in_sum_func= session->lex->in_sum_func;
686
 
    }
687
 
    session->change_item_tree(reference, rf);
688
 
    /*
689
 
      rf is Item_ref => never substitute other items (in this case)
690
 
      during fix_fields() => we can use rf after fix_fields()
691
 
    */
692
 
    assert(!rf->fixed);                // Assured by Item_ref()
693
 
    if (rf->fix_fields(session, reference) || rf->check_cols(1))
694
 
      return -1;
695
 
 
696
 
    mark_as_dependent(session, last_checked_context->select_lex,
697
 
                      context->select_lex, this,
698
 
                      rf);
699
 
    return 0;
700
 
  }
701
 
  else
702
 
  {
703
 
    mark_as_dependent(session, last_checked_context->select_lex,
704
 
                      context->select_lex,
705
 
                      this, (Item_ident*)*reference);
706
 
    if (last_checked_context->select_lex->having_fix_field)
707
 
    {
708
 
      Item_ref *rf;
709
 
      rf= new Item_ref(context,
710
 
                       (cached_table->getSchemaName()[0] ? cached_table->getSchemaName() : 0),
711
 
                       (char*) cached_table->alias, (char*) field_name);
712
 
      if (!rf)
713
 
        return -1;
714
 
      session->change_item_tree(reference, rf);
715
 
      /*
716
 
        rf is Item_ref => never substitute other items (in this case)
717
 
        during fix_fields() => we can use rf after fix_fields()
718
 
      */
719
 
      assert(!rf->fixed);                // Assured by Item_ref()
720
 
      if (rf->fix_fields(session, reference) || rf->check_cols(1))
721
 
        return -1;
722
 
      return 0;
723
 
    }
724
 
  }
725
 
  return 1;
726
 
}
727
 
 
728
 
 
729
 
/**
730
 
  Resolve the name of a column reference.
731
 
 
732
 
  The method resolves the column reference represented by 'this' as a column
733
 
  present in one of: FROM clause, SELECT clause, GROUP BY clause of a query
734
 
  Q, or in outer queries that contain Q.
735
 
 
736
 
  The name resolution algorithm used is (where [T_j] is an optional table
737
 
  name that qualifies the column name):
738
 
 
739
 
  @code
740
 
    resolve_column_reference([T_j].col_ref_i)
741
 
    {
742
 
      search for a column or derived column named col_ref_i
743
 
      [in table T_j] in the FROM clause of Q;
744
 
 
745
 
      if such a column is NOT found AND    // Lookup in outer queries.
746
 
         there are outer queries
747
 
      {
748
 
        for each outer query Q_k beginning from the inner-most one
749
 
        {
750
 
          search for a column or derived column named col_ref_i
751
 
          [in table T_j] in the FROM clause of Q_k;
752
 
 
753
 
          if such a column is not found
754
 
            Search for a column or derived column named col_ref_i
755
 
            [in table T_j] in the SELECT and GROUP clauses of Q_k.
756
 
        }
757
 
      }
758
 
    }
759
 
  @endcode
760
 
 
761
 
    Notice that compared to Item_ref::fix_fields, here we first search the FROM
762
 
    clause, and then we search the SELECT and GROUP BY clauses.
763
 
 
764
 
  @param[in]     session        current thread
765
 
  @param[in,out] reference  view column if this item was resolved to a
766
 
    view column
767
 
 
768
 
  @retval
769
 
    true  if error
770
 
  @retval
771
 
    false on success
772
 
*/
773
 
 
774
 
bool Item_field::fix_fields(Session *session, Item **reference)
775
 
{
776
 
  assert(fixed == 0);
777
 
  Field *from_field= (Field *)not_found_field;
778
 
  bool outer_fixed= false;
779
 
 
780
 
  if (!field)                                   // If field is not checked
781
 
  {
782
 
    /*
783
 
      In case of view, find_field_in_tables() write pointer to view field
784
 
      expression to 'reference', i.e. it substitute that expression instead
785
 
      of this Item_field
786
 
    */
787
 
    if ((from_field= find_field_in_tables(session, this,
788
 
                                          context->first_name_resolution_table,
789
 
                                          context->last_name_resolution_table,
790
 
                                          reference,
791
 
                                          session->lex->use_only_table_context ?
792
 
                                            REPORT_ALL_ERRORS :
793
 
                                            IGNORE_EXCEPT_NON_UNIQUE, true)) ==
794
 
        not_found_field)
795
 
    {
796
 
      int ret;
797
 
      /* Look up in current select's item_list to find aliased fields */
798
 
      if (session->lex->current_select->is_item_list_lookup)
799
 
      {
800
 
        uint32_t counter;
801
 
        enum_resolution_type resolution;
802
 
        Item** res= find_item_in_list(session,
803
 
                                      this, session->lex->current_select->item_list,
804
 
                                      &counter, REPORT_EXCEPT_NOT_FOUND,
805
 
                                      &resolution);
806
 
        if (!res)
807
 
          return 1;
808
 
        if (resolution == RESOLVED_AGAINST_ALIAS)
809
 
          alias_name_used= true;
810
 
        if (res != (Item **)not_found_item)
811
 
        {
812
 
          if ((*res)->type() == Item::FIELD_ITEM)
813
 
          {
814
 
            /*
815
 
              It's an Item_field referencing another Item_field in the select
816
 
              list.
817
 
              Use the field from the Item_field in the select list and leave
818
 
              the Item_field instance in place.
819
 
            */
820
 
 
821
 
            Field *new_field= (*((Item_field**)res))->field;
822
 
 
823
 
            if (new_field == NULL)
824
 
            {
825
 
              /* The column to which we link isn't valid. */
826
 
              my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name,
827
 
                       session->where());
828
 
              return(1);
829
 
            }
830
 
 
831
 
            set_field(new_field);
832
 
            return 0;
833
 
          }
834
 
          else
835
 
          {
836
 
            /*
837
 
              It's not an Item_field in the select list so we must make a new
838
 
              Item_ref to point to the Item in the select list and replace the
839
 
              Item_field created by the parser with the new Item_ref.
840
 
            */
841
 
            Item_ref *rf= new Item_ref(context, db_name,table_name,field_name);
842
 
            if (!rf)
843
 
              return 1;
844
 
            session->change_item_tree(reference, rf);
845
 
            /*
846
 
              Because Item_ref never substitutes itself with other items
847
 
              in Item_ref::fix_fields(), we can safely use the original
848
 
              pointer to it even after fix_fields()
849
 
             */
850
 
            return rf->fix_fields(session, reference) ||  rf->check_cols(1);
851
 
          }
852
 
        }
853
 
      }
854
 
      if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
855
 
        goto error;
856
 
      outer_fixed= true;
857
 
      if (!ret)
858
 
        goto mark_non_agg_field;
859
 
    }
860
 
    else if (!from_field)
861
 
      goto error;
862
 
 
863
 
    if (!outer_fixed && cached_table && cached_table->select_lex &&
864
 
        context->select_lex &&
865
 
        cached_table->select_lex != context->select_lex)
866
 
    {
867
 
      int ret;
868
 
      if ((ret= fix_outer_field(session, &from_field, reference)) < 0)
869
 
        goto error;
870
 
      outer_fixed= 1;
871
 
      if (!ret)
872
 
        goto mark_non_agg_field;
873
 
    }
874
 
 
875
 
    /*
876
 
      if it is not expression from merged VIEW we will set this field.
877
 
 
878
 
      We can leave expression substituted from view for next PS/SP rexecution
879
 
      (i.e. do not register this substitution for reverting on cleanup()
880
 
      (register_item_tree_changing())), because this subtree will be
881
 
      fix_field'ed during setup_tables()->setup_underlying() (i.e. before
882
 
      all other expressions of query, and references on tables which do
883
 
      not present in query will not make problems.
884
 
 
885
 
      Also we suppose that view can't be changed during PS/SP life.
886
 
    */
887
 
    if (from_field == view_ref_found)
888
 
      return false;
889
 
 
890
 
    set_field(from_field);
891
 
    if (session->lex->in_sum_func &&
892
 
        session->lex->in_sum_func->nest_level ==
893
 
        session->lex->current_select->nest_level)
894
 
    {
895
 
      set_if_bigger(session->lex->in_sum_func->max_arg_level,
896
 
                    session->lex->current_select->nest_level);
897
 
    }
898
 
  }
899
 
  else if (session->mark_used_columns != MARK_COLUMNS_NONE)
900
 
  {
901
 
    Table *table= field->getTable();
902
 
    boost::dynamic_bitset<> *current_bitmap, *other_bitmap;
903
 
    if (session->mark_used_columns == MARK_COLUMNS_READ)
904
 
    {
905
 
      current_bitmap= table->read_set;
906
 
      other_bitmap=   table->write_set;
907
 
    }
908
 
    else
909
 
    {
910
 
      current_bitmap= table->write_set;
911
 
      other_bitmap=   table->read_set;
912
 
    }
913
 
    //if (! current_bitmap->testAndSet(field->position()))
914
 
    if (! current_bitmap->test(field->position()))
915
 
    {
916
 
      if (! other_bitmap->test(field->position()))
917
 
      {
918
 
        /* First usage of column */
919
 
        table->used_fields++;                     // Used to optimize loops
920
 
        table->covering_keys&= field->part_of_key;
921
 
      }
922
 
    }
923
 
  }
924
 
  fixed= 1;
925
 
mark_non_agg_field:
926
 
  return false;
927
 
 
928
 
error:
929
 
  context->process_error(session);
930
 
  return true;
931
 
}
932
 
 
933
 
Item *Item_field::safe_charset_converter(const CHARSET_INFO * const tocs)
934
 
{
935
 
  no_const_subst= 1;
936
 
  return Item::safe_charset_converter(tocs);
937
 
}
938
 
 
939
 
 
940
 
void Item_field::cleanup()
941
 
{
942
 
  Item_ident::cleanup();
943
 
  /*
944
 
    Even if this object was created by direct link to field in setup_wild()
945
 
    it will be linked correctly next time by name of field and table alias.
946
 
    I.e. we can drop 'field'.
947
 
   */
948
 
  field= result_field= 0;
949
 
  null_value= false;
950
 
  return;
951
 
}
952
 
 
953
 
 
954
 
bool Item_field::result_as_int64_t()
955
 
{
956
 
  return field->can_be_compared_as_int64_t();
957
 
}
958
 
 
959
 
 
960
 
/**
961
 
  Find a field among specified multiple equalities.
962
 
 
963
 
  The function first searches the field among multiple equalities
964
 
  of the current level (in the cond_equal->current_level list).
965
 
  If it fails, it continues searching in upper levels accessed
966
 
  through a pointer cond_equal->upper_levels.
967
 
  The search terminates as soon as a multiple equality containing
968
 
  the field is found.
969
 
 
970
 
  @param cond_equal   reference to list of multiple equalities where
971
 
                      the field (this object) is to be looked for
972
 
 
973
 
  @return
974
 
    - First Item_equal containing the field, if success
975
 
    - 0, otherwise
976
 
*/
977
 
 
978
 
Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
979
 
{
980
 
  Item_equal *item= 0;
981
 
  while (cond_equal)
982
 
  {
983
 
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
984
 
    while ((item= li++))
985
 
    {
986
 
      if (item->contains(field))
987
 
        return item;
988
 
    }
989
 
    /*
990
 
      The field is not found in any of the multiple equalities
991
 
      of the current level. Look for it in upper levels
992
 
    */
993
 
    cond_equal= cond_equal->upper_levels;
994
 
  }
995
 
  return 0;
996
 
}
997
 
 
998
 
 
999
 
/**
1000
 
  Check whether a field can be substituted by an equal item.
1001
 
 
1002
 
  The function checks whether a substitution of the field
1003
 
  occurrence for an equal item is valid.
1004
 
 
1005
 
  @param arg   *arg != NULL <-> the field is in the context where
1006
 
               substitution for an equal item is valid
1007
 
 
1008
 
  @note
1009
 
    The following statement is not always true:
1010
 
  @n
1011
 
    x=y => F(x)=F(x/y).
1012
 
  @n
1013
 
    This means substitution of an item for an equal item not always
1014
 
    yields an equavalent condition. Here's an example:
1015
 
    @code
1016
 
    'a'='a '
1017
 
    (LENGTH('a')=1) != (LENGTH('a ')=2)
1018
 
  @endcode
1019
 
    Such a substitution is surely valid if either the substituted
1020
 
    field is not of a STRING type or if it is an argument of
1021
 
    a comparison predicate.
1022
 
 
1023
 
  @retval
1024
 
    true   substitution is valid
1025
 
  @retval
1026
 
    false  otherwise
1027
 
*/
1028
 
 
1029
 
bool Item_field::subst_argument_checker(unsigned char **arg)
1030
 
{
1031
 
  return (result_type() != STRING_RESULT) || (*arg);
1032
 
}
1033
 
 
1034
 
 
1035
 
/**
1036
 
  Set a pointer to the multiple equality the field reference belongs to
1037
 
  (if any).
1038
 
 
1039
 
  The function looks for a multiple equality containing the field item
1040
 
  among those referenced by arg.
1041
 
  In the case such equality exists the function does the following.
1042
 
  If the found multiple equality contains a constant, then the field
1043
 
  reference is substituted for this constant, otherwise it sets a pointer
1044
 
  to the multiple equality in the field item.
1045
 
 
1046
 
 
1047
 
  @param arg    reference to list of multiple equalities where
1048
 
                the field (this object) is to be looked for
1049
 
 
1050
 
  @note
1051
 
    This function is supposed to be called as a callback parameter in calls
1052
 
    of the compile method.
1053
 
 
1054
 
  @return
1055
 
    - pointer to the replacing constant item, if the field item was substituted
1056
 
    - pointer to the field item, otherwise.
1057
 
*/
1058
 
 
1059
 
Item *Item_field::equal_fields_propagator(unsigned char *arg)
1060
 
{
1061
 
  if (no_const_subst)
1062
 
    return this;
1063
 
  item_equal= find_item_equal((COND_EQUAL *) arg);
1064
 
  Item *item= 0;
1065
 
  if (item_equal)
1066
 
    item= item_equal->get_const();
1067
 
  /*
1068
 
    Disable const propagation for items used in different comparison contexts.
1069
 
    This must be done because, for example, Item_hex_string->val_int() is not
1070
 
    the same as (Item_hex_string->val_str() in BINARY column)->val_int().
1071
 
    We cannot simply disable the replacement in a particular context (
1072
 
    e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
1073
 
    Items don't know the context they are in and there are functions like
1074
 
    IF (<hex_string>, 'yes', 'no').
1075
 
    The same problem occurs when comparing a DATE/TIME field with a
1076
 
    DATE/TIME represented as an int and as a string.
1077
 
  */
1078
 
  if (!item ||
1079
 
      (cmp_context != (Item_result)-1 && item->cmp_context != cmp_context))
1080
 
    item= this;
1081
 
 
1082
 
  return item;
1083
 
}
1084
 
 
1085
 
 
1086
 
/**
1087
 
  Mark the item to not be part of substitution if it's not a binary item.
1088
 
 
1089
 
  See comments in Arg_comparator::set_compare_func() for details.
1090
 
*/
1091
 
 
1092
 
bool Item_field::set_no_const_sub(unsigned char *)
1093
 
{
1094
 
  if (field->charset() != &my_charset_bin)
1095
 
    no_const_subst=1;
1096
 
  return false;
1097
 
}
1098
 
 
1099
 
 
1100
 
/**
1101
 
  Replace an Item_field for an equal Item_field that evaluated earlier
1102
 
  (if any).
1103
 
 
1104
 
  The function returns a pointer to an item that is taken from
1105
 
  the very beginning of the item_equal list which the Item_field
1106
 
  object refers to (belongs to) unless item_equal contains  a constant
1107
 
  item. In this case the function returns this constant item,
1108
 
  (if the substitution does not require conversion).
1109
 
  If the Item_field object does not refer any Item_equal object
1110
 
  'this' is returned .
1111
 
 
1112
 
  @param arg   a dummy parameter, is not used here
1113
 
 
1114
 
 
1115
 
  @note
1116
 
    This function is supposed to be called as a callback parameter in calls
1117
 
    of the thransformer method.
1118
 
 
1119
 
  @return
1120
 
    - pointer to a replacement Item_field if there is a better equal item or
1121
 
      a pointer to a constant equal item;
1122
 
    - this - otherwise.
1123
 
*/
1124
 
 
1125
 
Item *Item_field::replace_equal_field(unsigned char *)
1126
 
{
1127
 
  if (item_equal)
1128
 
  {
1129
 
    Item *const_item_ptr= item_equal->get_const();
1130
 
    if (const_item_ptr)
1131
 
    {
1132
 
      if (cmp_context != (Item_result)-1 &&
1133
 
          const_item_ptr->cmp_context != cmp_context)
1134
 
        return this;
1135
 
      return const_item_ptr;
1136
 
    }
1137
 
    Item_field *subst= item_equal->get_first();
1138
 
    if (subst && !field->eq(subst->field))
1139
 
      return subst;
1140
 
  }
1141
 
  return this;
1142
 
}
1143
 
 
1144
 
 
1145
 
uint32_t Item_field::max_disp_length()
1146
 
{
1147
 
  return field->max_display_length();
1148
 
}
1149
 
 
1150
 
 
1151
 
/* ARGSUSED */
1152
 
void Item_field::make_field(SendField *tmp_field)
1153
 
{
1154
 
  field->make_field(tmp_field);
1155
 
  assert(tmp_field->table_name != 0);
1156
 
  if (name)
1157
 
    tmp_field->col_name=name;                   // Use user supplied name
1158
 
  if (table_name)
1159
 
    tmp_field->table_name= table_name;
1160
 
  if (db_name)
1161
 
    tmp_field->db_name= db_name;
1162
 
}
1163
 
 
1164
 
 
1165
 
/**
1166
 
  Set a field's value from a item.
1167
 
*/
1168
 
 
1169
 
void Item_field::save_org_in_field(Field *to)
1170
 
{
1171
 
  if (field->is_null())
1172
 
  {
1173
 
    null_value=1;
1174
 
    set_field_to_null_with_conversions(to, 1);
1175
 
  }
1176
 
  else
1177
 
  {
1178
 
    to->set_notnull();
1179
 
    field_conv(to,field);
1180
 
    null_value=0;
1181
 
  }
1182
 
}
1183
 
 
1184
 
int Item_field::save_in_field(Field *to, bool no_conversions)
1185
 
{
1186
 
  int res;
1187
 
  if (result_field->is_null())
1188
 
  {
1189
 
    null_value=1;
1190
 
    res= set_field_to_null_with_conversions(to, no_conversions);
1191
 
  }
1192
 
  else
1193
 
  {
1194
 
    to->set_notnull();
1195
 
    res= field_conv(to,result_field);
1196
 
    null_value=0;
1197
 
  }
1198
 
  return(res);
1199
 
}
1200
 
 
1201
 
 
1202
 
bool Item_field::send(plugin::Client *client, String *)
1203
 
{
1204
 
  return client->store(result_field);
1205
 
}
1206
 
 
1207
 
 
1208
 
void Item_field::update_null_value()
1209
 
{
1210
 
  /*
1211
 
    need to set no_errors to prevent warnings about type conversion
1212
 
    popping up.
1213
 
  */
1214
 
  Session *session= field->getTable()->in_use;
1215
 
  int no_errors;
1216
 
 
1217
 
  no_errors= session->no_errors;
1218
 
  session->no_errors= 1;
1219
 
  Item::update_null_value();
1220
 
  session->no_errors= no_errors;
1221
 
}
1222
 
 
1223
 
 
1224
 
/*
1225
 
  Add the field to the select list and substitute it for the reference to
1226
 
  the field.
1227
 
 
1228
 
  SYNOPSIS
1229
 
    Item_field::update_value_transformer()
1230
 
    select_arg      current select
1231
 
 
1232
 
  DESCRIPTION
1233
 
    If the field doesn't belong to the table being inserted into then it is
1234
 
    added to the select list, pointer to it is stored in the ref_pointer_array
1235
 
    of the select and the field itself is substituted for the Item_ref object.
1236
 
    This is done in order to get correct values from update fields that
1237
 
    belongs to the SELECT part in the INSERT .. SELECT .. ON DUPLICATE KEY
1238
 
    UPDATE statement.
1239
 
 
1240
 
  RETURN
1241
 
    0             if error occured
1242
 
    ref           if all conditions are met
1243
 
    this field    otherwise
1244
 
*/
1245
 
 
1246
 
Item *Item_field::update_value_transformer(unsigned char *select_arg)
1247
 
{
1248
 
  Select_Lex *select= (Select_Lex*)select_arg;
1249
 
  assert(fixed);
1250
 
 
1251
 
  if (field->getTable() != select->context.table_list->table)
1252
 
  {
1253
 
    List<Item> *all_fields= &select->join->all_fields;
1254
 
    Item **ref_pointer_array= select->ref_pointer_array;
1255
 
    int el= all_fields->elements;
1256
 
    Item_ref *ref;
1257
 
 
1258
 
    ref_pointer_array[el]= (Item*)this;
1259
 
    all_fields->push_front((Item*)this);
1260
 
    ref= new Item_ref(&select->context, ref_pointer_array + el,
1261
 
                      table_name, field_name);
1262
 
    return ref;
1263
 
  }
1264
 
  return this;
1265
 
}
1266
 
 
1267
 
 
1268
 
void Item_field::print(String *str, enum_query_type query_type)
1269
 
{
1270
 
  if (field && field->getTable()->const_table)
1271
 
  {
1272
 
    char buff[MAX_FIELD_WIDTH];
1273
 
    String tmp(buff,sizeof(buff),str->charset());
1274
 
    field->val_str_internal(&tmp);
1275
 
    if (field->is_null())  {
1276
 
      str->append("NULL");
1277
 
    }
1278
 
    else {
1279
 
      str->append('\'');
1280
 
      str->append(tmp);
1281
 
      str->append('\'');
1282
 
    }
1283
 
    return;
1284
 
  }
1285
 
  Item_ident::print(str, query_type);
1286
 
}
1287
 
 
1288
 
 
1289
 
} /* namespace drizzled */