~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/field.cc

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