~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/field.cc

  • Committer: Monty Taylor
  • Date: 2009-05-09 22:13:47 UTC
  • mto: This revision was merged to the branch mainline in revision 1009.
  • Revision ID: mordred@inaugust.com-20090509221347-l712szviusbobro0
Re-added bitset<> as a replacement for Bitmap<>

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