~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Brian Aker
  • Date: 2009-05-21 19:15:01 UTC
  • mfrom: (991.1.12 for-brian)
  • Revision ID: brian@gaz-20090521191501-u5qe56byfubioj1r
Merge Stewart

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/**
21
21
  This file defines all compare functions
22
22
*/
23
23
 
24
 
#include "config.h"
 
24
#include "drizzled/server_includes.h"
25
25
#include "drizzled/sql_select.h"
26
26
#include "drizzled/error.h"
27
27
#include "drizzled/temporal.h"
29
29
#include "drizzled/cached_item.h"
30
30
#include "drizzled/item/cache_int.h"
31
31
#include "drizzled/item/int_with_ref.h"
 
32
#include "drizzled/function/bit.h"
32
33
#include "drizzled/check_stack_overrun.h"
33
 
#include "drizzled/time_functions.h"
34
 
#include "drizzled/internal/my_sys.h"
35
 
#include <math.h>
36
 
#include <algorithm>
37
 
 
38
 
using namespace std;
39
 
 
40
 
namespace drizzled
41
 
{
42
 
 
43
 
extern const double log_10[309];
 
34
 
44
35
 
45
36
static Eq_creator eq_creator;
46
37
static Ne_creator ne_creator;
209
200
    collect_cmp_types()
210
201
      items             Array of items to collect types from
211
202
      nitems            Number of items in the array
212
 
      skip_nulls        Don't collect types of NULL items if TRUE
213
203
 
214
204
  DESCRIPTION
215
205
    This function collects different result types for comparison of the first
220
210
    Bitmap of collected types - otherwise
221
211
*/
222
212
 
223
 
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
 
213
static uint32_t collect_cmp_types(Item **items, uint32_t nitems)
224
214
{
225
215
  uint32_t i;
226
216
  uint32_t found_types;
229
219
  found_types= 0;
230
220
  for (i= 1; i < nitems ; i++)
231
221
  {
232
 
    if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
233
 
      continue; // Skip NULL constant items
234
222
    if ((left_result == ROW_RESULT ||
235
223
         items[i]->result_type() == ROW_RESULT) &&
236
224
        cmp_row_type(items[0], items[i]))
238
226
    found_types|= 1<< (uint32_t)item_cmp_type(left_result,
239
227
                                           items[i]->result_type());
240
228
  }
241
 
  /*
242
 
   Even if all right-hand items are NULLs and we are skipping them all, we need
243
 
   at least one type bit in the found_type bitmask.
244
 
  */
245
 
  if (skip_nulls && !found_types)
246
 
    found_types= 1 << (uint)left_result;
247
229
  return found_types;
248
230
}
249
231
 
445
427
  Field *field= field_item->field;
446
428
  int result= 0;
447
429
 
448
 
  field->setWriteSet();
449
 
 
450
430
  if (!(*item)->with_subselect && (*item)->const_item())
451
431
  {
452
432
    ulong orig_sql_mode= session->variables.sql_mode;
570
550
{
571
551
  owner= item;
572
552
  func= comparator_matrix[type]
573
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
574
 
 
 
553
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
575
554
  switch (type) {
576
555
  case ROW_RESULT:
577
 
    {
578
 
      uint32_t n= (*a)->cols();
579
 
      if (n != (*b)->cols())
580
 
      {
581
 
        my_error(ER_OPERAND_COLUMNS, MYF(0), n);
582
 
        comparators= 0;
583
 
        return 1;
584
 
      }
585
 
      if (!(comparators= new Arg_comparator[n]))
586
 
        return 1;
587
 
      for (uint32_t i=0; i < n; i++)
588
 
      {
589
 
        if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
590
 
        {
591
 
          my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
592
 
          return 1;
593
 
        }
594
 
        comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
595
 
      }
596
 
      break;
597
 
    }
598
 
 
 
556
  {
 
557
    uint32_t n= (*a)->cols();
 
558
    if (n != (*b)->cols())
 
559
    {
 
560
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
 
561
      comparators= 0;
 
562
      return 1;
 
563
    }
 
564
    if (!(comparators= new Arg_comparator[n]))
 
565
      return 1;
 
566
    for (uint32_t i=0; i < n; i++)
 
567
    {
 
568
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
 
569
      {
 
570
        my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
 
571
        return 1;
 
572
      }
 
573
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
 
574
    }
 
575
    break;
 
576
  }
599
577
  case STRING_RESULT:
 
578
  {
 
579
    /*
 
580
      We must set cmp_charset here as we may be called from for an automatic
 
581
      generated item, like in natural join
 
582
    */
 
583
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
 
584
        cmp_collation.derivation == DERIVATION_NONE)
 
585
    {
 
586
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
 
587
      return 1;
 
588
    }
 
589
    if (cmp_collation.collation == &my_charset_bin)
600
590
    {
601
591
      /*
602
 
        We must set cmp_charset here as we may be called from for an automatic
603
 
        generated item, like in natural join
 
592
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
593
        without removing end space
604
594
      */
605
 
      if (cmp_collation.set((*a)->collation, (*b)->collation) ||
606
 
          cmp_collation.derivation == DERIVATION_NONE)
607
 
      {
608
 
        my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
609
 
        return 1;
610
 
      }
611
 
      if (cmp_collation.collation == &my_charset_bin)
612
 
      {
613
 
        /*
614
 
          We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
615
 
          without removing end space
616
 
        */
617
 
        if (func == &Arg_comparator::compare_string)
618
 
          func= &Arg_comparator::compare_binary_string;
619
 
        else if (func == &Arg_comparator::compare_e_string)
620
 
          func= &Arg_comparator::compare_e_binary_string;
 
595
      if (func == &Arg_comparator::compare_string)
 
596
        func= &Arg_comparator::compare_binary_string;
 
597
      else if (func == &Arg_comparator::compare_e_string)
 
598
        func= &Arg_comparator::compare_e_binary_string;
621
599
 
622
 
        /*
623
 
          As this is binary compassion, mark all fields that they can't be
624
 
          transformed. Otherwise we would get into trouble with comparisons
625
 
like:
626
 
WHERE col= 'j' AND col LIKE BINARY 'j'
627
 
which would be transformed to:
628
 
WHERE col= 'j'
 
600
      /*
 
601
        As this is binary compassion, mark all fields that they can't be
 
602
        transformed. Otherwise we would get into trouble with comparisons
 
603
        like:
 
604
        WHERE col= 'j' AND col LIKE BINARY 'j'
 
605
        which would be transformed to:
 
606
        WHERE col= 'j'
629
607
      */
630
 
        (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
631
 
        (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
632
 
      }
633
 
      break;
 
608
      (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
 
609
      (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
634
610
    }
 
611
    break;
 
612
  }
635
613
  case INT_RESULT:
636
 
    {
637
 
      if (func == &Arg_comparator::compare_int_signed)
638
 
      {
639
 
        if ((*a)->unsigned_flag)
640
 
          func= (((*b)->unsigned_flag)?
641
 
                 &Arg_comparator::compare_int_unsigned :
642
 
                 &Arg_comparator::compare_int_unsigned_signed);
643
 
        else if ((*b)->unsigned_flag)
644
 
          func= &Arg_comparator::compare_int_signed_unsigned;
645
 
      }
646
 
      else if (func== &Arg_comparator::compare_e_int)
647
 
      {
648
 
        if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
649
 
          func= &Arg_comparator::compare_e_int_diff_signedness;
650
 
      }
651
 
      break;
652
 
    }
 
614
  {
 
615
    if (func == &Arg_comparator::compare_int_signed)
 
616
    {
 
617
      if ((*a)->unsigned_flag)
 
618
        func= (((*b)->unsigned_flag)?
 
619
               &Arg_comparator::compare_int_unsigned :
 
620
               &Arg_comparator::compare_int_unsigned_signed);
 
621
      else if ((*b)->unsigned_flag)
 
622
        func= &Arg_comparator::compare_int_signed_unsigned;
 
623
    }
 
624
    else if (func== &Arg_comparator::compare_e_int)
 
625
    {
 
626
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
 
627
        func= &Arg_comparator::compare_e_int_diff_signedness;
 
628
    }
 
629
    break;
 
630
  }
653
631
  case DECIMAL_RESULT:
654
632
    break;
655
633
  case REAL_RESULT:
 
634
  {
 
635
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
656
636
    {
657
 
      if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
658
 
      {
659
 
        precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
660
 
        if (func == &Arg_comparator::compare_real)
661
 
          func= &Arg_comparator::compare_real_fixed;
662
 
        else if (func == &Arg_comparator::compare_e_real)
663
 
          func= &Arg_comparator::compare_e_real_fixed;
664
 
      }
665
 
      break;
 
637
      precision= 5 / log_10[cmax((*a)->decimals, (*b)->decimals) + 1];
 
638
      if (func == &Arg_comparator::compare_real)
 
639
        func= &Arg_comparator::compare_real_fixed;
 
640
      else if (func == &Arg_comparator::compare_e_real)
 
641
        func= &Arg_comparator::compare_e_real_fixed;
666
642
    }
667
 
  }
668
 
 
 
643
    break;
 
644
  }
 
645
  default:
 
646
    assert(0);
 
647
  }
669
648
  return 0;
670
649
}
671
650
 
722
701
  }
723
702
 
724
703
  if (error > 0)
725
 
  {
726
704
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
727
705
                                 str->ptr(), str->length(),
728
706
                                 warn_type, warn_name);
729
 
  }
730
707
 
731
708
  return value;
732
709
}
765
742
*/
766
743
 
767
744
enum Arg_comparator::enum_date_cmp_type
768
 
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
769
 
                                     uint64_t *const_value)
 
745
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
770
746
{
771
747
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
772
748
  Item *str_arg= 0, *date_arg= 0;
773
749
 
774
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
750
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
775
751
    return CMP_DATE_DFLT;
776
752
 
777
 
  if (in_a->is_datetime())
 
753
  if (a->is_datetime())
778
754
  {
779
 
    if (in_b->is_datetime())
 
755
    if (b->is_datetime())
780
756
      cmp_type= CMP_DATE_WITH_DATE;
781
 
    else if (in_b->result_type() == STRING_RESULT)
 
757
    else if (b->result_type() == STRING_RESULT)
782
758
    {
783
759
      cmp_type= CMP_DATE_WITH_STR;
784
 
      date_arg= in_a;
785
 
      str_arg= in_b;
 
760
      date_arg= a;
 
761
      str_arg= b;
786
762
    }
787
763
  }
788
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
764
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
789
765
  {
790
766
    cmp_type= CMP_STR_WITH_DATE;
791
 
    date_arg= in_b;
792
 
    str_arg= in_a;
 
767
    date_arg= b;
 
768
    str_arg= a;
793
769
  }
794
770
 
795
771
  if (cmp_type != CMP_DATE_DFLT)
823
799
      String *str_val;
824
800
      String tmp;
825
801
      /* DateTime used to pick up as many string conversion possibilities as possible. */
826
 
      DateTime temporal;
 
802
      drizzled::DateTime temporal;
827
803
 
828
804
      str_val= str_arg->val_str(&tmp);
829
805
      if (! str_val)
857
833
}
858
834
 
859
835
 
 
836
/*
 
837
  Retrieves correct TIME value from the given item.
 
838
 
 
839
  SYNOPSIS
 
840
    get_time_value()
 
841
    session                 thread handle
 
842
    item_arg   [in/out] item to retrieve TIME value from
 
843
    cache_arg  [in/out] pointer to place to store the cache item to
 
844
    warn_item  [in]     unused
 
845
    is_null    [out]    true <=> the item_arg is null
 
846
 
 
847
  DESCRIPTION
 
848
    Retrieves the correct TIME value from given item for comparison by the
 
849
    compare_datetime() function.
 
850
    If item's result can be compared as int64_t then its int value is used
 
851
    and a value returned by get_time function is used otherwise.
 
852
    If an item is a constant one then its value is cached and it isn't
 
853
    get parsed again. An Item_cache_int object is used for for cached values.
 
854
    It seamlessly substitutes the original item.  The cache item is marked as
 
855
    non-constant to prevent re-caching it again.
 
856
 
 
857
  RETURN
 
858
    obtained value
 
859
*/
 
860
 
 
861
uint64_t
 
862
get_time_value(Session *,
 
863
               Item ***item_arg, Item **cache_arg,
 
864
               Item *, bool *is_null)
 
865
{
 
866
  uint64_t value;
 
867
  Item *item= **item_arg;
 
868
  DRIZZLE_TIME ltime;
 
869
 
 
870
  if (item->result_as_int64_t())
 
871
  {
 
872
    value= item->val_int();
 
873
    *is_null= item->null_value;
 
874
  }
 
875
  else
 
876
  {
 
877
    *is_null= item->get_time(&ltime);
 
878
    value= !*is_null ? TIME_to_uint64_t_datetime(&ltime) : 0;
 
879
  }
 
880
  /*
 
881
    Do not cache GET_USER_VAR() function as its const_item() may return true
 
882
    for the current thread but it still may change during the execution.
 
883
  */
 
884
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
 
885
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
 
886
  {
 
887
    Item_cache_int *cache= new Item_cache_int();
 
888
    /* Mark the cache as non-const to prevent re-caching. */
 
889
    cache->set_used_tables(1);
 
890
    cache->store(item, value);
 
891
    *cache_arg= cache;
 
892
    *item_arg= cache_arg;
 
893
  }
 
894
  return value;
 
895
}
 
896
 
 
897
 
860
898
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
861
899
                                        Item **a1, Item **a2,
862
900
                                        Item_result type)
1066
1104
  /* Compare values. */
1067
1105
  if (is_nulls_eq)
1068
1106
    return (a_value == b_value);
1069
 
  return (a_value < b_value) ? -1 : ((a_value > b_value) ? 1 : 0);
 
1107
  return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
1070
1108
}
1071
1109
 
1072
1110
 
1107
1145
      owner->null_value= 0;
1108
1146
      uint32_t res1_length= res1->length();
1109
1147
      uint32_t res2_length= res2->length();
1110
 
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
 
1148
      int cmp= memcmp(res1->ptr(), res2->ptr(), cmin(res1_length,res2_length));
1111
1149
      return cmp ? cmp : (int) (res1_length - res2_length);
1112
1150
    }
1113
1151
  }
1806
1844
 
1807
1845
    if (not_null_consts &&
1808
1846
        (intervals=
1809
 
          (interval_range*) memory::sql_alloc(sizeof(interval_range) * (rows - 1))))
 
1847
          (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
1810
1848
    {
1811
1849
      if (use_decimal_comparison)
1812
1850
      {
2036
2074
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2037
2075
    le_cmp.set_datetime_cmp_func(args, args + 2);
2038
2076
  }
2039
 
  else if (args[0]->real_item()->type() == FIELD_ITEM)
 
2077
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
 
2078
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2040
2079
  {
2041
2080
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2042
2081
    if (field_item->field->can_be_compared_as_int64_t())
2106
2145
  {
2107
2146
    int64_t value=args[0]->val_int(), a, b;
2108
2147
    if ((null_value=args[0]->null_value))
2109
 
      return 0;
 
2148
      return 0;                                 /* purecov: inspected */
2110
2149
    a=args[1]->val_int();
2111
2150
    b=args[2]->val_int();
2112
2151
    if (!args[1]->null_value && !args[2]->null_value)
2127
2166
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2128
2167
               a_buf, *a_dec, b_buf, *b_dec;
2129
2168
    if ((null_value=args[0]->null_value))
2130
 
      return 0;
 
2169
      return 0;                                 /* purecov: inspected */
2131
2170
    a_dec= args[1]->val_decimal(&a_buf);
2132
2171
    b_dec= args[2]->val_decimal(&b_buf);
2133
2172
    if (!args[1]->null_value && !args[2]->null_value)
2144
2183
  {
2145
2184
    double value= args[0]->val_real(),a,b;
2146
2185
    if ((null_value=args[0]->null_value))
2147
 
      return 0;
 
2186
      return 0;                                 /* purecov: inspected */
2148
2187
    a= args[1]->val_real();
2149
2188
    b= args[2]->val_real();
2150
2189
    if (!args[1]->null_value && !args[2]->null_value)
2181
2220
Item_func_ifnull::fix_length_and_dec()
2182
2221
{
2183
2222
  agg_result_type(&hybrid_type, args, 2);
2184
 
  maybe_null= args[1]->maybe_null;
2185
 
  decimals= max(args[0]->decimals, args[1]->decimals);
 
2223
  maybe_null=args[1]->maybe_null;
 
2224
  decimals= cmax(args[0]->decimals, args[1]->decimals);
2186
2225
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2187
2226
 
2188
2227
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2193
2232
    int len1= args[1]->max_length - args[1]->decimals
2194
2233
      - (args[1]->unsigned_flag ? 0 : 1);
2195
2234
 
2196
 
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
 
2235
    max_length= cmax(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2197
2236
  }
2198
2237
  else
2199
 
  {
2200
 
    max_length= max(args[0]->max_length, args[1]->max_length);
2201
 
  }
 
2238
    max_length= cmax(args[0]->max_length, args[1]->max_length);
2202
2239
 
2203
 
  switch (hybrid_type)
2204
 
  {
 
2240
  switch (hybrid_type) {
2205
2241
  case STRING_RESULT:
2206
2242
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2207
2243
    break;
2208
 
 
2209
2244
  case DECIMAL_RESULT:
2210
2245
  case REAL_RESULT:
2211
2246
    break;
2212
 
 
2213
2247
  case INT_RESULT:
2214
2248
    decimals= 0;
2215
2249
    break;
2216
 
 
2217
2250
  case ROW_RESULT:
 
2251
  default:
2218
2252
    assert(0);
2219
2253
  }
2220
 
 
2221
2254
  cached_field_type= agg_field_type(args, 2);
2222
2255
}
2223
2256
 
2224
2257
 
2225
2258
uint32_t Item_func_ifnull::decimal_precision() const
2226
2259
{
2227
 
  int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2228
 
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
2260
  int max_int_part=cmax(args[0]->decimal_int_part(),args[1]->decimal_int_part());
 
2261
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2229
2262
}
2230
2263
 
2231
2264
 
2352
2385
void
2353
2386
Item_func_if::fix_length_and_dec()
2354
2387
{
2355
 
  maybe_null= args[1]->maybe_null || args[2]->maybe_null;
2356
 
  decimals= max(args[1]->decimals, args[2]->decimals);
2357
 
  unsigned_flag= args[1]->unsigned_flag && args[2]->unsigned_flag;
 
2388
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
 
2389
  decimals= cmax(args[1]->decimals, args[2]->decimals);
 
2390
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2358
2391
 
2359
 
  enum Item_result arg1_type= args[1]->result_type();
2360
 
  enum Item_result arg2_type= args[2]->result_type();
2361
 
  bool null1= args[1]->const_item() && args[1]->null_value;
2362
 
  bool null2= args[2]->const_item() && args[2]->null_value;
 
2392
  enum Item_result arg1_type=args[1]->result_type();
 
2393
  enum Item_result arg2_type=args[2]->result_type();
 
2394
  bool null1=args[1]->const_item() && args[1]->null_value;
 
2395
  bool null2=args[2]->const_item() && args[2]->null_value;
2363
2396
 
2364
2397
  if (null1)
2365
2398
  {
2397
2430
    int len2= args[2]->max_length - args[2]->decimals
2398
2431
      - (args[2]->unsigned_flag ? 0 : 1);
2399
2432
 
2400
 
    max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2433
    max_length=cmax(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2401
2434
  }
2402
2435
  else
2403
 
    max_length= max(args[1]->max_length, args[2]->max_length);
 
2436
    max_length= cmax(args[1]->max_length, args[2]->max_length);
2404
2437
}
2405
2438
 
2406
2439
 
2407
2440
uint32_t Item_func_if::decimal_precision() const
2408
2441
{
2409
 
  int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2410
 
                  decimals);
2411
 
  return min(precision, DECIMAL_MAX_PRECISION);
 
2442
  int precision=(cmax(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
 
2443
                 decimals);
 
2444
  return cmin(precision, DECIMAL_MAX_PRECISION);
2412
2445
}
2413
2446
 
2414
2447
 
2729
2762
  Item **agg;
2730
2763
  uint32_t nagg;
2731
2764
  uint32_t found_types= 0;
2732
 
  if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
 
2765
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2733
2766
    return;
2734
2767
 
2735
2768
  /*
2755
2788
  */
2756
2789
  if (first_expr_num != -1)
2757
2790
  {
 
2791
    uint32_t i;
2758
2792
    agg[0]= args[first_expr_num];
2759
2793
    left_result_type= agg[0]->result_type();
2760
2794
 
2764
2798
    if (!(found_types= collect_cmp_types(agg, nagg)))
2765
2799
      return;
2766
2800
 
2767
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2801
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2768
2802
    {
2769
2803
      if (found_types & (1 << i) && !cmp_items[i])
2770
2804
      {
2813
2847
 
2814
2848
  if (else_expr_num != -1)
2815
2849
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2816
 
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
2850
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2817
2851
}
2818
2852
 
2819
2853
 
2850
2884
 
2851
2885
void Item_func_case::cleanup()
2852
2886
{
 
2887
  uint32_t i;
2853
2888
  Item_func::cleanup();
2854
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2889
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2855
2890
  {
2856
2891
    delete cmp_items[i];
2857
2892
    cmp_items[i]= 0;
2858
2893
  }
 
2894
  return;
2859
2895
}
2860
2896
 
2861
2897
 
2925
2961
{
2926
2962
  cached_field_type= agg_field_type(args, arg_count);
2927
2963
  agg_result_type(&hybrid_type, args, arg_count);
2928
 
 
2929
2964
  switch (hybrid_type) {
2930
2965
  case STRING_RESULT:
2931
2966
    count_only_length();
2932
2967
    decimals= NOT_FIXED_DEC;
2933
2968
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2934
2969
    break;
2935
 
 
2936
2970
  case DECIMAL_RESULT:
2937
2971
    count_decimal_length();
2938
2972
    break;
2939
 
 
2940
2973
  case REAL_RESULT:
2941
2974
    count_real_length();
2942
2975
    break;
2943
 
 
2944
2976
  case INT_RESULT:
2945
2977
    count_only_length();
2946
2978
    decimals= 0;
2947
2979
    break;
2948
 
 
2949
2980
  case ROW_RESULT:
 
2981
  default:
2950
2982
    assert(0);
2951
2983
  }
2952
2984
}
3073
3105
}
3074
3106
 
3075
3107
 
3076
 
void in_vector::sort()
3077
 
{
3078
 
  internal::my_qsort2(base,used_count,size,compare, (void *) collation);
3079
 
}
3080
 
 
3081
 
 
3082
3108
int in_vector::find(Item *item)
3083
3109
{
3084
3110
  unsigned char *result=get_value(item);
3110
3136
{
3111
3137
  if (base)
3112
3138
  {
3113
 
    // base was allocated with help of memory::sql_alloc => following is OK
 
3139
    // base was allocated with help of sql_alloc => following is OK
3114
3140
    for (uint32_t i=0 ; i < count ; i++)
3115
3141
      ((String*) base)[i].free();
3116
3142
  }
3232
3258
{
3233
3259
  tmp= item->val_real();
3234
3260
  if (item->null_value)
3235
 
    return 0;
 
3261
    return 0;                                   /* purecov: inspected */
3236
3262
  return (unsigned char*) &tmp;
3237
3263
}
3238
3264
 
3270
3296
  switch (type) {
3271
3297
  case STRING_RESULT:
3272
3298
    return new cmp_item_sort_string(cs);
3273
 
 
3274
3299
  case INT_RESULT:
3275
3300
    return new cmp_item_int;
3276
 
 
3277
3301
  case REAL_RESULT:
3278
3302
    return new cmp_item_real;
3279
 
 
3280
3303
  case ROW_RESULT:
3281
3304
    return new cmp_item_row;
3282
 
 
3283
3305
  case DECIMAL_RESULT:
3284
3306
    return new cmp_item_decimal;
 
3307
  default:
 
3308
    assert(0);
 
3309
    break;
3285
3310
  }
3286
 
 
3287
3311
  return 0; // to satisfy compiler :)
3288
3312
}
3289
3313
 
3362
3386
    return;
3363
3387
  }
3364
3388
  n= tmpl->n;
3365
 
  if ((comparators= (cmp_item **) memory::sql_alloc(sizeof(cmp_item *)*n)))
 
3389
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
3366
3390
  {
3367
3391
    item->bring_value();
3368
3392
    item->null_value= 0;
3554
3578
  bool compare_as_datetime= false;
3555
3579
  Item *date_arg= 0;
3556
3580
  uint32_t found_types= 0;
3557
 
  uint32_t type_cnt= 0;
 
3581
  uint32_t type_cnt= 0, i;
3558
3582
  Item_result cmp_type= STRING_RESULT;
3559
3583
  left_result_type= args[0]->result_type();
3560
 
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
 
3584
  if (!(found_types= collect_cmp_types(args, arg_count)))
3561
3585
    return;
3562
3586
 
3563
3587
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3568
3592
      break;
3569
3593
    }
3570
3594
  }
3571
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3595
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
3572
3596
  {
3573
3597
    if (found_types & 1 << i)
3574
3598
    {
3675
3699
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3676
3700
  {
3677
3701
    if (compare_as_datetime)
3678
 
    {
3679
3702
      array= new in_datetime(date_arg, arg_count - 1);
3680
 
    }
3681
3703
    else
3682
3704
    {
3683
3705
      /*
3688
3710
        comparison type accordingly.
3689
3711
      */
3690
3712
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3713
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3691
3714
          cmp_type != INT_RESULT)
3692
3715
      {
3693
3716
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3703
3726
            cmp_type= INT_RESULT;
3704
3727
        }
3705
3728
      }
3706
 
 
3707
3729
      switch (cmp_type) {
3708
3730
      case STRING_RESULT:
3709
3731
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3710
3732
                            cmp_collation.collation);
3711
3733
        break;
3712
 
 
3713
3734
      case INT_RESULT:
3714
3735
        array= new in_int64_t(arg_count-1);
3715
3736
        break;
3716
 
 
3717
3737
      case REAL_RESULT:
3718
3738
        array= new in_double(arg_count-1);
3719
3739
        break;
3720
 
 
3721
3740
      case ROW_RESULT:
3722
3741
        /*
3723
3742
          The row comparator was created at the beginning but only DATETIME
3726
3745
        */
3727
3746
        ((in_row*)array)->tmp.store_value(args[0]);
3728
3747
        break;
3729
 
 
3730
3748
      case DECIMAL_RESULT:
3731
3749
        array= new in_decimal(arg_count - 1);
3732
3750
        break;
 
3751
      default:
 
3752
        assert(0);
 
3753
        return;
3733
3754
      }
3734
3755
    }
3735
 
 
3736
3756
    if (array && !(session->is_fatal_error))            // If not EOM
3737
3757
    {
3738
3758
      uint32_t j=0;
3739
3759
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3740
3760
      {
3741
 
        if (!args[arg_num]->null_value)                 // Skip NULL values
3742
 
        {
3743
 
          array->set(j,args[arg_num]);
3744
 
          j++;
3745
 
        }
3746
 
        else
3747
 
          have_null= 1;
 
3761
        array->set(j,args[arg_num]);
 
3762
        if (!args[arg_num]->null_value)                 // Skip NULL values
 
3763
          j++;
 
3764
        else
 
3765
          have_null= 1;
3748
3766
      }
3749
3767
      if ((array->used_count= j))
3750
 
        array->sort();
 
3768
        array->sort();
3751
3769
    }
3752
3770
  }
3753
3771
  else
3756
3774
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3757
3775
    else
3758
3776
    {
3759
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3777
      for (i= 0; i <= (uint32_t) DECIMAL_RESULT; i++)
3760
3778
      {
3761
3779
        if (found_types & (1 << i) && !cmp_items[i])
3762
3780
        {
3848
3866
}
3849
3867
 
3850
3868
 
 
3869
int64_t Item_func_bit_or::val_int()
 
3870
{
 
3871
  assert(fixed == 1);
 
3872
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
3873
  if (args[0]->null_value)
 
3874
  {
 
3875
    null_value=1; /* purecov: inspected */
 
3876
    return 0; /* purecov: inspected */
 
3877
  }
 
3878
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
3879
  if (args[1]->null_value)
 
3880
  {
 
3881
    null_value=1;
 
3882
    return 0;
 
3883
  }
 
3884
  null_value=0;
 
3885
  return (int64_t) (arg1 | arg2);
 
3886
}
 
3887
 
 
3888
 
 
3889
int64_t Item_func_bit_and::val_int()
 
3890
{
 
3891
  assert(fixed == 1);
 
3892
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
3893
  if (args[0]->null_value)
 
3894
  {
 
3895
    null_value=1; /* purecov: inspected */
 
3896
    return 0; /* purecov: inspected */
 
3897
  }
 
3898
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
3899
  if (args[1]->null_value)
 
3900
  {
 
3901
    null_value=1; /* purecov: inspected */
 
3902
    return 0; /* purecov: inspected */
 
3903
  }
 
3904
  null_value=0;
 
3905
  return (int64_t) (arg1 & arg2);
 
3906
}
 
3907
 
3851
3908
Item_cond::Item_cond(Session *session, Item_cond *item)
3852
3909
  :Item_bool_func(session, item),
3853
3910
   abort_on_null(item->abort_on_null),
3921
3978
    if ((!item->fixed &&
3922
3979
         item->fix_fields(session, li.ref())) ||
3923
3980
        (item= *li.ref())->check_cols(1))
3924
 
      return true;
 
3981
      return true; /* purecov: inspected */
3925
3982
    used_tables_cache|=     item->used_tables();
3926
3983
    if (item->const_item())
3927
3984
      and_tables_cache= (table_map) 0;
4369
4426
  if (canDoTurboBM)
4370
4427
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4371
4428
  return my_wildcmp(cmp.cmp_collation.collation,
4372
 
                    res->ptr(),res->ptr()+res->length(),
 
4429
                    res->ptr(),res->ptr()+res->length(),
4373
4430
                    res2->ptr(),res2->ptr()+res2->length(),
4374
 
                    make_escape_code(cmp.cmp_collation.collation, escape),
4375
 
                    internal::wild_one,internal::wild_many) ? 0 : 1;
 
4431
                    escape,wild_one,wild_many) ? 0 : 1;
4376
4432
}
4377
4433
 
4378
4434
 
4389
4445
    if (!res2)
4390
4446
      return OPTIMIZE_NONE;
4391
4447
 
4392
 
    if (*res2->ptr() != internal::wild_many)
 
4448
    if (*res2->ptr() != wild_many)
4393
4449
    {
4394
 
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != internal::wild_one)
 
4450
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
4395
4451
        return OPTIMIZE_OP;
4396
4452
    }
4397
4453
  }
4414
4470
 
4415
4471
  if (escape_item->const_item())
4416
4472
  {
4417
 
    
4418
4473
    /* If we are on execution stage */
4419
4474
    String *escape_str= escape_item->val_str(&tmp_value1);
4420
4475
    if (escape_str)
4421
4476
    {
4422
 
      escape= (char *)memory::sql_alloc(escape_str->length());
4423
 
      strcpy(escape, escape_str->ptr()); 
 
4477
      if (escape_used_in_parsing && escape_str->numchars() > 1)
 
4478
      {
 
4479
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
 
4480
        return true;
 
4481
      }
 
4482
 
 
4483
      if (use_mb(cmp.cmp_collation.collation))
 
4484
      {
 
4485
        const CHARSET_INFO * const cs= escape_str->charset();
 
4486
        my_wc_t wc;
 
4487
        int rc= cs->cset->mb_wc(cs, &wc,
 
4488
                                (const unsigned char*) escape_str->ptr(),
 
4489
                                (const unsigned char*) escape_str->ptr() +
 
4490
                                               escape_str->length());
 
4491
        escape= (int) (rc > 0 ? wc : '\\');
 
4492
      }
 
4493
      else
 
4494
      {
 
4495
        /*
 
4496
          In the case of 8bit character set, we pass native
 
4497
          code instead of Unicode code as "escape" argument.
 
4498
          Convert to "cs" if charset of escape differs.
 
4499
        */
 
4500
        const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4501
        uint32_t unused;
 
4502
        if (escape_str->needs_conversion(escape_str->length(),
 
4503
                                         escape_str->charset(), cs, &unused))
 
4504
        {
 
4505
          char ch;
 
4506
          uint32_t errors;
 
4507
          uint32_t cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
 
4508
                                          escape_str->length(),
 
4509
                                          escape_str->charset(), &errors);
 
4510
          escape= cnvlen ? ch : '\\';
 
4511
        }
 
4512
        else
 
4513
          escape= *(escape_str->ptr());
 
4514
      }
4424
4515
    }
4425
4516
    else
4426
 
    {
4427
 
      escape= (char *)memory::sql_alloc(1);
4428
 
      strcpy(escape, "\\");
4429
 
    } 
4430
 
   
 
4517
      escape= '\\';
 
4518
 
4431
4519
    /*
4432
4520
      We could also do boyer-more for non-const items, but as we would have to
4433
4521
      recompute the tables for each row it's not worth it.
4447
4535
      */
4448
4536
 
4449
4537
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4450
 
          *first == internal::wild_many &&
4451
 
          *last  == internal::wild_many)
 
4538
          *first == wild_many &&
 
4539
          *last  == wild_many)
4452
4540
      {
4453
4541
        const char* tmp = first + 1;
4454
 
        for (; *tmp != internal::wild_many && *tmp != internal::wild_one; tmp++)
4455
 
        {
4456
 
          if (escape == tmp)
4457
 
            break;
4458
 
        }
4459
 
  
 
4542
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
4460
4543
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
4461
4544
      }
4462
4545
      if (canDoTurboBM)
4505
4588
 
4506
4589
  if (!cs->sort_order)
4507
4590
  {
4508
 
    for (int i = pattern_len - 2; i >= 0; i--)
 
4591
    int i;
 
4592
    for (i = pattern_len - 2; i >= 0; i--)
4509
4593
    {
4510
4594
      int tmp = *(splm1 + i - f);
4511
4595
      if (g < i && tmp < i - g)
4512
 
        suff[i] = tmp;
 
4596
        suff[i] = tmp;
4513
4597
      else
4514
4598
      {
4515
 
        if (i < g)
4516
 
          g = i;
4517
 
        f = i;
4518
 
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4519
 
          g--;
4520
 
        suff[i] = f - g;
 
4599
        if (i < g)
 
4600
          g = i; // g = cmin(i, g)
 
4601
        f = i;
 
4602
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
 
4603
          g--;
 
4604
        suff[i] = f - g;
4521
4605
      }
4522
4606
    }
4523
4607
  }
4524
4608
  else
4525
4609
  {
4526
 
    for (int i = pattern_len - 2; 0 <= i; --i)
 
4610
    int i;
 
4611
    for (i = pattern_len - 2; 0 <= i; --i)
4527
4612
    {
4528
4613
      int tmp = *(splm1 + i - f);
4529
4614
      if (g < i && tmp < i - g)
4530
 
        suff[i] = tmp;
 
4615
        suff[i] = tmp;
4531
4616
      else
4532
4617
      {
4533
 
        if (i < g)
4534
 
          g = i;
4535
 
        f = i;
4536
 
        while (g >= 0 &&
4537
 
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4538
 
          g--;
4539
 
        suff[i] = f - g;
 
4618
        if (i < g)
 
4619
          g = i; // g = cmin(i, g)
 
4620
        f = i;
 
4621
        while (g >= 0 &&
 
4622
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
 
4623
          g--;
 
4624
        suff[i] = f - g;
4540
4625
      }
4541
4626
    }
4542
4627
  }
4658
4743
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4659
4744
      else
4660
4745
      {
4661
 
        if (turboShift < bcShift)
4662
 
          shift= max(shift, u + 1);
4663
 
        u = 0;
 
4746
        if (turboShift < bcShift)
 
4747
          shift = cmax(shift, u + 1);
 
4748
        u = 0;
4664
4749
      }
4665
4750
      j+= shift;
4666
4751
    }
4673
4758
      register int i = plm1;
4674
4759
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4675
4760
      {
4676
 
        i--;
4677
 
        if (i == plm1 - shift)
4678
 
          i-= u;
 
4761
        i--;
 
4762
        if (i == plm1 - shift)
 
4763
          i-= u;
4679
4764
      }
4680
 
 
4681
4765
      if (i < 0)
4682
 
        return 1;
 
4766
        return 1;
4683
4767
 
4684
 
      register const int v= plm1 - i;
4685
 
      turboShift= u - v;
4686
 
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4687
 
      shift= (turboShift > bcShift) ? turboShift : bcShift;
4688
 
      shift= max(shift, bmGs[i]);
4689
 
      
 
4768
      register const int v = plm1 - i;
 
4769
      turboShift = u - v;
 
4770
      bcShift    = bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
 
4771
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
 
4772
      shift      = cmax(shift, bmGs[i]);
4690
4773
      if (shift == bmGs[i])
4691
 
        u= (pattern_len - shift < v) ? pattern_len - shift : v;
 
4774
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4692
4775
      else
4693
4776
      {
4694
 
        if (turboShift < bcShift)
4695
 
          shift= max(shift, u + 1);
4696
 
        u = 0;
 
4777
        if (turboShift < bcShift)
 
4778
          shift = cmax(shift, u + 1);
 
4779
        u = 0;
4697
4780
      }
4698
 
 
4699
4781
      j+= shift;
4700
4782
    }
4701
4783
    return 0;
5114
5196
  while ((item_field= it++))
5115
5197
  {
5116
5198
    /* Skip fields of non-const tables. They haven't been read yet */
5117
 
    if (item_field->field->getTable()->const_table)
 
5199
    if (item_field->field->table->const_table)
5118
5200
    {
5119
5201
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5120
5202
        return 0;
5186
5268
  str->append(')');
5187
5269
}
5188
5270
 
5189
 
} /* namespace drizzled */