~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Brian Aker
  • Date: 2009-05-23 17:13:03 UTC
  • mfrom: (1034.1.8 merge)
  • Revision ID: brian@gaz-20090523171303-d28xhutqic0xe2b4
Merge Brian

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"
30
30
#include "drizzled/item/cache_int.h"
31
31
#include "drizzled/item/int_with_ref.h"
32
32
#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];
 
33
 
44
34
 
45
35
static Eq_creator eq_creator;
46
36
static Ne_creator ne_creator;
209
199
    collect_cmp_types()
210
200
      items             Array of items to collect types from
211
201
      nitems            Number of items in the array
212
 
      skip_nulls        Don't collect types of NULL items if TRUE
213
202
 
214
203
  DESCRIPTION
215
204
    This function collects different result types for comparison of the first
220
209
    Bitmap of collected types - otherwise
221
210
*/
222
211
 
223
 
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
 
212
static uint32_t collect_cmp_types(Item **items, uint32_t nitems)
224
213
{
225
214
  uint32_t i;
226
215
  uint32_t found_types;
229
218
  found_types= 0;
230
219
  for (i= 1; i < nitems ; i++)
231
220
  {
232
 
    if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
233
 
      continue; // Skip NULL constant items
234
221
    if ((left_result == ROW_RESULT ||
235
222
         items[i]->result_type() == ROW_RESULT) &&
236
223
        cmp_row_type(items[0], items[i]))
238
225
    found_types|= 1<< (uint32_t)item_cmp_type(left_result,
239
226
                                           items[i]->result_type());
240
227
  }
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
228
  return found_types;
248
229
}
249
230
 
445
426
  Field *field= field_item->field;
446
427
  int result= 0;
447
428
 
448
 
  field->setWriteSet();
449
 
 
450
429
  if (!(*item)->with_subselect && (*item)->const_item())
451
430
  {
452
431
    ulong orig_sql_mode= session->variables.sql_mode;
570
549
{
571
550
  owner= item;
572
551
  func= comparator_matrix[type]
573
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
574
 
 
 
552
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
575
553
  switch (type) {
576
554
  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
 
 
 
555
  {
 
556
    uint32_t n= (*a)->cols();
 
557
    if (n != (*b)->cols())
 
558
    {
 
559
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
 
560
      comparators= 0;
 
561
      return 1;
 
562
    }
 
563
    if (!(comparators= new Arg_comparator[n]))
 
564
      return 1;
 
565
    for (uint32_t i=0; i < n; i++)
 
566
    {
 
567
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
 
568
      {
 
569
        my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
 
570
        return 1;
 
571
      }
 
572
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
 
573
    }
 
574
    break;
 
575
  }
599
576
  case STRING_RESULT:
 
577
  {
 
578
    /*
 
579
      We must set cmp_charset here as we may be called from for an automatic
 
580
      generated item, like in natural join
 
581
    */
 
582
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
 
583
        cmp_collation.derivation == DERIVATION_NONE)
 
584
    {
 
585
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
 
586
      return 1;
 
587
    }
 
588
    if (cmp_collation.collation == &my_charset_bin)
600
589
    {
601
590
      /*
602
 
        We must set cmp_charset here as we may be called from for an automatic
603
 
        generated item, like in natural join
 
591
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
592
        without removing end space
604
593
      */
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;
 
594
      if (func == &Arg_comparator::compare_string)
 
595
        func= &Arg_comparator::compare_binary_string;
 
596
      else if (func == &Arg_comparator::compare_e_string)
 
597
        func= &Arg_comparator::compare_e_binary_string;
621
598
 
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'
 
599
      /*
 
600
        As this is binary compassion, mark all fields that they can't be
 
601
        transformed. Otherwise we would get into trouble with comparisons
 
602
        like:
 
603
        WHERE col= 'j' AND col LIKE BINARY 'j'
 
604
        which would be transformed to:
 
605
        WHERE col= 'j'
629
606
      */
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;
 
607
      (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
 
608
      (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
634
609
    }
 
610
    break;
 
611
  }
635
612
  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
 
    }
 
613
  {
 
614
    if (func == &Arg_comparator::compare_int_signed)
 
615
    {
 
616
      if ((*a)->unsigned_flag)
 
617
        func= (((*b)->unsigned_flag)?
 
618
               &Arg_comparator::compare_int_unsigned :
 
619
               &Arg_comparator::compare_int_unsigned_signed);
 
620
      else if ((*b)->unsigned_flag)
 
621
        func= &Arg_comparator::compare_int_signed_unsigned;
 
622
    }
 
623
    else if (func== &Arg_comparator::compare_e_int)
 
624
    {
 
625
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
 
626
        func= &Arg_comparator::compare_e_int_diff_signedness;
 
627
    }
 
628
    break;
 
629
  }
653
630
  case DECIMAL_RESULT:
654
631
    break;
655
632
  case REAL_RESULT:
 
633
  {
 
634
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
656
635
    {
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;
 
636
      precision= 5 / log_10[cmax((*a)->decimals, (*b)->decimals) + 1];
 
637
      if (func == &Arg_comparator::compare_real)
 
638
        func= &Arg_comparator::compare_real_fixed;
 
639
      else if (func == &Arg_comparator::compare_e_real)
 
640
        func= &Arg_comparator::compare_e_real_fixed;
666
641
    }
667
 
  }
668
 
 
 
642
    break;
 
643
  }
 
644
  default:
 
645
    assert(0);
 
646
  }
669
647
  return 0;
670
648
}
671
649
 
722
700
  }
723
701
 
724
702
  if (error > 0)
725
 
  {
726
703
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
727
704
                                 str->ptr(), str->length(),
728
705
                                 warn_type, warn_name);
729
 
  }
730
706
 
731
707
  return value;
732
708
}
765
741
*/
766
742
 
767
743
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)
 
744
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
770
745
{
771
746
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
772
747
  Item *str_arg= 0, *date_arg= 0;
773
748
 
774
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
749
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
775
750
    return CMP_DATE_DFLT;
776
751
 
777
 
  if (in_a->is_datetime())
 
752
  if (a->is_datetime())
778
753
  {
779
 
    if (in_b->is_datetime())
 
754
    if (b->is_datetime())
780
755
      cmp_type= CMP_DATE_WITH_DATE;
781
 
    else if (in_b->result_type() == STRING_RESULT)
 
756
    else if (b->result_type() == STRING_RESULT)
782
757
    {
783
758
      cmp_type= CMP_DATE_WITH_STR;
784
 
      date_arg= in_a;
785
 
      str_arg= in_b;
 
759
      date_arg= a;
 
760
      str_arg= b;
786
761
    }
787
762
  }
788
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
763
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
789
764
  {
790
765
    cmp_type= CMP_STR_WITH_DATE;
791
 
    date_arg= in_b;
792
 
    str_arg= in_a;
 
766
    date_arg= b;
 
767
    str_arg= a;
793
768
  }
794
769
 
795
770
  if (cmp_type != CMP_DATE_DFLT)
823
798
      String *str_val;
824
799
      String tmp;
825
800
      /* DateTime used to pick up as many string conversion possibilities as possible. */
826
 
      DateTime temporal;
 
801
      drizzled::DateTime temporal;
827
802
 
828
803
      str_val= str_arg->val_str(&tmp);
829
804
      if (! str_val)
857
832
}
858
833
 
859
834
 
 
835
/*
 
836
  Retrieves correct TIME value from the given item.
 
837
 
 
838
  SYNOPSIS
 
839
    get_time_value()
 
840
    session                 thread handle
 
841
    item_arg   [in/out] item to retrieve TIME value from
 
842
    cache_arg  [in/out] pointer to place to store the cache item to
 
843
    warn_item  [in]     unused
 
844
    is_null    [out]    true <=> the item_arg is null
 
845
 
 
846
  DESCRIPTION
 
847
    Retrieves the correct TIME value from given item for comparison by the
 
848
    compare_datetime() function.
 
849
    If item's result can be compared as int64_t then its int value is used
 
850
    and a value returned by get_time function is used otherwise.
 
851
    If an item is a constant one then its value is cached and it isn't
 
852
    get parsed again. An Item_cache_int object is used for for cached values.
 
853
    It seamlessly substitutes the original item.  The cache item is marked as
 
854
    non-constant to prevent re-caching it again.
 
855
 
 
856
  RETURN
 
857
    obtained value
 
858
*/
 
859
 
 
860
uint64_t
 
861
get_time_value(Session *,
 
862
               Item ***item_arg, Item **cache_arg,
 
863
               Item *, bool *is_null)
 
864
{
 
865
  uint64_t value;
 
866
  Item *item= **item_arg;
 
867
  DRIZZLE_TIME ltime;
 
868
 
 
869
  if (item->result_as_int64_t())
 
870
  {
 
871
    value= item->val_int();
 
872
    *is_null= item->null_value;
 
873
  }
 
874
  else
 
875
  {
 
876
    *is_null= item->get_time(&ltime);
 
877
    value= !*is_null ? TIME_to_uint64_t_datetime(&ltime) : 0;
 
878
  }
 
879
  /*
 
880
    Do not cache GET_USER_VAR() function as its const_item() may return true
 
881
    for the current thread but it still may change during the execution.
 
882
  */
 
883
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
 
884
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
 
885
  {
 
886
    Item_cache_int *cache= new Item_cache_int();
 
887
    /* Mark the cache as non-const to prevent re-caching. */
 
888
    cache->set_used_tables(1);
 
889
    cache->store(item, value);
 
890
    *cache_arg= cache;
 
891
    *item_arg= cache_arg;
 
892
  }
 
893
  return value;
 
894
}
 
895
 
 
896
 
860
897
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
861
898
                                        Item **a1, Item **a2,
862
899
                                        Item_result type)
1066
1103
  /* Compare values. */
1067
1104
  if (is_nulls_eq)
1068
1105
    return (a_value == b_value);
1069
 
  return (a_value < b_value) ? -1 : ((a_value > b_value) ? 1 : 0);
 
1106
  return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
1070
1107
}
1071
1108
 
1072
1109
 
1107
1144
      owner->null_value= 0;
1108
1145
      uint32_t res1_length= res1->length();
1109
1146
      uint32_t res2_length= res2->length();
1110
 
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
 
1147
      int cmp= memcmp(res1->ptr(), res2->ptr(), cmin(res1_length,res2_length));
1111
1148
      return cmp ? cmp : (int) (res1_length - res2_length);
1112
1149
    }
1113
1150
  }
1806
1843
 
1807
1844
    if (not_null_consts &&
1808
1845
        (intervals=
1809
 
          (interval_range*) memory::sql_alloc(sizeof(interval_range) * (rows - 1))))
 
1846
          (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
1810
1847
    {
1811
1848
      if (use_decimal_comparison)
1812
1849
      {
2036
2073
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2037
2074
    le_cmp.set_datetime_cmp_func(args, args + 2);
2038
2075
  }
2039
 
  else if (args[0]->real_item()->type() == FIELD_ITEM)
 
2076
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
 
2077
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2040
2078
  {
2041
2079
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2042
2080
    if (field_item->field->can_be_compared_as_int64_t())
2106
2144
  {
2107
2145
    int64_t value=args[0]->val_int(), a, b;
2108
2146
    if ((null_value=args[0]->null_value))
2109
 
      return 0;
 
2147
      return 0;                                 /* purecov: inspected */
2110
2148
    a=args[1]->val_int();
2111
2149
    b=args[2]->val_int();
2112
2150
    if (!args[1]->null_value && !args[2]->null_value)
2127
2165
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2128
2166
               a_buf, *a_dec, b_buf, *b_dec;
2129
2167
    if ((null_value=args[0]->null_value))
2130
 
      return 0;
 
2168
      return 0;                                 /* purecov: inspected */
2131
2169
    a_dec= args[1]->val_decimal(&a_buf);
2132
2170
    b_dec= args[2]->val_decimal(&b_buf);
2133
2171
    if (!args[1]->null_value && !args[2]->null_value)
2144
2182
  {
2145
2183
    double value= args[0]->val_real(),a,b;
2146
2184
    if ((null_value=args[0]->null_value))
2147
 
      return 0;
 
2185
      return 0;                                 /* purecov: inspected */
2148
2186
    a= args[1]->val_real();
2149
2187
    b= args[2]->val_real();
2150
2188
    if (!args[1]->null_value && !args[2]->null_value)
2181
2219
Item_func_ifnull::fix_length_and_dec()
2182
2220
{
2183
2221
  agg_result_type(&hybrid_type, args, 2);
2184
 
  maybe_null= args[1]->maybe_null;
2185
 
  decimals= max(args[0]->decimals, args[1]->decimals);
 
2222
  maybe_null=args[1]->maybe_null;
 
2223
  decimals= cmax(args[0]->decimals, args[1]->decimals);
2186
2224
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2187
2225
 
2188
2226
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2193
2231
    int len1= args[1]->max_length - args[1]->decimals
2194
2232
      - (args[1]->unsigned_flag ? 0 : 1);
2195
2233
 
2196
 
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
 
2234
    max_length= cmax(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2197
2235
  }
2198
2236
  else
2199
 
  {
2200
 
    max_length= max(args[0]->max_length, args[1]->max_length);
2201
 
  }
 
2237
    max_length= cmax(args[0]->max_length, args[1]->max_length);
2202
2238
 
2203
 
  switch (hybrid_type)
2204
 
  {
 
2239
  switch (hybrid_type) {
2205
2240
  case STRING_RESULT:
2206
2241
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2207
2242
    break;
2208
 
 
2209
2243
  case DECIMAL_RESULT:
2210
2244
  case REAL_RESULT:
2211
2245
    break;
2212
 
 
2213
2246
  case INT_RESULT:
2214
2247
    decimals= 0;
2215
2248
    break;
2216
 
 
2217
2249
  case ROW_RESULT:
 
2250
  default:
2218
2251
    assert(0);
2219
2252
  }
2220
 
 
2221
2253
  cached_field_type= agg_field_type(args, 2);
2222
2254
}
2223
2255
 
2224
2256
 
2225
2257
uint32_t Item_func_ifnull::decimal_precision() const
2226
2258
{
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);
 
2259
  int max_int_part=cmax(args[0]->decimal_int_part(),args[1]->decimal_int_part());
 
2260
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2229
2261
}
2230
2262
 
2231
2263
 
2352
2384
void
2353
2385
Item_func_if::fix_length_and_dec()
2354
2386
{
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;
 
2387
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
 
2388
  decimals= cmax(args[1]->decimals, args[2]->decimals);
 
2389
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2358
2390
 
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;
 
2391
  enum Item_result arg1_type=args[1]->result_type();
 
2392
  enum Item_result arg2_type=args[2]->result_type();
 
2393
  bool null1=args[1]->const_item() && args[1]->null_value;
 
2394
  bool null2=args[2]->const_item() && args[2]->null_value;
2363
2395
 
2364
2396
  if (null1)
2365
2397
  {
2397
2429
    int len2= args[2]->max_length - args[2]->decimals
2398
2430
      - (args[2]->unsigned_flag ? 0 : 1);
2399
2431
 
2400
 
    max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2432
    max_length=cmax(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2401
2433
  }
2402
2434
  else
2403
 
    max_length= max(args[1]->max_length, args[2]->max_length);
 
2435
    max_length= cmax(args[1]->max_length, args[2]->max_length);
2404
2436
}
2405
2437
 
2406
2438
 
2407
2439
uint32_t Item_func_if::decimal_precision() const
2408
2440
{
2409
 
  int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2410
 
                  decimals);
2411
 
  return min(precision, DECIMAL_MAX_PRECISION);
 
2441
  int precision=(cmax(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
 
2442
                 decimals);
 
2443
  return cmin(precision, DECIMAL_MAX_PRECISION);
2412
2444
}
2413
2445
 
2414
2446
 
2729
2761
  Item **agg;
2730
2762
  uint32_t nagg;
2731
2763
  uint32_t found_types= 0;
2732
 
  if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
 
2764
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2733
2765
    return;
2734
2766
 
2735
2767
  /*
2755
2787
  */
2756
2788
  if (first_expr_num != -1)
2757
2789
  {
 
2790
    uint32_t i;
2758
2791
    agg[0]= args[first_expr_num];
2759
2792
    left_result_type= agg[0]->result_type();
2760
2793
 
2764
2797
    if (!(found_types= collect_cmp_types(agg, nagg)))
2765
2798
      return;
2766
2799
 
2767
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2800
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2768
2801
    {
2769
2802
      if (found_types & (1 << i) && !cmp_items[i])
2770
2803
      {
2813
2846
 
2814
2847
  if (else_expr_num != -1)
2815
2848
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2816
 
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
2849
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2817
2850
}
2818
2851
 
2819
2852
 
2850
2883
 
2851
2884
void Item_func_case::cleanup()
2852
2885
{
 
2886
  uint32_t i;
2853
2887
  Item_func::cleanup();
2854
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2888
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2855
2889
  {
2856
2890
    delete cmp_items[i];
2857
2891
    cmp_items[i]= 0;
2858
2892
  }
 
2893
  return;
2859
2894
}
2860
2895
 
2861
2896
 
2925
2960
{
2926
2961
  cached_field_type= agg_field_type(args, arg_count);
2927
2962
  agg_result_type(&hybrid_type, args, arg_count);
2928
 
 
2929
2963
  switch (hybrid_type) {
2930
2964
  case STRING_RESULT:
2931
2965
    count_only_length();
2932
2966
    decimals= NOT_FIXED_DEC;
2933
2967
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2934
2968
    break;
2935
 
 
2936
2969
  case DECIMAL_RESULT:
2937
2970
    count_decimal_length();
2938
2971
    break;
2939
 
 
2940
2972
  case REAL_RESULT:
2941
2973
    count_real_length();
2942
2974
    break;
2943
 
 
2944
2975
  case INT_RESULT:
2945
2976
    count_only_length();
2946
2977
    decimals= 0;
2947
2978
    break;
2948
 
 
2949
2979
  case ROW_RESULT:
 
2980
  default:
2950
2981
    assert(0);
2951
2982
  }
2952
2983
}
3073
3104
}
3074
3105
 
3075
3106
 
3076
 
void in_vector::sort()
3077
 
{
3078
 
  internal::my_qsort2(base,used_count,size,compare, (void *) collation);
3079
 
}
3080
 
 
3081
 
 
3082
3107
int in_vector::find(Item *item)
3083
3108
{
3084
3109
  unsigned char *result=get_value(item);
3110
3135
{
3111
3136
  if (base)
3112
3137
  {
3113
 
    // base was allocated with help of memory::sql_alloc => following is OK
 
3138
    // base was allocated with help of sql_alloc => following is OK
3114
3139
    for (uint32_t i=0 ; i < count ; i++)
3115
3140
      ((String*) base)[i].free();
3116
3141
  }
3232
3257
{
3233
3258
  tmp= item->val_real();
3234
3259
  if (item->null_value)
3235
 
    return 0;
 
3260
    return 0;                                   /* purecov: inspected */
3236
3261
  return (unsigned char*) &tmp;
3237
3262
}
3238
3263
 
3270
3295
  switch (type) {
3271
3296
  case STRING_RESULT:
3272
3297
    return new cmp_item_sort_string(cs);
3273
 
 
3274
3298
  case INT_RESULT:
3275
3299
    return new cmp_item_int;
3276
 
 
3277
3300
  case REAL_RESULT:
3278
3301
    return new cmp_item_real;
3279
 
 
3280
3302
  case ROW_RESULT:
3281
3303
    return new cmp_item_row;
3282
 
 
3283
3304
  case DECIMAL_RESULT:
3284
3305
    return new cmp_item_decimal;
 
3306
  default:
 
3307
    assert(0);
 
3308
    break;
3285
3309
  }
3286
 
 
3287
3310
  return 0; // to satisfy compiler :)
3288
3311
}
3289
3312
 
3362
3385
    return;
3363
3386
  }
3364
3387
  n= tmpl->n;
3365
 
  if ((comparators= (cmp_item **) memory::sql_alloc(sizeof(cmp_item *)*n)))
 
3388
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
3366
3389
  {
3367
3390
    item->bring_value();
3368
3391
    item->null_value= 0;
3554
3577
  bool compare_as_datetime= false;
3555
3578
  Item *date_arg= 0;
3556
3579
  uint32_t found_types= 0;
3557
 
  uint32_t type_cnt= 0;
 
3580
  uint32_t type_cnt= 0, i;
3558
3581
  Item_result cmp_type= STRING_RESULT;
3559
3582
  left_result_type= args[0]->result_type();
3560
 
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
 
3583
  if (!(found_types= collect_cmp_types(args, arg_count)))
3561
3584
    return;
3562
3585
 
3563
3586
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3568
3591
      break;
3569
3592
    }
3570
3593
  }
3571
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3594
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
3572
3595
  {
3573
3596
    if (found_types & 1 << i)
3574
3597
    {
3675
3698
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3676
3699
  {
3677
3700
    if (compare_as_datetime)
3678
 
    {
3679
3701
      array= new in_datetime(date_arg, arg_count - 1);
3680
 
    }
3681
3702
    else
3682
3703
    {
3683
3704
      /*
3688
3709
        comparison type accordingly.
3689
3710
      */
3690
3711
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3712
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3691
3713
          cmp_type != INT_RESULT)
3692
3714
      {
3693
3715
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3703
3725
            cmp_type= INT_RESULT;
3704
3726
        }
3705
3727
      }
3706
 
 
3707
3728
      switch (cmp_type) {
3708
3729
      case STRING_RESULT:
3709
3730
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3710
3731
                            cmp_collation.collation);
3711
3732
        break;
3712
 
 
3713
3733
      case INT_RESULT:
3714
3734
        array= new in_int64_t(arg_count-1);
3715
3735
        break;
3716
 
 
3717
3736
      case REAL_RESULT:
3718
3737
        array= new in_double(arg_count-1);
3719
3738
        break;
3720
 
 
3721
3739
      case ROW_RESULT:
3722
3740
        /*
3723
3741
          The row comparator was created at the beginning but only DATETIME
3726
3744
        */
3727
3745
        ((in_row*)array)->tmp.store_value(args[0]);
3728
3746
        break;
3729
 
 
3730
3747
      case DECIMAL_RESULT:
3731
3748
        array= new in_decimal(arg_count - 1);
3732
3749
        break;
 
3750
      default:
 
3751
        assert(0);
 
3752
        return;
3733
3753
      }
3734
3754
    }
3735
 
 
3736
3755
    if (array && !(session->is_fatal_error))            // If not EOM
3737
3756
    {
3738
3757
      uint32_t j=0;
3739
3758
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3740
3759
      {
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;
 
3760
        array->set(j,args[arg_num]);
 
3761
        if (!args[arg_num]->null_value)                 // Skip NULL values
 
3762
          j++;
 
3763
        else
 
3764
          have_null= 1;
3748
3765
      }
3749
3766
      if ((array->used_count= j))
3750
 
        array->sort();
 
3767
        array->sort();
3751
3768
    }
3752
3769
  }
3753
3770
  else
3756
3773
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3757
3774
    else
3758
3775
    {
3759
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3776
      for (i= 0; i <= (uint32_t) DECIMAL_RESULT; i++)
3760
3777
      {
3761
3778
        if (found_types & (1 << i) && !cmp_items[i])
3762
3779
        {
3921
3938
    if ((!item->fixed &&
3922
3939
         item->fix_fields(session, li.ref())) ||
3923
3940
        (item= *li.ref())->check_cols(1))
3924
 
      return true;
 
3941
      return true; /* purecov: inspected */
3925
3942
    used_tables_cache|=     item->used_tables();
3926
3943
    if (item->const_item())
3927
3944
      and_tables_cache= (table_map) 0;
4369
4386
  if (canDoTurboBM)
4370
4387
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4371
4388
  return my_wildcmp(cmp.cmp_collation.collation,
4372
 
                    res->ptr(),res->ptr()+res->length(),
 
4389
                    res->ptr(),res->ptr()+res->length(),
4373
4390
                    res2->ptr(),res2->ptr()+res2->length(),
4374
 
                    make_escape_code(cmp.cmp_collation.collation, escape),
4375
 
                    internal::wild_one,internal::wild_many) ? 0 : 1;
 
4391
                    escape,wild_one,wild_many) ? 0 : 1;
4376
4392
}
4377
4393
 
4378
4394
 
4389
4405
    if (!res2)
4390
4406
      return OPTIMIZE_NONE;
4391
4407
 
4392
 
    if (*res2->ptr() != internal::wild_many)
 
4408
    if (*res2->ptr() != wild_many)
4393
4409
    {
4394
 
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != internal::wild_one)
 
4410
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
4395
4411
        return OPTIMIZE_OP;
4396
4412
    }
4397
4413
  }
4414
4430
 
4415
4431
  if (escape_item->const_item())
4416
4432
  {
4417
 
    
4418
4433
    /* If we are on execution stage */
4419
4434
    String *escape_str= escape_item->val_str(&tmp_value1);
4420
4435
    if (escape_str)
4421
4436
    {
4422
 
      escape= (char *)memory::sql_alloc(escape_str->length());
4423
 
      strcpy(escape, escape_str->ptr()); 
 
4437
      if (escape_used_in_parsing && escape_str->numchars() > 1)
 
4438
      {
 
4439
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
 
4440
        return true;
 
4441
      }
 
4442
 
 
4443
      if (use_mb(cmp.cmp_collation.collation))
 
4444
      {
 
4445
        const CHARSET_INFO * const cs= escape_str->charset();
 
4446
        my_wc_t wc;
 
4447
        int rc= cs->cset->mb_wc(cs, &wc,
 
4448
                                (const unsigned char*) escape_str->ptr(),
 
4449
                                (const unsigned char*) escape_str->ptr() +
 
4450
                                               escape_str->length());
 
4451
        escape= (int) (rc > 0 ? wc : '\\');
 
4452
      }
 
4453
      else
 
4454
      {
 
4455
        /*
 
4456
          In the case of 8bit character set, we pass native
 
4457
          code instead of Unicode code as "escape" argument.
 
4458
          Convert to "cs" if charset of escape differs.
 
4459
        */
 
4460
        const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4461
        uint32_t unused;
 
4462
        if (escape_str->needs_conversion(escape_str->length(),
 
4463
                                         escape_str->charset(), cs, &unused))
 
4464
        {
 
4465
          char ch;
 
4466
          uint32_t errors;
 
4467
          uint32_t cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
 
4468
                                          escape_str->length(),
 
4469
                                          escape_str->charset(), &errors);
 
4470
          escape= cnvlen ? ch : '\\';
 
4471
        }
 
4472
        else
 
4473
          escape= *(escape_str->ptr());
 
4474
      }
4424
4475
    }
4425
4476
    else
4426
 
    {
4427
 
      escape= (char *)memory::sql_alloc(1);
4428
 
      strcpy(escape, "\\");
4429
 
    } 
4430
 
   
 
4477
      escape= '\\';
 
4478
 
4431
4479
    /*
4432
4480
      We could also do boyer-more for non-const items, but as we would have to
4433
4481
      recompute the tables for each row it's not worth it.
4447
4495
      */
4448
4496
 
4449
4497
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4450
 
          *first == internal::wild_many &&
4451
 
          *last  == internal::wild_many)
 
4498
          *first == wild_many &&
 
4499
          *last  == wild_many)
4452
4500
      {
4453
4501
        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
 
  
 
4502
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
4460
4503
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
4461
4504
      }
4462
4505
      if (canDoTurboBM)
4505
4548
 
4506
4549
  if (!cs->sort_order)
4507
4550
  {
4508
 
    for (int i = pattern_len - 2; i >= 0; i--)
 
4551
    int i;
 
4552
    for (i = pattern_len - 2; i >= 0; i--)
4509
4553
    {
4510
4554
      int tmp = *(splm1 + i - f);
4511
4555
      if (g < i && tmp < i - g)
4512
 
        suff[i] = tmp;
 
4556
        suff[i] = tmp;
4513
4557
      else
4514
4558
      {
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;
 
4559
        if (i < g)
 
4560
          g = i; // g = cmin(i, g)
 
4561
        f = i;
 
4562
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
 
4563
          g--;
 
4564
        suff[i] = f - g;
4521
4565
      }
4522
4566
    }
4523
4567
  }
4524
4568
  else
4525
4569
  {
4526
 
    for (int i = pattern_len - 2; 0 <= i; --i)
 
4570
    int i;
 
4571
    for (i = pattern_len - 2; 0 <= i; --i)
4527
4572
    {
4528
4573
      int tmp = *(splm1 + i - f);
4529
4574
      if (g < i && tmp < i - g)
4530
 
        suff[i] = tmp;
 
4575
        suff[i] = tmp;
4531
4576
      else
4532
4577
      {
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;
 
4578
        if (i < g)
 
4579
          g = i; // g = cmin(i, g)
 
4580
        f = i;
 
4581
        while (g >= 0 &&
 
4582
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
 
4583
          g--;
 
4584
        suff[i] = f - g;
4540
4585
      }
4541
4586
    }
4542
4587
  }
4658
4703
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4659
4704
      else
4660
4705
      {
4661
 
        if (turboShift < bcShift)
4662
 
          shift= max(shift, u + 1);
4663
 
        u = 0;
 
4706
        if (turboShift < bcShift)
 
4707
          shift = cmax(shift, u + 1);
 
4708
        u = 0;
4664
4709
      }
4665
4710
      j+= shift;
4666
4711
    }
4673
4718
      register int i = plm1;
4674
4719
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4675
4720
      {
4676
 
        i--;
4677
 
        if (i == plm1 - shift)
4678
 
          i-= u;
 
4721
        i--;
 
4722
        if (i == plm1 - shift)
 
4723
          i-= u;
4679
4724
      }
4680
 
 
4681
4725
      if (i < 0)
4682
 
        return 1;
 
4726
        return 1;
4683
4727
 
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
 
      
 
4728
      register const int v = plm1 - i;
 
4729
      turboShift = u - v;
 
4730
      bcShift    = bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
 
4731
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
 
4732
      shift      = cmax(shift, bmGs[i]);
4690
4733
      if (shift == bmGs[i])
4691
 
        u= (pattern_len - shift < v) ? pattern_len - shift : v;
 
4734
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4692
4735
      else
4693
4736
      {
4694
 
        if (turboShift < bcShift)
4695
 
          shift= max(shift, u + 1);
4696
 
        u = 0;
 
4737
        if (turboShift < bcShift)
 
4738
          shift = cmax(shift, u + 1);
 
4739
        u = 0;
4697
4740
      }
4698
 
 
4699
4741
      j+= shift;
4700
4742
    }
4701
4743
    return 0;
5114
5156
  while ((item_field= it++))
5115
5157
  {
5116
5158
    /* Skip fields of non-const tables. They haven't been read yet */
5117
 
    if (item_field->field->getTable()->const_table)
 
5159
    if (item_field->field->table->const_table)
5118
5160
    {
5119
5161
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5120
5162
        return 0;
5186
5228
  str->append(')');
5187
5229
}
5188
5230
 
5189
 
} /* namespace drizzled */