~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/field.cc

pandora-build v0.100 - Fixes several bugs found by cb1kenobi. Add several thoughts from folks at LCA.

Show diffs side-by-side

added added

removed removed

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