~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/field.cc

  • Committer: Olaf van der Spek
  • Date: 2011-07-05 11:15:32 UTC
  • mto: This revision was merged to the branch mainline in revision 2367.
  • Revision ID: olafvdspek@gmail.com-20110705111532-zod5hduzwcqe01ea
Use boost::to_lower

Show diffs side-by-side

added added

removed removed

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