~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Lee Bieber
  • Date: 2011-02-23 23:22:48 UTC
  • mfrom: (2183.2.20 list2)
  • mto: This revision was merged to the branch mainline in revision 2197.
  • Revision ID: kalebral@gmail.com-20110223232248-ev4y8pyt16b806o0
Merge Olaf - Use List::size()

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
 
35
40
#include <math.h>
36
41
#include <algorithm>
37
42
 
463
468
      the call to save_in_field below overrides that value.
464
469
    */
465
470
    if (field_item->depended_from)
 
471
    {
466
472
      orig_field_val= field->val_int();
 
473
    }
 
474
 
467
475
    if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
468
476
    {
469
477
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
472
480
        session->change_item_tree(item, tmp);
473
481
      result= 1;                                        // Item was replaced
474
482
    }
 
483
 
475
484
    /* Restore the original field value. */
476
485
    if (field_item->depended_from)
477
486
    {
478
 
      result= field->store(orig_field_val, true);
 
487
      result= field->store(orig_field_val, field->isUnsigned());
479
488
      /* orig_field_val must be a valid value that can be restored back. */
480
489
      assert(!result);
481
490
    }
489
498
void Item_bool_func2::fix_length_and_dec()
490
499
{
491
500
  max_length= 1;                                     // Function returns 0 or 1
492
 
  Session *session;
493
501
 
494
502
  /*
495
503
    As some compare functions are generated after sql_yacc,
527
535
    return;
528
536
  }
529
537
 
530
 
  session= current_session;
531
538
  Item_field *field_item= NULL;
532
539
 
533
540
  if (args[0]->real_item()->type() == FIELD_ITEM)
536
543
    if (field_item->field->can_be_compared_as_int64_t() &&
537
544
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
538
545
    {
539
 
      if (convert_constant_item(session, field_item, &args[1]))
 
546
      if (convert_constant_item(&getSession(), field_item, &args[1]))
540
547
      {
541
548
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
542
549
                         INT_RESULT);           // Works for all types.
552
559
          !(field_item->is_datetime() &&
553
560
            args[0]->result_type() == STRING_RESULT))
554
561
      {
555
 
        if (convert_constant_item(session, field_item, &args[0]))
 
562
        if (convert_constant_item(&getSession(), field_item, &args[0]))
556
563
        {
557
564
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
558
565
                           INT_RESULT); // Works for all types.
565
572
  set_cmp_func();
566
573
}
567
574
 
 
575
Arg_comparator::Arg_comparator():
 
576
  session(current_session),
 
577
  a_cache(0),
 
578
  b_cache(0)
 
579
{}
 
580
 
 
581
Arg_comparator::Arg_comparator(Item **a1, Item **a2):
 
582
  a(a1),
 
583
  b(a2),
 
584
  session(current_session),
 
585
  a_cache(0),
 
586
  b_cache(0)
 
587
{}
568
588
 
569
589
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
570
590
{
692
712
    converted value. 0 on error and on zero-dates -- check 'failure'
693
713
*/
694
714
 
695
 
static uint64_t
696
 
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
 
715
static int64_t
 
716
get_date_from_str(Session *session, String *str, type::timestamp_t warn_type,
697
717
                  char *warn_name, bool *error_arg)
698
718
{
699
 
  uint64_t value= 0;
700
 
  int error;
701
 
  DRIZZLE_TIME l_time;
702
 
  enum enum_drizzle_timestamp_type ret;
703
 
 
704
 
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
705
 
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
706
 
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
707
 
                       &error);
708
 
 
709
 
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
 
719
  int64_t value= 0;
 
720
  type::cut_t error= type::VALID;
 
721
  type::Time l_time;
 
722
  type::timestamp_t ret;
 
723
 
 
724
  ret= l_time.store(str->ptr(), str->length(),
 
725
                    (TIME_FUZZY_DATE | MODE_INVALID_DATES | (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
726
                    error);
 
727
 
 
728
  if (ret == type::DRIZZLE_TIMESTAMP_DATETIME || ret == type::DRIZZLE_TIMESTAMP_DATE)
710
729
  {
711
730
    /*
712
731
      Do not return yet, we may still want to throw a "trailing garbage"
713
732
      warning.
714
733
    */
715
734
    *error_arg= false;
716
 
    value= TIME_to_uint64_t_datetime(&l_time);
 
735
    l_time.convert(value);
717
736
  }
718
737
  else
719
738
  {
720
739
    *error_arg= true;
721
 
    error= 1;                                   /* force warning */
 
740
    error= type::CUT;                                   /* force warning */
722
741
  }
723
742
 
724
 
  if (error > 0)
 
743
  if (error != type::VALID)
725
744
  {
726
745
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
727
746
                                 str->ptr(), str->length(),
766
785
 
767
786
enum Arg_comparator::enum_date_cmp_type
768
787
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
769
 
                                     uint64_t *const_value)
 
788
                                     int64_t *const_value)
770
789
{
771
790
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
772
791
  Item *str_arg= 0, *date_arg= 0;
777
796
  if (in_a->is_datetime())
778
797
  {
779
798
    if (in_b->is_datetime())
 
799
    {
780
800
      cmp_type= CMP_DATE_WITH_DATE;
 
801
    }
781
802
    else if (in_b->result_type() == STRING_RESULT)
782
803
    {
783
804
      cmp_type= CMP_DATE_WITH_STR;
819
840
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
820
841
       * from val_int(), not uint64_t...
821
842
       */
822
 
      uint64_t value;
 
843
      int64_t value;
823
844
      String *str_val;
824
845
      String tmp;
825
846
      /* DateTime used to pick up as many string conversion possibilities as possible. */
845
866
      }
846
867
 
847
868
      /* String conversion was good.  Convert to an integer for comparison purposes. */
848
 
      int64_t int_value;
849
 
      temporal.to_int64_t(&int_value);
850
 
      value= (uint64_t) int_value;
 
869
      temporal.to_int64_t(&value);
851
870
 
852
871
      if (const_value)
853
872
        *const_value= value;
861
880
                                        Item **a1, Item **a2,
862
881
                                        Item_result type)
863
882
{
864
 
  enum enum_date_cmp_type cmp_type;
865
 
  uint64_t const_value= (uint64_t)-1;
 
883
  enum_date_cmp_type cmp_type;
 
884
  int64_t const_value= -1;
866
885
  a= a1;
867
886
  b= a2;
868
887
 
869
888
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
870
889
  {
871
 
    session= current_session;
872
890
    owner= owner_arg;
873
891
    a_type= (*a)->field_type();
874
892
    b_type= (*b)->field_type();
875
893
    a_cache= 0;
876
894
    b_cache= 0;
877
895
 
878
 
    if (const_value != (uint64_t)-1)
 
896
    if (const_value != -1)
879
897
    {
880
898
      Item_cache_int *cache= new Item_cache_int();
881
899
      /* Mark the cache as non-const to prevent re-caching. */
896
914
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
897
915
    func= &Arg_comparator::compare_datetime;
898
916
    get_value_func= &get_datetime_value;
 
917
 
899
918
    return 0;
900
919
  }
901
920
 
905
924
 
906
925
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
907
926
{
908
 
  session= current_session;
909
927
  /* A caller will handle null values by itself. */
910
928
  owner= NULL;
911
929
  a= a1;
949
967
    obtained value
950
968
*/
951
969
 
952
 
uint64_t
 
970
int64_t
953
971
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
954
972
                   Item *warn_item, bool *is_null)
955
973
{
956
 
  uint64_t value= 0;
 
974
  int64_t value= 0;
957
975
  String buf, *str= 0;
958
976
  Item *item= **item_arg;
959
977
 
977
995
    str= item->val_str(&buf);
978
996
    *is_null= item->null_value;
979
997
  }
 
998
 
980
999
  if (*is_null)
981
1000
    return ~(uint64_t) 0;
 
1001
 
982
1002
  /*
983
1003
    Convert strings to the integer DATE/DATETIME representation.
984
1004
    Even if both dates provided in strings we can't compare them directly as
989
1009
  {
990
1010
    bool error;
991
1011
    enum_field_types f_type= warn_item->field_type();
992
 
    enum enum_drizzle_timestamp_type t_type= f_type ==
993
 
      DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
 
1012
    type::timestamp_t t_type= f_type == DRIZZLE_TYPE_DATE ? type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME;
994
1013
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
995
1014
    /*
996
1015
      If str did not contain a valid date according to the current
1013
1032
    *cache_arg= cache;
1014
1033
    *item_arg= cache_arg;
1015
1034
  }
 
1035
 
1016
1036
  return value;
1017
1037
}
1018
1038
 
1169
1189
 
1170
1190
int Arg_comparator::compare_decimal()
1171
1191
{
1172
 
  my_decimal value1;
1173
 
  my_decimal *val1= (*a)->val_decimal(&value1);
 
1192
  type::Decimal value1;
 
1193
  type::Decimal *val1= (*a)->val_decimal(&value1);
1174
1194
  if (!(*a)->null_value)
1175
1195
  {
1176
 
    my_decimal value2;
1177
 
    my_decimal *val2= (*b)->val_decimal(&value2);
 
1196
    type::Decimal value2;
 
1197
    type::Decimal *val2= (*b)->val_decimal(&value2);
1178
1198
    if (!(*b)->null_value)
1179
1199
    {
1180
1200
      owner->null_value= 0;
1181
 
      return my_decimal_cmp(val1, val2);
 
1201
      return class_decimal_cmp(val1, val2);
1182
1202
    }
1183
1203
  }
1184
1204
  owner->null_value= 1;
1196
1216
 
1197
1217
int Arg_comparator::compare_e_decimal()
1198
1218
{
1199
 
  my_decimal value1, value2;
1200
 
  my_decimal *val1= (*a)->val_decimal(&value1);
1201
 
  my_decimal *val2= (*b)->val_decimal(&value2);
 
1219
  type::Decimal value1, value2;
 
1220
  type::Decimal *val1= (*a)->val_decimal(&value1);
 
1221
  type::Decimal *val2= (*b)->val_decimal(&value2);
1202
1222
  if ((*a)->null_value || (*b)->null_value)
1203
1223
    return test((*a)->null_value && (*b)->null_value);
1204
 
  return test(my_decimal_cmp(val1, val2) == 0);
 
1224
  return test(class_decimal_cmp(val1, val2) == 0);
1205
1225
}
1206
1226
 
1207
1227
 
1611
1631
 
1612
1632
void Item_in_optimizer::cleanup()
1613
1633
{
1614
 
  Item_bool_func::cleanup();
 
1634
  item::function::Boolean::cleanup();
1615
1635
  if (!save_cache)
1616
1636
    cache= 0;
1617
1637
  return;
1664
1684
    change records at each execution.
1665
1685
  */
1666
1686
  if ((*args) != new_item)
1667
 
    current_session->change_item_tree(args, new_item);
 
1687
    getSession().change_item_tree(args, new_item);
1668
1688
 
1669
1689
  /*
1670
1690
    Transform the right IN operand which should be an Item_in_subselect or a
1819
1839
          {
1820
1840
            range->type= DECIMAL_RESULT;
1821
1841
            range->dec.init();
1822
 
            my_decimal *dec= el->val_decimal(&range->dec);
 
1842
            type::Decimal *dec= el->val_decimal(&range->dec);
1823
1843
            if (dec != &range->dec)
1824
1844
            {
1825
1845
              range->dec= *dec;
1869
1889
{
1870
1890
  assert(fixed == 1);
1871
1891
  double value;
1872
 
  my_decimal dec_buf, *dec= NULL;
 
1892
  type::Decimal dec_buf, *dec= NULL;
1873
1893
  uint32_t i;
1874
1894
 
1875
1895
  if (use_decimal_comparison)
1877
1897
    dec= row->element_index(0)->val_decimal(&dec_buf);
1878
1898
    if (row->element_index(0)->null_value)
1879
1899
      return -1;
1880
 
    my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
 
1900
    class_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
1881
1901
  }
1882
1902
  else
1883
1903
  {
1902
1922
        and we are comparing against a decimal
1903
1923
      */
1904
1924
      if (dec && range->type == DECIMAL_RESULT)
1905
 
        cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
 
1925
        cmp_result= class_decimal_cmp(&range->dec, dec) <= 0;
1906
1926
      else
1907
1927
        cmp_result= (range->dbl <= value);
1908
1928
      if (cmp_result)
1912
1932
    }
1913
1933
    interval_range *range= intervals+start;
1914
1934
    return ((dec && range->type == DECIMAL_RESULT) ?
1915
 
            my_decimal_cmp(dec, &range->dec) < 0 :
 
1935
            class_decimal_cmp(dec, &range->dec) < 0 :
1916
1936
            value < range->dbl) ? 0 : start + 1;
1917
1937
  }
1918
1938
 
1923
1943
        ((el->result_type() == DECIMAL_RESULT) ||
1924
1944
         (el->result_type() == INT_RESULT)))
1925
1945
    {
1926
 
      my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
 
1946
      type::Decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
1927
1947
      /* Skip NULL ranges. */
1928
1948
      if (el->null_value)
1929
1949
        continue;
1930
 
      if (my_decimal_cmp(e_dec, dec) > 0)
 
1950
      if (class_decimal_cmp(e_dec, dec) > 0)
1931
1951
        return i - 1;
1932
1952
    }
1933
1953
    else
1977
1997
  if (Item_func_opt_neg::fix_fields(session, ref))
1978
1998
    return 1;
1979
1999
 
1980
 
  session->lex->current_select->between_count++;
 
2000
  session->getLex()->current_select->between_count++;
1981
2001
 
1982
2002
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1983
2003
  if (pred_level && !negated)
1998
2018
  int i;
1999
2019
  bool datetime_found= false;
2000
2020
  compare_as_dates= true;
2001
 
  Session *session= current_session;
2002
2021
 
2003
2022
  /*
2004
2023
    As some compare functions are generated after sql_yacc,
2045
2064
        The following can't be recoded with || as convert_constant_item
2046
2065
        changes the argument
2047
2066
      */
2048
 
      if (convert_constant_item(session, field_item, &args[1]))
 
2067
      if (convert_constant_item(&getSession(), field_item, &args[1]))
2049
2068
        cmp_type=INT_RESULT;                    // Works for all types.
2050
 
      if (convert_constant_item(session, field_item, &args[2]))
 
2069
      if (convert_constant_item(&getSession(), field_item, &args[2]))
2051
2070
        cmp_type=INT_RESULT;                    // Works for all types.
2052
2071
    }
2053
2072
  }
2124
2143
  }
2125
2144
  else if (cmp_type == DECIMAL_RESULT)
2126
2145
  {
2127
 
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
 
2146
    type::Decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2128
2147
               a_buf, *a_dec, b_buf, *b_dec;
2129
2148
    if ((null_value=args[0]->null_value))
2130
2149
      return 0;
2131
2150
    a_dec= args[1]->val_decimal(&a_buf);
2132
2151
    b_dec= args[2]->val_decimal(&b_buf);
2133
2152
    if (!args[1]->null_value && !args[2]->null_value)
2134
 
      return (int64_t) ((my_decimal_cmp(dec, a_dec) >= 0 &&
2135
 
                          my_decimal_cmp(dec, b_dec) <= 0) != negated);
 
2153
      return (int64_t) ((class_decimal_cmp(dec, a_dec) >= 0 &&
 
2154
                          class_decimal_cmp(dec, b_dec) <= 0) != negated);
2136
2155
    if (args[1]->null_value && args[2]->null_value)
2137
2156
      null_value=1;
2138
2157
    else if (args[1]->null_value)
2139
 
      null_value= (my_decimal_cmp(dec, b_dec) <= 0);
 
2158
      null_value= (class_decimal_cmp(dec, b_dec) <= 0);
2140
2159
    else
2141
 
      null_value= (my_decimal_cmp(dec, a_dec) >= 0);
 
2160
      null_value= (class_decimal_cmp(dec, a_dec) >= 0);
2142
2161
  }
2143
2162
  else
2144
2163
  {
2272
2291
}
2273
2292
 
2274
2293
 
2275
 
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
 
2294
type::Decimal *Item_func_ifnull::decimal_op(type::Decimal *decimal_value)
2276
2295
{
2277
2296
  assert(fixed == 1);
2278
 
  my_decimal *value= args[0]->val_decimal(decimal_value);
 
2297
  type::Decimal *value= args[0]->val_decimal(decimal_value);
2279
2298
  if (!args[0]->null_value)
2280
2299
  {
2281
2300
    null_value= 0;
2445
2464
}
2446
2465
 
2447
2466
 
2448
 
my_decimal *
2449
 
Item_func_if::val_decimal(my_decimal *decimal_value)
 
2467
type::Decimal *
 
2468
Item_func_if::val_decimal(type::Decimal *decimal_value)
2450
2469
{
2451
2470
  assert(fixed == 1);
2452
2471
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
2453
 
  my_decimal *value= arg->val_decimal(decimal_value);
 
2472
  type::Decimal *value= arg->val_decimal(decimal_value);
2454
2473
  null_value= arg->null_value;
2455
2474
  return value;
2456
2475
}
2530
2549
}
2531
2550
 
2532
2551
 
2533
 
my_decimal *
2534
 
Item_func_nullif::val_decimal(my_decimal * decimal_value)
 
2552
type::Decimal *
 
2553
Item_func_nullif::val_decimal(type::Decimal * decimal_value)
2535
2554
{
2536
2555
  assert(fixed == 1);
2537
 
  my_decimal *res;
 
2556
  type::Decimal *res;
2538
2557
  if (!cmp.compare())
2539
2558
  {
2540
2559
    null_value=1;
2667
2686
}
2668
2687
 
2669
2688
 
2670
 
my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
 
2689
type::Decimal *Item_func_case::val_decimal(type::Decimal *decimal_value)
2671
2690
{
2672
2691
  assert(fixed == 1);
2673
2692
  char buff[MAX_FIELD_WIDTH];
2674
2693
  String dummy_str(buff, sizeof(buff), default_charset());
2675
2694
  Item *item= find_item(&dummy_str);
2676
 
  my_decimal *res;
 
2695
  type::Decimal *res;
2677
2696
 
2678
2697
  if (!item)
2679
2698
  {
2716
2735
 
2717
2736
void Item_func_case::agg_num_lengths(Item *arg)
2718
2737
{
2719
 
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
 
2738
  uint32_t len= class_decimal_length_to_precision(arg->max_length, arg->decimals,
2720
2739
                                           arg->unsigned_flag) - arg->decimals;
2721
2740
  set_if_bigger(max_length, len);
2722
2741
  set_if_bigger(decimals, arg->decimals);
2799
2818
      agg_num_lengths(args[i + 1]);
2800
2819
    if (else_expr_num != -1)
2801
2820
      agg_num_lengths(args[else_expr_num]);
2802
 
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
 
2821
    max_length= class_decimal_precision_to_length(max_length + decimals, decimals,
2803
2822
                                               unsigned_flag);
2804
2823
  }
2805
2824
}
2906
2925
}
2907
2926
 
2908
2927
 
2909
 
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
 
2928
type::Decimal *Item_func_coalesce::decimal_op(type::Decimal *decimal_value)
2910
2929
{
2911
2930
  assert(fixed == 1);
2912
2931
  null_value= 0;
2913
2932
  for (uint32_t i= 0; i < arg_count; i++)
2914
2933
  {
2915
 
    my_decimal *res= args[i]->val_decimal(decimal_value);
 
2934
    type::Decimal *res= args[i]->val_decimal(decimal_value);
2916
2935
    if (!args[i]->null_value)
2917
2936
      return res;
2918
2937
  }
3061
3080
}
3062
3081
 
3063
3082
 
3064
 
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
 
3083
static int cmp_decimal(void *, type::Decimal *a, type::Decimal *b)
3065
3084
{
3066
3085
  /*
3067
3086
    We need call of fixing buffer pointer, because fast sort just copy
3069
3088
  */
3070
3089
  a->fix_buffer_pointer();
3071
3090
  b->fix_buffer_pointer();
3072
 
  return my_decimal_cmp(a, b);
 
3091
  return class_decimal_cmp(a, b);
3073
3092
}
3074
3093
 
3075
3094
 
3177
3196
  return;
3178
3197
}
3179
3198
 
3180
 
in_int64_t::in_int64_t(uint32_t elements)
3181
 
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
 
3199
in_int64_t::in_int64_t(uint32_t elements) :
 
3200
  in_vector(elements, sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3182
3201
{}
3183
3202
 
3184
3203
void in_int64_t::set(uint32_t pos,Item *item)
3198
3217
  return (unsigned char*) &tmp;
3199
3218
}
3200
3219
 
3201
 
void in_datetime::set(uint32_t pos,Item *item)
 
3220
in_datetime::in_datetime(Item *warn_item_arg, uint32_t elements) :
 
3221
  in_int64_t(elements),
 
3222
  session(current_session),
 
3223
  warn_item(warn_item_arg),
 
3224
  lval_cache(0)
 
3225
{}
 
3226
 
 
3227
void in_datetime::set(uint32_t pos, Item *item)
3202
3228
{
3203
3229
  Item **tmp_item= &item;
3204
3230
  bool is_null;
3238
3264
 
3239
3265
 
3240
3266
in_decimal::in_decimal(uint32_t elements)
3241
 
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
 
3267
  :in_vector(elements, sizeof(type::Decimal),(qsort2_cmp) cmp_decimal, 0)
3242
3268
{}
3243
3269
 
3244
3270
 
3245
3271
void in_decimal::set(uint32_t pos, Item *item)
3246
3272
{
3247
 
  /* as far as 'item' is constant, we can store reference on my_decimal */
3248
 
  my_decimal *dec= ((my_decimal *)base) + pos;
 
3273
  /* as far as 'item' is constant, we can store reference on type::Decimal */
 
3274
  type::Decimal *dec= ((type::Decimal *)base) + pos;
3249
3275
  dec->len= DECIMAL_BUFF_LENGTH;
3250
3276
  dec->fix_buffer_pointer();
3251
 
  my_decimal *res= item->val_decimal(dec);
 
3277
  type::Decimal *res= item->val_decimal(dec);
3252
3278
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
3253
3279
  if (!item->null_value && res != dec)
3254
 
    my_decimal2decimal(res, dec);
 
3280
    class_decimal2decimal(res, dec);
3255
3281
}
3256
3282
 
3257
3283
 
3258
3284
unsigned char *in_decimal::get_value(Item *item)
3259
3285
{
3260
 
  my_decimal *result= item->val_decimal(&val);
 
3286
  type::Decimal *result= item->val_decimal(&val);
3261
3287
  if (item->null_value)
3262
3288
    return 0;
3263
3289
  return (unsigned char *)result;
3416
3442
 
3417
3443
void cmp_item_decimal::store_value(Item *item)
3418
3444
{
3419
 
  my_decimal *val= item->val_decimal(&value);
 
3445
  type::Decimal *val= item->val_decimal(&value);
3420
3446
  /* val may be zero if item is nnull */
3421
3447
  if (val && val != &value)
3422
 
    my_decimal2decimal(val, &value);
 
3448
    class_decimal2decimal(val, &value);
3423
3449
}
3424
3450
 
3425
3451
 
3426
3452
int cmp_item_decimal::cmp(Item *arg)
3427
3453
{
3428
 
  my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
 
3454
  type::Decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
3429
3455
  if (arg->null_value)
3430
3456
    return 1;
3431
 
  return my_decimal_cmp(&value, tmp);
 
3457
  return class_decimal_cmp(&value, tmp);
3432
3458
}
3433
3459
 
3434
3460
 
3435
3461
int cmp_item_decimal::compare(cmp_item *arg)
3436
3462
{
3437
3463
  cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
3438
 
  return my_decimal_cmp(&value, &l_cmp->value);
 
3464
  return class_decimal_cmp(&value, &l_cmp->value);
3439
3465
}
3440
3466
 
3441
3467
 
3548
3574
{
3549
3575
  Item **arg, **arg_end;
3550
3576
  bool const_itm= 1;
3551
 
  Session *session= current_session;
3552
3577
  bool datetime_found= false;
3553
3578
  /* true <=> arguments values will be compared as DATETIMEs. */
3554
3579
  bool compare_as_datetime= false;
3696
3721
          bool all_converted= true;
3697
3722
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3698
3723
          {
3699
 
            if (!convert_constant_item (session, field_item, &arg[0]))
 
3724
            if (!convert_constant_item (&getSession(), field_item, &arg[0]))
3700
3725
              all_converted= false;
3701
3726
          }
3702
3727
          if (all_converted)
3733
3758
      }
3734
3759
    }
3735
3760
 
3736
 
    if (array && !(session->is_fatal_error))            // If not EOM
 
3761
    if (array && !(getSession().is_fatal_error))                // If not EOM
3737
3762
    {
3738
3763
      uint32_t j=0;
3739
3764
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3849
3874
 
3850
3875
 
3851
3876
Item_cond::Item_cond(Session *session, Item_cond *item)
3852
 
  :Item_bool_func(session, item),
 
3877
  :item::function::Boolean(session, item),
3853
3878
   abort_on_null(item->abort_on_null),
3854
3879
   and_tables_cache(item->and_tables_cache)
3855
3880
{
3861
3886
 
3862
3887
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3863
3888
{
3864
 
  List_iterator_fast<Item> li(item->list);
 
3889
  List<Item>::iterator li(item->list.begin());
3865
3890
  while (Item *it= li++)
3866
3891
    list.push_back(it->copy_andor_structure(session));
3867
3892
}
3871
3896
Item_cond::fix_fields(Session *session, Item **)
3872
3897
{
3873
3898
  assert(fixed == 0);
3874
 
  List_iterator<Item> li(list);
 
3899
  List<Item>::iterator li(list.begin());
3875
3900
  Item *item;
3876
3901
  void *orig_session_marker= session->session_marker;
3877
3902
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3878
3903
  not_null_tables_cache= used_tables_cache= 0;
3879
 
  const_item_cache= 1;
 
3904
  const_item_cache= true;
3880
3905
 
3881
3906
  if (functype() == COND_OR_FUNC)
3882
3907
    session->session_marker= 0;
3911
3936
           !((Item_cond*) item)->list.is_empty())
3912
3937
    {                                           // Identical function
3913
3938
      li.replace(((Item_cond*) item)->list);
3914
 
      ((Item_cond*) item)->list.empty();
 
3939
      ((Item_cond*) item)->list.clear();
3915
3940
      item= *li.ref();                          // new current item
3916
3941
    }
3917
3942
    if (abort_on_null)
3937
3962
    if (item->maybe_null)
3938
3963
      maybe_null=1;
3939
3964
  }
3940
 
  session->lex->current_select->cond_count+= list.elements;
 
3965
  session->getLex()->current_select->cond_count+= list.size();
3941
3966
  session->session_marker= orig_session_marker;
3942
3967
  fix_length_and_dec();
3943
3968
  fixed= 1;
3947
3972
 
3948
3973
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3949
3974
{
3950
 
  List_iterator<Item> li(list);
 
3975
  List<Item>::iterator li(list.begin());
3951
3976
  Item *item;
3952
3977
 
3953
3978
  used_tables_cache=0;
3954
 
  const_item_cache=1;
 
3979
  const_item_cache= true;
3955
3980
 
3956
3981
  and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
3957
3982
  not_null_tables_cache= 0;
3979
4004
 
3980
4005
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
3981
4006
{
3982
 
  List_iterator_fast<Item> li(list);
 
4007
  List<Item>::iterator li(list.begin());
3983
4008
  Item *item;
3984
4009
  while ((item= li++))
3985
4010
    if (item->walk(processor, walk_subquery, arg))
4008
4033
 
4009
4034
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4010
4035
{
4011
 
  List_iterator<Item> li(list);
 
4036
  List<Item>::iterator li(list.begin());
4012
4037
  Item *item;
4013
4038
  while ((item= li++))
4014
4039
  {
4023
4048
      change records at each execution.
4024
4049
    */
4025
4050
    if (new_item != item)
4026
 
      current_session->change_item_tree(li.ref(), new_item);
 
4051
      getSession().change_item_tree(li.ref(), new_item);
4027
4052
  }
4028
4053
  return Item_func::transform(transformer, arg);
4029
4054
}
4059
4084
  if (!(this->*analyzer)(arg_p))
4060
4085
    return 0;
4061
4086
 
4062
 
  List_iterator<Item> li(list);
 
4087
  List<Item>::iterator li(list.begin());
4063
4088
  Item *item;
4064
4089
  while ((item= li++))
4065
4090
  {
4078
4103
void Item_cond::traverse_cond(Cond_traverser traverser,
4079
4104
                              void *arg, traverse_order order)
4080
4105
{
4081
 
  List_iterator<Item> li(list);
 
4106
  List<Item>::iterator li(list.begin());
4082
4107
  Item *item;
4083
4108
 
4084
4109
  switch (order) {
4119
4144
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4120
4145
                               List<Item> &fields)
4121
4146
{
4122
 
  List_iterator<Item> li(list);
 
4147
  List<Item>::iterator li(list.begin());
4123
4148
  Item *item;
4124
4149
  while ((item= li++))
4125
4150
    item->split_sum_func(session, ref_pointer_array,
4136
4161
 
4137
4162
void Item_cond::update_used_tables()
4138
4163
{
4139
 
  List_iterator_fast<Item> li(list);
 
4164
  List<Item>::iterator li(list.begin());
4140
4165
  Item *item;
4141
4166
 
4142
4167
  used_tables_cache=0;
4143
 
  const_item_cache=1;
 
4168
  const_item_cache= true;
4144
4169
  while ((item=li++))
4145
4170
  {
4146
4171
    item->update_used_tables();
4153
4178
void Item_cond::print(String *str, enum_query_type query_type)
4154
4179
{
4155
4180
  str->append('(');
4156
 
  List_iterator_fast<Item> li(list);
 
4181
  List<Item>::iterator li(list.begin());
4157
4182
  Item *item;
4158
4183
  if ((item=li++))
4159
4184
    item->print(str, query_type);
4170
4195
 
4171
4196
void Item_cond::neg_arguments(Session *session)
4172
4197
{
4173
 
  List_iterator<Item> li(list);
 
4198
  List<Item>::iterator li(list.begin());
4174
4199
  Item *item;
4175
4200
  while ((item= li++))          /* Apply not transformation to the arguments */
4176
4201
  {
4208
4233
int64_t Item_cond_and::val_int()
4209
4234
{
4210
4235
  assert(fixed == 1);
4211
 
  List_iterator_fast<Item> li(list);
 
4236
  List<Item>::iterator li(list.begin());
4212
4237
  Item *item;
4213
4238
  null_value= 0;
4214
4239
  while ((item=li++))
4226
4251
int64_t Item_cond_or::val_int()
4227
4252
{
4228
4253
  assert(fixed == 1);
4229
 
  List_iterator_fast<Item> li(list);
 
4254
  List<Item>::iterator li(list.begin());
4230
4255
  Item *item;
4231
4256
  null_value=0;
4232
4257
  while ((item=li++))
4463
4488
      {
4464
4489
        pattern     = first + 1;
4465
4490
        pattern_len = (int) len - 2;
4466
 
        int *suff = (int*) session->alloc((int) (sizeof(int)*
4467
 
                                      ((pattern_len + 1)*2+
4468
 
                                      alphabet_size)));
 
4491
        int *suff = (int*) session->getMemRoot()->allocate((int) (sizeof(int)*
 
4492
                                                                  ((pattern_len + 1)*2+
 
4493
                                                                   alphabet_size)));
4469
4494
        bmGs      = suff + pattern_len + 1;
4470
4495
        bmBc      = bmGs + pattern_len + 1;
4471
4496
        turboBM_compute_good_suffix_shifts(suff);
4482
4507
  Item_bool_func2::cleanup();
4483
4508
}
4484
4509
 
 
4510
static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
 
4511
{
4485
4512
#ifdef LIKE_CMP_TOUPPER
4486
 
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
 
4513
  return cs->toupper(a);
4487
4514
#else
4488
 
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
 
4515
  return cs->sort_order[a];
4489
4516
#endif
4490
 
 
 
4517
}
4491
4518
 
4492
4519
/**
4493
4520
  Precomputation dependent only on pattern_len.
4624
4651
 
4625
4652
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
4626
4653
{
4627
 
  register int bcShift;
4628
 
  register int turboShift;
 
4654
  int bcShift;
 
4655
  int turboShift;
4629
4656
  int shift = pattern_len;
4630
4657
  int j     = 0;
4631
4658
  int u     = 0;
4639
4666
  {
4640
4667
    while (j <= tlmpl)
4641
4668
    {
4642
 
      register int i= plm1;
 
4669
      int i= plm1;
4643
4670
      while (i >= 0 && pattern[i] == text[i + j])
4644
4671
      {
4645
4672
        i--;
4649
4676
      if (i < 0)
4650
4677
        return 1;
4651
4678
 
4652
 
      register const int v = plm1 - i;
 
4679
      const int v = plm1 - i;
4653
4680
      turboShift = u - v;
4654
4681
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
4655
4682
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4670
4697
  {
4671
4698
    while (j <= tlmpl)
4672
4699
    {
4673
 
      register int i = plm1;
 
4700
      int i = plm1;
4674
4701
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4675
4702
      {
4676
4703
        i--;
4681
4708
      if (i < 0)
4682
4709
        return 1;
4683
4710
 
4684
 
      register const int v= plm1 - i;
 
4711
      const int v= plm1 - i;
4685
4712
      turboShift= u - v;
4686
4713
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4687
4714
      shift= (turboShift > bcShift) ? turboShift : bcShift;
4722
4749
int64_t Item_cond_xor::val_int()
4723
4750
{
4724
4751
  assert(fixed == 1);
4725
 
  List_iterator<Item> li(list);
 
4752
  List<Item>::iterator li(list.begin());
4726
4753
  Item *item;
4727
4754
  int result=0;
4728
4755
  null_value=0;
4882
4909
}
4883
4910
 
4884
4911
Item_equal::Item_equal(Item_field *f1, Item_field *f2)
4885
 
  : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
 
4912
  : item::function::Boolean(), const_item(0), eval_item(0), cond_false(0)
4886
4913
{
4887
 
  const_item_cache= 0;
 
4914
  const_item_cache= false;
4888
4915
  fields.push_back(f1);
4889
4916
  fields.push_back(f2);
4890
4917
}
4891
4918
 
4892
4919
Item_equal::Item_equal(Item *c, Item_field *f)
4893
 
  : Item_bool_func(), eval_item(0), cond_false(0)
 
4920
  : item::function::Boolean(), eval_item(0), cond_false(0)
4894
4921
{
4895
 
  const_item_cache= 0;
 
4922
  const_item_cache= false;
4896
4923
  fields.push_back(f);
4897
4924
  const_item= c;
4898
4925
}
4899
4926
 
4900
4927
 
4901
4928
Item_equal::Item_equal(Item_equal *item_equal)
4902
 
  : Item_bool_func(), eval_item(0), cond_false(0)
 
4929
  : item::function::Boolean(), eval_item(0), cond_false(0)
4903
4930
{
4904
 
  const_item_cache= 0;
4905
 
  List_iterator_fast<Item_field> li(item_equal->fields);
 
4931
  const_item_cache= false;
 
4932
  List<Item_field>::iterator li(item_equal->fields.begin());
4906
4933
  Item_field *item;
4907
4934
  while ((item= li++))
4908
4935
  {
4925
4952
  func->set_cmp_func();
4926
4953
  func->quick_fix_field();
4927
4954
  if ((cond_false= !func->val_int()))
4928
 
    const_item_cache= 1;
 
4955
    const_item_cache= true;
4929
4956
}
4930
4957
 
4931
4958
void Item_equal::add(Item_field *f)
4935
4962
 
4936
4963
uint32_t Item_equal::members()
4937
4964
{
4938
 
  return fields.elements;
 
4965
  return fields.size();
4939
4966
}
4940
4967
 
4941
4968
 
4954
4981
 
4955
4982
bool Item_equal::contains(Field *field)
4956
4983
{
4957
 
  List_iterator_fast<Item_field> it(fields);
 
4984
  List<Item_field>::iterator it(fields.begin());
4958
4985
  Item_field *item;
4959
4986
  while ((item= it++))
4960
4987
  {
5013
5040
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
5014
5041
{
5015
5042
  bool swap;
5016
 
  List_iterator<Item_field> it(fields);
 
5043
  List<Item_field>::iterator it(fields.begin());
5017
5044
  do
5018
5045
  {
5019
5046
    Item_field *item1= it++;
5037
5064
        ref1= ref2;
5038
5065
      }
5039
5066
    }
5040
 
    it.rewind();
 
5067
    it= fields.begin();
5041
5068
  } while (swap);
5042
5069
}
5043
5070
 
5054
5081
 
5055
5082
void Item_equal::update_const()
5056
5083
{
5057
 
  List_iterator<Item_field> it(fields);
 
5084
  List<Item_field>::iterator it(fields.begin());
5058
5085
  Item *item;
5059
5086
  while ((item= it++))
5060
5087
  {
5068
5095
 
5069
5096
bool Item_equal::fix_fields(Session *, Item **)
5070
5097
{
5071
 
  List_iterator_fast<Item_field> li(fields);
 
5098
  List<Item_field>::iterator li(fields.begin());
5072
5099
  Item *item;
5073
5100
  not_null_tables_cache= used_tables_cache= 0;
5074
 
  const_item_cache= 0;
 
5101
  const_item_cache= false;
5075
5102
  while ((item= li++))
5076
5103
  {
5077
5104
    table_map tmp_table_map;
5088
5115
 
5089
5116
void Item_equal::update_used_tables()
5090
5117
{
5091
 
  List_iterator_fast<Item_field> li(fields);
 
5118
  List<Item_field>::iterator li(fields.begin());
5092
5119
  Item *item;
5093
5120
  not_null_tables_cache= used_tables_cache= 0;
5094
5121
  if ((const_item_cache= cond_false))
5106
5133
  Item_field *item_field;
5107
5134
  if (cond_false)
5108
5135
    return 0;
5109
 
  List_iterator_fast<Item_field> it(fields);
 
5136
  List<Item_field>::iterator it(fields.begin());
5110
5137
  Item *item= const_item ? const_item : it++;
 
5138
  eval_item->store_value(item);
5111
5139
  if ((null_value= item->null_value))
5112
5140
    return 0;
5113
 
  eval_item->store_value(item);
5114
5141
  while ((item_field= it++))
5115
5142
  {
5116
5143
    /* Skip fields of non-const tables. They haven't been read yet */
5117
5144
    if (item_field->field->getTable()->const_table)
5118
5145
    {
5119
 
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
 
5146
      if (eval_item->cmp(item_field) || (null_value= item_field->null_value))
5120
5147
        return 0;
5121
5148
    }
5122
5149
  }
5132
5159
 
5133
5160
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
5134
5161
{
5135
 
  List_iterator_fast<Item_field> it(fields);
 
5162
  List<Item_field>::iterator it(fields.begin());
5136
5163
  Item *item;
5137
5164
  while ((item= it++))
5138
5165
  {
5144
5171
 
5145
5172
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
5146
5173
{
5147
 
  List_iterator<Item_field> it(fields);
 
5174
  List<Item_field>::iterator it(fields.begin());
5148
5175
  Item *item;
5149
5176
  while ((item= it++))
5150
5177
  {
5159
5186
      change records at each execution.
5160
5187
    */
5161
5188
    if (new_item != item)
5162
 
      current_session->change_item_tree((Item **) it.ref(), new_item);
 
5189
      getSession().change_item_tree((Item **) it.ref(), new_item);
5163
5190
  }
5164
5191
  return Item_func::transform(transformer, arg);
5165
5192
}
5168
5195
{
5169
5196
  str->append(func_name());
5170
5197
  str->append('(');
5171
 
  List_iterator_fast<Item_field> it(fields);
 
5198
  List<Item_field>::iterator it(fields.begin());
5172
5199
  Item *item;
5173
5200
  if (const_item)
5174
5201
    const_item->print(str, query_type);
5186
5213
  str->append(')');
5187
5214
}
5188
5215
 
 
5216
cmp_item_datetime::cmp_item_datetime(Item *warn_item_arg) :
 
5217
  session(current_session),
 
5218
  warn_item(warn_item_arg),
 
5219
  lval_cache(0)
 
5220
{}
 
5221
 
5189
5222
} /* namespace drizzled */