~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Olaf van der Spek
  • Date: 2011-02-12 17:09:31 UTC
  • mto: (2167.1.2 build) (2172.1.4 build)
  • mto: This revision was merged to the branch mainline in revision 2168.
  • Revision ID: olafvdspek@gmail.com-20110212170931-k1fg0lzsmm5i3ciq
casts

Show diffs side-by-side

added added

removed removed

Lines of Context:
493
493
void Item_bool_func2::fix_length_and_dec()
494
494
{
495
495
  max_length= 1;                                     // Function returns 0 or 1
496
 
  Session *session;
497
496
 
498
497
  /*
499
498
    As some compare functions are generated after sql_yacc,
531
530
    return;
532
531
  }
533
532
 
534
 
  session= current_session;
535
533
  Item_field *field_item= NULL;
536
534
 
537
535
  if (args[0]->real_item()->type() == FIELD_ITEM)
540
538
    if (field_item->field->can_be_compared_as_int64_t() &&
541
539
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
542
540
    {
543
 
      if (convert_constant_item(session, field_item, &args[1]))
 
541
      if (convert_constant_item(&getSession(), field_item, &args[1]))
544
542
      {
545
543
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
546
544
                         INT_RESULT);           // Works for all types.
556
554
          !(field_item->is_datetime() &&
557
555
            args[0]->result_type() == STRING_RESULT))
558
556
      {
559
 
        if (convert_constant_item(session, field_item, &args[0]))
 
557
        if (convert_constant_item(&getSession(), field_item, &args[0]))
560
558
        {
561
559
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
562
560
                           INT_RESULT); // Works for all types.
696
694
    converted value. 0 on error and on zero-dates -- check 'failure'
697
695
*/
698
696
 
699
 
static uint64_t
700
 
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
 
697
static int64_t
 
698
get_date_from_str(Session *session, String *str, type::timestamp_t warn_type,
701
699
                  char *warn_name, bool *error_arg)
702
700
{
703
 
  uint64_t value= 0;
704
 
  int error;
 
701
  int64_t value= 0;
 
702
  type::cut_t error= type::VALID;
705
703
  type::Time l_time;
706
 
  enum enum_drizzle_timestamp_type ret;
707
 
 
708
 
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
709
 
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
710
 
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
711
 
                       &error);
712
 
 
713
 
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
 
704
  type::timestamp_t ret;
 
705
 
 
706
  ret= l_time.store(str->ptr(), str->length(),
 
707
                    (TIME_FUZZY_DATE | MODE_INVALID_DATES | (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
708
                    error);
 
709
 
 
710
  if (ret == type::DRIZZLE_TIMESTAMP_DATETIME || ret == type::DRIZZLE_TIMESTAMP_DATE)
714
711
  {
715
712
    /*
716
713
      Do not return yet, we may still want to throw a "trailing garbage"
717
714
      warning.
718
715
    */
719
716
    *error_arg= false;
720
 
    value= TIME_to_uint64_t_datetime(&l_time);
 
717
    l_time.convert(value);
721
718
  }
722
719
  else
723
720
  {
724
721
    *error_arg= true;
725
 
    error= 1;                                   /* force warning */
 
722
    error= type::CUT;                                   /* force warning */
726
723
  }
727
724
 
728
 
  if (error > 0)
 
725
  if (error != type::VALID)
729
726
  {
730
727
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
731
728
                                 str->ptr(), str->length(),
770
767
 
771
768
enum Arg_comparator::enum_date_cmp_type
772
769
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
773
 
                                     uint64_t *const_value)
 
770
                                     int64_t *const_value)
774
771
{
775
772
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
776
773
  Item *str_arg= 0, *date_arg= 0;
781
778
  if (in_a->is_datetime())
782
779
  {
783
780
    if (in_b->is_datetime())
 
781
    {
784
782
      cmp_type= CMP_DATE_WITH_DATE;
 
783
    }
785
784
    else if (in_b->result_type() == STRING_RESULT)
786
785
    {
787
786
      cmp_type= CMP_DATE_WITH_STR;
823
822
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
824
823
       * from val_int(), not uint64_t...
825
824
       */
826
 
      uint64_t value;
 
825
      int64_t value;
827
826
      String *str_val;
828
827
      String tmp;
829
828
      /* DateTime used to pick up as many string conversion possibilities as possible. */
849
848
      }
850
849
 
851
850
      /* String conversion was good.  Convert to an integer for comparison purposes. */
852
 
      int64_t int_value;
853
 
      temporal.to_int64_t(&int_value);
854
 
      value= (uint64_t) int_value;
 
851
      temporal.to_int64_t(&value);
855
852
 
856
853
      if (const_value)
857
854
        *const_value= value;
865
862
                                        Item **a1, Item **a2,
866
863
                                        Item_result type)
867
864
{
868
 
  enum enum_date_cmp_type cmp_type;
869
 
  uint64_t const_value= (uint64_t)-1;
 
865
  enum_date_cmp_type cmp_type;
 
866
  int64_t const_value= -1;
870
867
  a= a1;
871
868
  b= a2;
872
869
 
873
870
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
874
871
  {
875
 
    session= current_session;
876
872
    owner= owner_arg;
877
873
    a_type= (*a)->field_type();
878
874
    b_type= (*b)->field_type();
879
875
    a_cache= 0;
880
876
    b_cache= 0;
881
877
 
882
 
    if (const_value != (uint64_t)-1)
 
878
    if (const_value != -1)
883
879
    {
884
880
      Item_cache_int *cache= new Item_cache_int();
885
881
      /* Mark the cache as non-const to prevent re-caching. */
900
896
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
901
897
    func= &Arg_comparator::compare_datetime;
902
898
    get_value_func= &get_datetime_value;
 
899
 
903
900
    return 0;
904
901
  }
905
902
 
909
906
 
910
907
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
911
908
{
912
 
  session= current_session;
913
909
  /* A caller will handle null values by itself. */
914
910
  owner= NULL;
915
911
  a= a1;
953
949
    obtained value
954
950
*/
955
951
 
956
 
uint64_t
 
952
int64_t
957
953
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
958
954
                   Item *warn_item, bool *is_null)
959
955
{
960
 
  uint64_t value= 0;
 
956
  int64_t value= 0;
961
957
  String buf, *str= 0;
962
958
  Item *item= **item_arg;
963
959
 
981
977
    str= item->val_str(&buf);
982
978
    *is_null= item->null_value;
983
979
  }
 
980
 
984
981
  if (*is_null)
985
982
    return ~(uint64_t) 0;
 
983
 
986
984
  /*
987
985
    Convert strings to the integer DATE/DATETIME representation.
988
986
    Even if both dates provided in strings we can't compare them directly as
993
991
  {
994
992
    bool error;
995
993
    enum_field_types f_type= warn_item->field_type();
996
 
    enum enum_drizzle_timestamp_type t_type= f_type ==
997
 
      DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
 
994
    type::timestamp_t t_type= f_type == DRIZZLE_TYPE_DATE ? type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME;
998
995
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
999
996
    /*
1000
997
      If str did not contain a valid date according to the current
1017
1014
    *cache_arg= cache;
1018
1015
    *item_arg= cache_arg;
1019
1016
  }
 
1017
 
1020
1018
  return value;
1021
1019
}
1022
1020
 
1668
1666
    change records at each execution.
1669
1667
  */
1670
1668
  if ((*args) != new_item)
1671
 
    current_session->change_item_tree(args, new_item);
 
1669
    getSession().change_item_tree(args, new_item);
1672
1670
 
1673
1671
  /*
1674
1672
    Transform the right IN operand which should be an Item_in_subselect or a
2002
2000
  int i;
2003
2001
  bool datetime_found= false;
2004
2002
  compare_as_dates= true;
2005
 
  Session *session= current_session;
2006
2003
 
2007
2004
  /*
2008
2005
    As some compare functions are generated after sql_yacc,
2049
2046
        The following can't be recoded with || as convert_constant_item
2050
2047
        changes the argument
2051
2048
      */
2052
 
      if (convert_constant_item(session, field_item, &args[1]))
 
2049
      if (convert_constant_item(&getSession(), field_item, &args[1]))
2053
2050
        cmp_type=INT_RESULT;                    // Works for all types.
2054
 
      if (convert_constant_item(session, field_item, &args[2]))
 
2051
      if (convert_constant_item(&getSession(), field_item, &args[2]))
2055
2052
        cmp_type=INT_RESULT;                    // Works for all types.
2056
2053
    }
2057
2054
  }
3181
3178
  return;
3182
3179
}
3183
3180
 
3184
 
in_int64_t::in_int64_t(uint32_t elements)
3185
 
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
 
3181
in_int64_t::in_int64_t(uint32_t elements) :
 
3182
  in_vector(elements, sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3186
3183
{}
3187
3184
 
3188
3185
void in_int64_t::set(uint32_t pos,Item *item)
3202
3199
  return (unsigned char*) &tmp;
3203
3200
}
3204
3201
 
3205
 
void in_datetime::set(uint32_t pos,Item *item)
 
3202
void in_datetime::set(uint32_t pos, Item *item)
3206
3203
{
3207
3204
  Item **tmp_item= &item;
3208
3205
  bool is_null;
3552
3549
{
3553
3550
  Item **arg, **arg_end;
3554
3551
  bool const_itm= 1;
3555
 
  Session *session= current_session;
3556
3552
  bool datetime_found= false;
3557
3553
  /* true <=> arguments values will be compared as DATETIMEs. */
3558
3554
  bool compare_as_datetime= false;
3700
3696
          bool all_converted= true;
3701
3697
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3702
3698
          {
3703
 
            if (!convert_constant_item (session, field_item, &arg[0]))
 
3699
            if (!convert_constant_item (&getSession(), field_item, &arg[0]))
3704
3700
              all_converted= false;
3705
3701
          }
3706
3702
          if (all_converted)
3737
3733
      }
3738
3734
    }
3739
3735
 
3740
 
    if (array && !(session->is_fatal_error))            // If not EOM
 
3736
    if (array && !(getSession().is_fatal_error))                // If not EOM
3741
3737
    {
3742
3738
      uint32_t j=0;
3743
3739
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
4027
4023
      change records at each execution.
4028
4024
    */
4029
4025
    if (new_item != item)
4030
 
      current_session->change_item_tree(li.ref(), new_item);
 
4026
      getSession().change_item_tree(li.ref(), new_item);
4031
4027
  }
4032
4028
  return Item_func::transform(transformer, arg);
4033
4029
}
4486
4482
  Item_bool_func2::cleanup();
4487
4483
}
4488
4484
 
 
4485
static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
 
4486
{
4489
4487
#ifdef LIKE_CMP_TOUPPER
4490
 
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
 
4488
  return cs->toupper(a);
4491
4489
#else
4492
 
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
 
4490
  return cs->sort_order[a];
4493
4491
#endif
4494
 
 
 
4492
}
4495
4493
 
4496
4494
/**
4497
4495
  Precomputation dependent only on pattern_len.
5112
5110
    return 0;
5113
5111
  List_iterator_fast<Item_field> it(fields);
5114
5112
  Item *item= const_item ? const_item : it++;
 
5113
  eval_item->store_value(item);
5115
5114
  if ((null_value= item->null_value))
5116
5115
    return 0;
5117
 
  eval_item->store_value(item);
5118
5116
  while ((item_field= it++))
5119
5117
  {
5120
5118
    /* Skip fields of non-const tables. They haven't been read yet */
5121
5119
    if (item_field->field->getTable()->const_table)
5122
5120
    {
5123
 
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
 
5121
      if (eval_item->cmp(item_field) || (null_value= item_field->null_value))
5124
5122
        return 0;
5125
5123
    }
5126
5124
  }
5163
5161
      change records at each execution.
5164
5162
    */
5165
5163
    if (new_item != item)
5166
 
      current_session->change_item_tree((Item **) it.ref(), new_item);
 
5164
      getSession().change_item_tree((Item **) it.ref(), new_item);
5167
5165
  }
5168
5166
  return Item_func::transform(transformer, arg);
5169
5167
}