~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/field.cc

  • Committer: Brian Aker
  • Date: 2010-05-27 01:25:56 UTC
  • mfrom: (1567.1.4 new-staging)
  • Revision ID: brian@gaz-20100527012556-5zgkirkl7swbigd6
Merge of Brian, Paul. PBXT compile issue, and test framework cleanup. 

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