~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Lee Bieber
  • Date: 2011-03-29 22:31:41 UTC
  • mfrom: (2257.1.3 build)
  • Revision ID: kalebral@gmail.com-20110329223141-yxc22h3l2he58sk0
Merge Andrew - 743842: Build failure using GCC 4.6
Merge Stewart - 738022: CachedDirectory silently fails to add entries if stat() fails
Merge Olaf - Common fwd: add copyright, add more declaration

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  This file defines all compare functions
22
22
*/
23
23
 
24
 
#include "config.h"
25
 
#include "drizzled/sql_select.h"
26
 
#include "drizzled/error.h"
27
 
#include "drizzled/temporal.h"
28
 
#include "drizzled/item/cmpfunc.h"
29
 
#include "drizzled/cached_item.h"
30
 
#include "drizzled/item/cache_int.h"
31
 
#include "drizzled/item/int_with_ref.h"
32
 
#include "drizzled/check_stack_overrun.h"
33
 
#include "drizzled/time_functions.h"
34
 
#include "drizzled/internal/my_sys.h"
 
24
#include <config.h>
 
25
 
 
26
#include <drizzled/cached_item.h>
 
27
#include <drizzled/check_stack_overrun.h>
 
28
#include <drizzled/current_session.h>
 
29
#include <drizzled/error.h>
 
30
#include <drizzled/internal/my_sys.h>
 
31
#include <drizzled/item/cache_int.h>
 
32
#include <drizzled/item/cmpfunc.h>
 
33
#include <drizzled/item/int_with_ref.h>
 
34
#include <drizzled/item/subselect.h>
 
35
#include <drizzled/session.h>
 
36
#include <drizzled/sql_select.h>
 
37
#include <drizzled/temporal.h>
 
38
#include <drizzled/time_functions.h>
 
39
#include <drizzled/sql_lex.h>
 
40
#include <drizzled/system_variables.h>
 
41
 
35
42
#include <math.h>
36
43
#include <algorithm>
37
44
 
38
45
using namespace std;
39
46
 
40
 
namespace drizzled
41
 
{
 
47
namespace drizzled {
42
48
 
43
49
extern const double log_10[309];
44
50
 
342
348
  higher than the precedence of NOT.
343
349
*/
344
350
 
345
 
void Item_func_not::print(String *str, enum_query_type query_type)
 
351
void Item_func_not::print(String *str)
346
352
{
347
353
  str->append('(');
348
 
  Item_func::print(str, query_type);
 
354
  Item_func::print(str);
349
355
  str->append(')');
350
356
}
351
357
 
377
383
          (test_sub_item && !test_sub_item->any_value()));
378
384
}
379
385
 
380
 
void Item_func_not_all::print(String *str, enum_query_type query_type)
 
386
void Item_func_not_all::print(String *str)
381
387
{
382
388
  if (show)
383
 
    Item_func::print(str, query_type);
 
389
    Item_func::print(str);
384
390
  else
385
 
    args[0]->print(str, query_type);
 
391
    args[0]->print(str);
386
392
}
387
393
 
388
394
 
472
478
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
473
479
                                       test(field->flags & UNSIGNED_FLAG));
474
480
      if (tmp)
475
 
        session->change_item_tree(item, tmp);
 
481
        *item= tmp;
476
482
      result= 1;                                        // Item was replaced
477
483
    }
478
484
 
567
573
  set_cmp_func();
568
574
}
569
575
 
 
576
Arg_comparator::Arg_comparator():
 
577
  session(current_session),
 
578
  a_cache(0),
 
579
  b_cache(0)
 
580
{}
 
581
 
 
582
Arg_comparator::Arg_comparator(Item **a1, Item **a2):
 
583
  a(a1),
 
584
  b(a2),
 
585
  session(current_session),
 
586
  a_cache(0),
 
587
  b_cache(0)
 
588
{}
570
589
 
571
590
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
572
591
{
770
789
                                     int64_t *const_value)
771
790
{
772
791
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
773
 
  Item *str_arg= 0, *date_arg= 0;
 
792
  Item *str_arg= 0;
774
793
 
775
794
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
776
795
    return CMP_DATE_DFLT;
784
803
    else if (in_b->result_type() == STRING_RESULT)
785
804
    {
786
805
      cmp_type= CMP_DATE_WITH_STR;
787
 
      date_arg= in_a;
788
806
      str_arg= in_b;
789
807
    }
790
808
  }
791
809
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
792
810
  {
793
811
    cmp_type= CMP_STR_WITH_DATE;
794
 
    date_arg= in_b;
795
812
    str_arg= in_a;
796
813
  }
797
814
 
840
857
         */
841
858
        return CMP_DATE_DFLT;
842
859
      }
843
 
      if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
844
 
      {
845
 
        /* Chuck an error. Bad datetime input. */
846
 
        my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
847
 
        return CMP_DATE_DFLT; /* :( What else can I return... */
848
 
      }
849
 
 
850
 
      /* String conversion was good.  Convert to an integer for comparison purposes. */
851
 
      temporal.to_int64_t(&value);
 
860
      if (temporal.from_string(str_val->c_ptr(), str_val->length()))
 
861
      {
 
862
        /* String conversion was good.  Convert to an integer for comparison purposes. */
 
863
        temporal.to_int64_t(&value);
 
864
      }
 
865
      else
 
866
      {
 
867
        /* We aren't a DATETIME but still could be a TIME */
 
868
        Time timevalue;
 
869
        if (timevalue.from_string(str_val->c_ptr(), str_val->length()))
 
870
        {
 
871
          uint64_t timeint;
 
872
          timevalue.to_uint64_t(timeint);
 
873
          value= static_cast<int64_t>(timeint);
 
874
        }
 
875
        else
 
876
        {
 
877
          /* Chuck an error. Bad datetime input. */
 
878
          my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
 
879
          return CMP_DATE_DFLT; /* :( What else can I return... */
 
880
        }
 
881
      }
852
882
 
853
883
      if (const_value)
854
884
        *const_value= value;
1427
1457
}
1428
1458
 
1429
1459
 
1430
 
void Item_func_truth::print(String *str, enum_query_type query_type)
 
1460
void Item_func_truth::print(String *str)
1431
1461
{
1432
1462
  str->append('(');
1433
 
  args[0]->print(str, query_type);
 
1463
  args[0]->print(str);
1434
1464
  str->append(STRING_WITH_LEN(" is "));
1435
1465
  if (! affirmative)
1436
1466
    str->append(STRING_WITH_LEN("not "));
1659
1689
  new_item= (*args)->transform(transformer, argument);
1660
1690
  if (!new_item)
1661
1691
    return 0;
1662
 
  /*
1663
 
    Session::change_item_tree() should be called only if the tree was
1664
 
    really transformed, i.e. when a new item has been created.
1665
 
    Otherwise we'll be allocating a lot of unnecessary memory for
1666
 
    change records at each execution.
1667
 
  */
1668
 
  if ((*args) != new_item)
1669
 
    getSession().change_item_tree(args, new_item);
 
1692
  *args= new_item;
1670
1693
 
1671
1694
  /*
1672
1695
    Transform the right IN operand which should be an Item_in_subselect or a
1979
2002
  if (Item_func_opt_neg::fix_fields(session, ref))
1980
2003
    return 1;
1981
2004
 
1982
 
  session->lex->current_select->between_count++;
 
2005
  session->lex().current_select->between_count++;
1983
2006
 
1984
2007
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1985
2008
  if (pred_level && !negated)
2165
2188
}
2166
2189
 
2167
2190
 
2168
 
void Item_func_between::print(String *str, enum_query_type query_type)
 
2191
void Item_func_between::print(String *str)
2169
2192
{
2170
2193
  str->append('(');
2171
 
  args[0]->print(str, query_type);
 
2194
  args[0]->print(str);
2172
2195
  if (negated)
2173
2196
    str->append(STRING_WITH_LEN(" not"));
2174
2197
  str->append(STRING_WITH_LEN(" between "));
2175
 
  args[1]->print(str, query_type);
 
2198
  args[1]->print(str);
2176
2199
  str->append(STRING_WITH_LEN(" and "));
2177
 
  args[2]->print(str, query_type);
 
2200
  args[2]->print(str);
2178
2201
  str->append(')');
2179
2202
}
2180
2203
 
2823
2846
    Fix this so that it prints the whole CASE expression
2824
2847
*/
2825
2848
 
2826
 
void Item_func_case::print(String *str, enum_query_type query_type)
 
2849
void Item_func_case::print(String *str)
2827
2850
{
2828
2851
  str->append(STRING_WITH_LEN("(case "));
2829
2852
  if (first_expr_num != -1)
2830
2853
  {
2831
 
    args[first_expr_num]->print(str, query_type);
 
2854
    args[first_expr_num]->print(str);
2832
2855
    str->append(' ');
2833
2856
  }
2834
2857
  for (uint32_t i=0 ; i < ncases ; i+=2)
2835
2858
  {
2836
2859
    str->append(STRING_WITH_LEN("when "));
2837
 
    args[i]->print(str, query_type);
 
2860
    args[i]->print(str);
2838
2861
    str->append(STRING_WITH_LEN(" then "));
2839
 
    args[i+1]->print(str, query_type);
 
2862
    args[i+1]->print(str);
2840
2863
    str->append(' ');
2841
2864
  }
2842
2865
  if (else_expr_num != -1)
2843
2866
  {
2844
2867
    str->append(STRING_WITH_LEN("else "));
2845
 
    args[else_expr_num]->print(str, query_type);
 
2868
    args[else_expr_num]->print(str);
2846
2869
    str->append(' ');
2847
2870
  }
2848
2871
  str->append(STRING_WITH_LEN("end)"));
3102
3125
  return (int) ((*compare)(collation, base+start*size, result) == 0);
3103
3126
}
3104
3127
 
3105
 
in_string::in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
 
3128
in_string::in_string(uint32_t elements,qsort2_cmp cmp_func, const charset_info_st * const cs)
3106
3129
  :in_vector(elements, sizeof(String), cmp_func, cs),
3107
3130
   tmp(buff, sizeof(buff), &my_charset_bin)
3108
3131
{}
3132
3155
  }
3133
3156
  if (!str->charset())
3134
3157
  {
3135
 
    const CHARSET_INFO *cs;
 
3158
    const charset_info_st *cs;
3136
3159
    if (!(cs= item->collation.collation))
3137
3160
      cs= &my_charset_bin;              // Should never happen for STR items
3138
3161
    str->set_charset(cs);
3199
3222
  return (unsigned char*) &tmp;
3200
3223
}
3201
3224
 
 
3225
in_datetime::in_datetime(Item *warn_item_arg, uint32_t elements) :
 
3226
  in_int64_t(elements),
 
3227
  session(current_session),
 
3228
  warn_item(warn_item_arg),
 
3229
  lval_cache(0)
 
3230
{}
 
3231
 
3202
3232
void in_datetime::set(uint32_t pos, Item *item)
3203
3233
{
3204
3234
  Item **tmp_item= &item;
3266
3296
 
3267
3297
 
3268
3298
cmp_item* cmp_item::get_comparator(Item_result type,
3269
 
                                   const CHARSET_INFO * const cs)
 
3299
                                   const charset_info_st * const cs)
3270
3300
{
3271
3301
  switch (type) {
3272
3302
  case STRING_RESULT:
3537
3567
}
3538
3568
 
3539
3569
 
3540
 
static int srtcmp_in(const CHARSET_INFO * const cs, const String *x,const String *y)
 
3570
static int srtcmp_in(const charset_info_st * const cs, const String *x,const String *y)
3541
3571
{
3542
3572
  return cs->coll->strnncollsp(cs,
3543
3573
                               (unsigned char *) x->ptr(),x->length(),
3776
3806
}
3777
3807
 
3778
3808
 
3779
 
void Item_func_in::print(String *str, enum_query_type query_type)
 
3809
void Item_func_in::print(String *str)
3780
3810
{
3781
3811
  str->append('(');
3782
 
  args[0]->print(str, query_type);
 
3812
  args[0]->print(str);
3783
3813
  if (negated)
3784
3814
    str->append(STRING_WITH_LEN(" not"));
3785
3815
  str->append(STRING_WITH_LEN(" in ("));
3786
 
  print_args(str, 1, query_type);
 
3816
  print_args(str, 1);
3787
3817
  str->append(STRING_WITH_LEN("))"));
3788
3818
}
3789
3819
 
3861
3891
 
3862
3892
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3863
3893
{
3864
 
  List_iterator_fast<Item> li(item->list);
 
3894
  List<Item>::iterator li(item->list.begin());
3865
3895
  while (Item *it= li++)
3866
3896
    list.push_back(it->copy_andor_structure(session));
3867
3897
}
3871
3901
Item_cond::fix_fields(Session *session, Item **)
3872
3902
{
3873
3903
  assert(fixed == 0);
3874
 
  List_iterator<Item> li(list);
 
3904
  List<Item>::iterator li(list.begin());
3875
3905
  Item *item;
3876
3906
  void *orig_session_marker= session->session_marker;
3877
3907
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3911
3941
           !((Item_cond*) item)->list.is_empty())
3912
3942
    {                                           // Identical function
3913
3943
      li.replace(((Item_cond*) item)->list);
3914
 
      ((Item_cond*) item)->list.empty();
3915
 
      item= *li.ref();                          // new current item
 
3944
      ((Item_cond*) item)->list.clear();
 
3945
      item= &*li;                               // new current item
3916
3946
    }
3917
3947
    if (abort_on_null)
3918
3948
      item->top_level_item();
3920
3950
    // item can be substituted in fix_fields
3921
3951
    if ((!item->fixed &&
3922
3952
         item->fix_fields(session, li.ref())) ||
3923
 
        (item= *li.ref())->check_cols(1))
 
3953
        (item= &*li)->check_cols(1))
3924
3954
      return true;
3925
3955
    used_tables_cache|=     item->used_tables();
3926
3956
    if (item->const_item())
3937
3967
    if (item->maybe_null)
3938
3968
      maybe_null=1;
3939
3969
  }
3940
 
  session->lex->current_select->cond_count+= list.elements;
 
3970
  session->lex().current_select->cond_count+= list.size();
3941
3971
  session->session_marker= orig_session_marker;
3942
3972
  fix_length_and_dec();
3943
3973
  fixed= 1;
3947
3977
 
3948
3978
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3949
3979
{
3950
 
  List_iterator<Item> li(list);
 
3980
  List<Item>::iterator li(list.begin());
3951
3981
  Item *item;
3952
3982
 
3953
3983
  used_tables_cache=0;
3960
3990
  {
3961
3991
    table_map tmp_table_map;
3962
3992
    item->fix_after_pullout(new_parent, li.ref());
3963
 
    item= *li.ref();
 
3993
    item= &*li;
3964
3994
    used_tables_cache|= item->used_tables();
3965
3995
    const_item_cache&= item->const_item();
3966
3996
 
3979
4009
 
3980
4010
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
3981
4011
{
3982
 
  List_iterator_fast<Item> li(list);
 
4012
  List<Item>::iterator li(list.begin());
3983
4013
  Item *item;
3984
4014
  while ((item= li++))
3985
4015
    if (item->walk(processor, walk_subquery, arg))
4008
4038
 
4009
4039
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4010
4040
{
4011
 
  List_iterator<Item> li(list);
 
4041
  List<Item>::iterator li(list.begin());
4012
4042
  Item *item;
4013
4043
  while ((item= li++))
4014
4044
  {
4015
4045
    Item *new_item= item->transform(transformer, arg);
4016
4046
    if (!new_item)
4017
4047
      return 0;
4018
 
 
4019
 
    /*
4020
 
      Session::change_item_tree() should be called only if the tree was
4021
 
      really transformed, i.e. when a new item has been created.
4022
 
      Otherwise we'll be allocating a lot of unnecessary memory for
4023
 
      change records at each execution.
4024
 
    */
4025
 
    if (new_item != item)
4026
 
      getSession().change_item_tree(li.ref(), new_item);
 
4048
    *li.ref()= new_item;
4027
4049
  }
4028
4050
  return Item_func::transform(transformer, arg);
4029
4051
}
4059
4081
  if (!(this->*analyzer)(arg_p))
4060
4082
    return 0;
4061
4083
 
4062
 
  List_iterator<Item> li(list);
 
4084
  List<Item>::iterator li(list.begin());
4063
4085
  Item *item;
4064
4086
  while ((item= li++))
4065
4087
  {
4078
4100
void Item_cond::traverse_cond(Cond_traverser traverser,
4079
4101
                              void *arg, traverse_order order)
4080
4102
{
4081
 
  List_iterator<Item> li(list);
 
4103
  List<Item>::iterator li(list.begin());
4082
4104
  Item *item;
4083
4105
 
4084
4106
  switch (order) {
4116
4138
    that have or refer (HAVING) to a SUM expression.
4117
4139
*/
4118
4140
 
4119
 
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4120
 
                               List<Item> &fields)
 
4141
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields)
4121
4142
{
4122
 
  List_iterator<Item> li(list);
 
4143
  List<Item>::iterator li(list.begin());
4123
4144
  Item *item;
4124
4145
  while ((item= li++))
4125
 
    item->split_sum_func(session, ref_pointer_array,
4126
 
                         fields, li.ref(), true);
 
4146
    item->split_sum_func(session, ref_pointer_array, fields, li.ref(), true);
4127
4147
}
4128
4148
 
4129
4149
 
4136
4156
 
4137
4157
void Item_cond::update_used_tables()
4138
4158
{
4139
 
  List_iterator_fast<Item> li(list);
 
4159
  List<Item>::iterator li(list.begin());
4140
4160
  Item *item;
4141
4161
 
4142
4162
  used_tables_cache=0;
4150
4170
}
4151
4171
 
4152
4172
 
4153
 
void Item_cond::print(String *str, enum_query_type query_type)
 
4173
void Item_cond::print(String *str)
4154
4174
{
4155
4175
  str->append('(');
4156
 
  List_iterator_fast<Item> li(list);
 
4176
  List<Item>::iterator li(list.begin());
4157
4177
  Item *item;
4158
4178
  if ((item=li++))
4159
 
    item->print(str, query_type);
 
4179
    item->print(str);
4160
4180
  while ((item=li++))
4161
4181
  {
4162
4182
    str->append(' ');
4163
4183
    str->append(func_name());
4164
4184
    str->append(' ');
4165
 
    item->print(str, query_type);
 
4185
    item->print(str);
4166
4186
  }
4167
4187
  str->append(')');
4168
4188
}
4170
4190
 
4171
4191
void Item_cond::neg_arguments(Session *session)
4172
4192
{
4173
 
  List_iterator<Item> li(list);
 
4193
  List<Item>::iterator li(list.begin());
4174
4194
  Item *item;
4175
4195
  while ((item= li++))          /* Apply not transformation to the arguments */
4176
4196
  {
4208
4228
int64_t Item_cond_and::val_int()
4209
4229
{
4210
4230
  assert(fixed == 1);
4211
 
  List_iterator_fast<Item> li(list);
 
4231
  List<Item>::iterator li(list.begin());
4212
4232
  Item *item;
4213
4233
  null_value= 0;
4214
4234
  while ((item=li++))
4226
4246
int64_t Item_cond_or::val_int()
4227
4247
{
4228
4248
  assert(fixed == 1);
4229
 
  List_iterator_fast<Item> li(list);
 
4249
  List<Item>::iterator li(list.begin());
4230
4250
  Item *item;
4231
4251
  null_value=0;
4232
4252
  while ((item=li++))
4276
4296
    }
4277
4297
    return res;
4278
4298
  }
4279
 
  if (((Item_cond_and*) a)->add((Item*) b))
4280
 
    return 0;
 
4299
  ((Item_cond_and*) a)->add((Item*) b);
4281
4300
  ((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
4282
4301
  ((Item_cond_and*) a)->not_null_tables_cache|= b->not_null_tables();
4283
4302
  return a;
4342
4361
}
4343
4362
 
4344
4363
 
4345
 
void Item_func_isnotnull::print(String *str, enum_query_type query_type)
 
4364
void Item_func_isnotnull::print(String *str)
4346
4365
{
4347
4366
  str->append('(');
4348
 
  args[0]->print(str, query_type);
 
4367
  args[0]->print(str);
4349
4368
  str->append(STRING_WITH_LEN(" is not null)"));
4350
4369
}
4351
4370
 
4482
4501
  Item_bool_func2::cleanup();
4483
4502
}
4484
4503
 
4485
 
static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
 
4504
static unsigned char likeconv(const charset_info_st *cs, unsigned char a)
4486
4505
{
4487
4506
#ifdef LIKE_CMP_TOUPPER
4488
4507
  return cs->toupper(a);
4501
4520
  int            f = 0;
4502
4521
  int            g = plm1;
4503
4522
  int *const splm1 = suff + plm1;
4504
 
  const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4523
  const charset_info_st * const cs= cmp.cmp_collation.collation;
4505
4524
 
4506
4525
  *splm1 = pattern_len;
4507
4526
 
4599
4618
  int *end = bmBc + alphabet_size;
4600
4619
  int j;
4601
4620
  const int plm1 = pattern_len - 1;
4602
 
  const CHARSET_INFO *const cs= cmp.cmp_collation.collation;
 
4621
  const charset_info_st *const cs= cmp.cmp_collation.collation;
4603
4622
 
4604
4623
  for (i = bmBc; i < end; i++)
4605
4624
    *i = pattern_len;
4626
4645
 
4627
4646
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
4628
4647
{
4629
 
  register int bcShift;
4630
 
  register int turboShift;
 
4648
  int bcShift;
 
4649
  int turboShift;
4631
4650
  int shift = pattern_len;
4632
4651
  int j     = 0;
4633
4652
  int u     = 0;
4634
 
  const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4653
  const charset_info_st * const cs= cmp.cmp_collation.collation;
4635
4654
 
4636
4655
  const int plm1=  pattern_len - 1;
4637
4656
  const int tlmpl= text_len - pattern_len;
4641
4660
  {
4642
4661
    while (j <= tlmpl)
4643
4662
    {
4644
 
      register int i= plm1;
 
4663
      int i= plm1;
4645
4664
      while (i >= 0 && pattern[i] == text[i + j])
4646
4665
      {
4647
4666
        i--;
4651
4670
      if (i < 0)
4652
4671
        return 1;
4653
4672
 
4654
 
      register const int v = plm1 - i;
 
4673
      const int v = plm1 - i;
4655
4674
      turboShift = u - v;
4656
4675
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
4657
4676
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4672
4691
  {
4673
4692
    while (j <= tlmpl)
4674
4693
    {
4675
 
      register int i = plm1;
 
4694
      int i = plm1;
4676
4695
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4677
4696
      {
4678
4697
        i--;
4683
4702
      if (i < 0)
4684
4703
        return 1;
4685
4704
 
4686
 
      register const int v= plm1 - i;
 
4705
      const int v= plm1 - i;
4687
4706
      turboShift= u - v;
4688
4707
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4689
4708
      shift= (turboShift > bcShift) ? turboShift : bcShift;
4724
4743
int64_t Item_cond_xor::val_int()
4725
4744
{
4726
4745
  assert(fixed == 1);
4727
 
  List_iterator<Item> li(list);
 
4746
  List<Item>::iterator li(list.begin());
4728
4747
  Item *item;
4729
4748
  int result=0;
4730
4749
  null_value=0;
4904
4923
  : item::function::Boolean(), eval_item(0), cond_false(0)
4905
4924
{
4906
4925
  const_item_cache= false;
4907
 
  List_iterator_fast<Item_field> li(item_equal->fields);
 
4926
  List<Item_field>::iterator li(item_equal->fields.begin());
4908
4927
  Item_field *item;
4909
4928
  while ((item= li++))
4910
4929
  {
4937
4956
 
4938
4957
uint32_t Item_equal::members()
4939
4958
{
4940
 
  return fields.elements;
 
4959
  return fields.size();
4941
4960
}
4942
4961
 
4943
4962
 
4956
4975
 
4957
4976
bool Item_equal::contains(Field *field)
4958
4977
{
4959
 
  List_iterator_fast<Item_field> it(fields);
 
4978
  List<Item_field>::iterator it(fields.begin());
4960
4979
  Item_field *item;
4961
4980
  while ((item= it++))
4962
4981
  {
5015
5034
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
5016
5035
{
5017
5036
  bool swap;
5018
 
  List_iterator<Item_field> it(fields);
 
5037
  List<Item_field>::iterator it(fields.begin());
5019
5038
  do
5020
5039
  {
5021
5040
    Item_field *item1= it++;
5039
5058
        ref1= ref2;
5040
5059
      }
5041
5060
    }
5042
 
    it.rewind();
 
5061
    it= fields.begin();
5043
5062
  } while (swap);
5044
5063
}
5045
5064
 
5056
5075
 
5057
5076
void Item_equal::update_const()
5058
5077
{
5059
 
  List_iterator<Item_field> it(fields);
 
5078
  List<Item_field>::iterator it(fields.begin());
5060
5079
  Item *item;
5061
5080
  while ((item= it++))
5062
5081
  {
5070
5089
 
5071
5090
bool Item_equal::fix_fields(Session *, Item **)
5072
5091
{
5073
 
  List_iterator_fast<Item_field> li(fields);
 
5092
  List<Item_field>::iterator li(fields.begin());
5074
5093
  Item *item;
5075
5094
  not_null_tables_cache= used_tables_cache= 0;
5076
5095
  const_item_cache= false;
5090
5109
 
5091
5110
void Item_equal::update_used_tables()
5092
5111
{
5093
 
  List_iterator_fast<Item_field> li(fields);
 
5112
  List<Item_field>::iterator li(fields.begin());
5094
5113
  Item *item;
5095
5114
  not_null_tables_cache= used_tables_cache= 0;
5096
5115
  if ((const_item_cache= cond_false))
5108
5127
  Item_field *item_field;
5109
5128
  if (cond_false)
5110
5129
    return 0;
5111
 
  List_iterator_fast<Item_field> it(fields);
 
5130
  List<Item_field>::iterator it(fields.begin());
5112
5131
  Item *item= const_item ? const_item : it++;
5113
5132
  eval_item->store_value(item);
5114
5133
  if ((null_value= item->null_value))
5134
5153
 
5135
5154
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
5136
5155
{
5137
 
  List_iterator_fast<Item_field> it(fields);
 
5156
  List<Item_field>::iterator it(fields.begin());
5138
5157
  Item *item;
5139
5158
  while ((item= it++))
5140
5159
  {
5146
5165
 
5147
5166
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
5148
5167
{
5149
 
  List_iterator<Item_field> it(fields);
 
5168
  List<Item_field>::iterator it(fields.begin());
5150
5169
  Item *item;
5151
5170
  while ((item= it++))
5152
5171
  {
5153
5172
    Item *new_item= item->transform(transformer, arg);
5154
5173
    if (!new_item)
5155
5174
      return 0;
5156
 
 
5157
 
    /*
5158
 
      Session::change_item_tree() should be called only if the tree was
5159
 
      really transformed, i.e. when a new item has been created.
5160
 
      Otherwise we'll be allocating a lot of unnecessary memory for
5161
 
      change records at each execution.
5162
 
    */
5163
 
    if (new_item != item)
5164
 
      getSession().change_item_tree((Item **) it.ref(), new_item);
 
5175
    *(Item **)it.ref()= new_item;
5165
5176
  }
5166
5177
  return Item_func::transform(transformer, arg);
5167
5178
}
5168
5179
 
5169
 
void Item_equal::print(String *str, enum_query_type query_type)
 
5180
void Item_equal::print(String *str)
5170
5181
{
5171
5182
  str->append(func_name());
5172
5183
  str->append('(');
5173
 
  List_iterator_fast<Item_field> it(fields);
 
5184
  List<Item_field>::iterator it(fields.begin());
5174
5185
  Item *item;
5175
5186
  if (const_item)
5176
 
    const_item->print(str, query_type);
 
5187
    const_item->print(str);
5177
5188
  else
5178
5189
  {
5179
5190
    item= it++;
5180
 
    item->print(str, query_type);
 
5191
    item->print(str);
5181
5192
  }
5182
5193
  while ((item= it++))
5183
5194
  {
5184
5195
    str->append(',');
5185
5196
    str->append(' ');
5186
 
    item->print(str, query_type);
 
5197
    item->print(str);
5187
5198
  }
5188
5199
  str->append(')');
5189
5200
}
5190
5201
 
 
5202
cmp_item_datetime::cmp_item_datetime(Item *warn_item_arg) :
 
5203
  session(current_session),
 
5204
  warn_item(warn_item_arg),
 
5205
  lval_cache(0)
 
5206
{}
 
5207
 
5191
5208
} /* namespace drizzled */