~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

Merge Valgrind.

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 <drizzled/server_includes.h>
25
 
#include <drizzled/sql_select.h>
26
 
 
27
 
static bool convert_constant_item(THD *, Item_field *, Item **);
 
24
#include "drizzled/server_includes.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
 
 
35
#include <algorithm>
 
36
 
 
37
using namespace std;
 
38
 
 
39
 
 
40
static Eq_creator eq_creator;
 
41
static Ne_creator ne_creator;
 
42
static Gt_creator gt_creator;
 
43
static Lt_creator lt_creator;
 
44
static Ge_creator ge_creator;
 
45
static Le_creator le_creator;
 
46
 
 
47
static bool convert_constant_item(Session *, Item_field *, Item **);
28
48
 
29
49
static Item_result item_store_type(Item_result a, Item *item,
30
50
                                   bool unsigned_flag)
42
62
    return INT_RESULT;
43
63
}
44
64
 
45
 
static void agg_result_type(Item_result *type, Item **items, uint nitems)
 
65
static void agg_result_type(Item_result *type, Item **items, uint32_t nitems)
46
66
{
47
67
  Item **item, **item_end;
48
68
  bool unsigned_flag= 0;
79
99
  DESCRIPTION
80
100
    The function checks that two expressions have compatible row signatures
81
101
    i.e. that the number of columns they return are the same and that if they
82
 
    are both row expressions then each component from the first expression has 
 
102
    are both row expressions then each component from the first expression has
83
103
    a row signature compatible with the signature of the corresponding component
84
104
    of the second expression.
85
105
 
90
110
 
91
111
static int cmp_row_type(Item* item1, Item* item2)
92
112
{
93
 
  uint n= item1->cols();
 
113
  uint32_t n= item1->cols();
94
114
  if (item2->check_cols(n))
95
115
    return 1;
96
 
  for (uint i=0; i<n; i++)
 
116
  for (uint32_t i=0; i<n; i++)
97
117
  {
98
118
    if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
99
119
        (item1->element_index(i)->result_type() == ROW_RESULT &&
127
147
    0  otherwise
128
148
*/
129
149
 
130
 
static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
 
150
static int agg_cmp_type(Item_result *type, Item **items, uint32_t nitems)
131
151
{
132
 
  uint i;
 
152
  uint32_t i;
133
153
  type[0]= items[0]->result_type();
134
154
  for (i= 1 ; i < nitems ; i++)
135
155
  {
140
160
      of the first row expression has a compatible row signature with
141
161
      the signature of the corresponding component of the second row
142
162
      expression.
143
 
    */ 
 
163
    */
144
164
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
145
165
      return 1;     // error found: invalid usage of rows
146
166
  }
166
186
  @return aggregated field type.
167
187
*/
168
188
 
169
 
enum_field_types agg_field_type(Item **items, uint nitems)
 
189
enum_field_types agg_field_type(Item **items, uint32_t nitems)
170
190
{
171
 
  uint i;
 
191
  uint32_t i;
172
192
  if (!nitems || items[0]->result_type() == ROW_RESULT )
173
193
    return (enum_field_types)-1;
174
194
  enum_field_types res= items[0]->field_type();
184
204
    collect_cmp_types()
185
205
      items             Array of items to collect types from
186
206
      nitems            Number of items in the array
 
207
      skip_nulls        Don't collect types of NULL items if TRUE
187
208
 
188
209
  DESCRIPTION
189
210
    This function collects different result types for comparison of the first
194
215
    Bitmap of collected types - otherwise
195
216
*/
196
217
 
197
 
static uint collect_cmp_types(Item **items, uint nitems)
 
218
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
198
219
{
199
 
  uint i;
200
 
  uint found_types;
 
220
  uint32_t i;
 
221
  uint32_t found_types;
201
222
  Item_result left_result= items[0]->result_type();
202
223
  assert(nitems > 1);
203
224
  found_types= 0;
204
225
  for (i= 1; i < nitems ; i++)
205
226
  {
206
 
    if ((left_result == ROW_RESULT || 
 
227
    if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
 
228
      continue; // Skip NULL constant items
 
229
    if ((left_result == ROW_RESULT ||
207
230
         items[i]->result_type() == ROW_RESULT) &&
208
231
        cmp_row_type(items[0], items[i]))
209
232
      return 0;
210
 
    found_types|= 1<< (uint)item_cmp_type(left_result,
 
233
    found_types|= 1<< (uint32_t)item_cmp_type(left_result,
211
234
                                           items[i]->result_type());
212
235
  }
 
236
  /*
 
237
   Even if all right-hand items are NULLs and we are skipping them all, we need
 
238
   at least one type bit in the found_type bitmask.
 
239
  */
 
240
  if (skip_nulls && !found_types)
 
241
    found_types= 1 << (uint)left_result;
213
242
  return found_types;
214
243
}
215
244
 
216
 
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
217
 
                              const char *fname)
218
 
{
219
 
  my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
220
 
           c1.collation->name,c1.derivation_name(),
221
 
           c2.collation->name,c2.derivation_name(),
222
 
           fname);
223
 
}
224
 
 
225
245
 
226
246
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
227
247
{
229
249
}
230
250
 
231
251
 
 
252
const Eq_creator* Eq_creator::instance()
 
253
{
 
254
  return &eq_creator;
 
255
}
 
256
 
 
257
 
232
258
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
233
259
{
234
260
  return new Item_func_ne(a, b);
235
261
}
236
262
 
237
263
 
 
264
const Ne_creator* Ne_creator::instance()
 
265
{
 
266
  return &ne_creator;
 
267
}
 
268
 
 
269
 
238
270
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
239
271
{
240
272
  return new Item_func_gt(a, b);
241
273
}
242
274
 
243
275
 
 
276
const Gt_creator* Gt_creator::instance()
 
277
{
 
278
  return &gt_creator;
 
279
}
 
280
 
 
281
 
244
282
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
245
283
{
246
284
  return new Item_func_lt(a, b);
247
285
}
248
286
 
249
287
 
 
288
const Lt_creator* Lt_creator::instance()
 
289
{
 
290
  return &lt_creator;
 
291
}
 
292
 
 
293
 
250
294
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
251
295
{
252
296
  return new Item_func_ge(a, b);
253
297
}
254
298
 
255
299
 
 
300
const Ge_creator* Ge_creator::instance()
 
301
{
 
302
  return &ge_creator;
 
303
}
 
304
 
 
305
 
256
306
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
257
307
{
258
308
  return new Item_func_le(a, b);
259
309
}
260
310
 
 
311
const Le_creator* Le_creator::instance()
 
312
{
 
313
  return &le_creator;
 
314
}
 
315
 
 
316
 
261
317
/*
262
318
  Test functions
263
319
  Most of these  returns 0LL if false and 1LL if true and
361
417
    also when comparing bigint to strings (in which case strings
362
418
    are converted to bigints).
363
419
 
364
 
  @param  thd             thread handle
 
420
  @param  session             thread handle
365
421
  @param  field_item      item will be converted using the type of this field
366
422
  @param[in,out] item     reference to the item to convert
367
423
 
378
434
    1  Item was replaced with an integer version of the item
379
435
*/
380
436
 
381
 
static bool convert_constant_item(THD *thd, Item_field *field_item,
 
437
static bool convert_constant_item(Session *session, Item_field *field_item,
382
438
                                  Item **item)
383
439
{
384
440
  Field *field= field_item->field;
385
441
  int result= 0;
386
442
 
 
443
  field->setWriteSet();
 
444
 
387
445
  if (!(*item)->with_subselect && (*item)->const_item())
388
446
  {
389
 
    TABLE *table= field->table;
390
 
    ulong orig_sql_mode= thd->variables.sql_mode;
391
 
    enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
392
 
    my_bitmap_map *old_write_map;
393
 
    my_bitmap_map *old_read_map;
 
447
    ulong orig_sql_mode= session->variables.sql_mode;
 
448
    enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
394
449
    uint64_t orig_field_val= 0; /* original field value if valid */
395
450
 
396
 
    if (table)
397
 
    {
398
 
      old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
399
 
      old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
400
 
    }
401
451
    /* For comparison purposes allow invalid dates like 2000-01-32 */
402
 
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
 
452
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
403
453
                             MODE_INVALID_DATES;
404
 
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
454
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
405
455
 
406
456
    /*
407
457
      Store the value of the field if it references an outer field because
414
464
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
415
465
                                       test(field->flags & UNSIGNED_FLAG));
416
466
      if (tmp)
417
 
        thd->change_item_tree(item, tmp);
 
467
        session->change_item_tree(item, tmp);
418
468
      result= 1;                                        // Item was replaced
419
469
    }
420
470
    /* Restore the original field value. */
424
474
      /* orig_field_val must be a valid value that can be restored back. */
425
475
      assert(!result);
426
476
    }
427
 
    thd->variables.sql_mode= orig_sql_mode;
428
 
    thd->count_cuted_fields= orig_count_cuted_fields;
429
 
    if (table)
430
 
    {
431
 
      dbug_tmp_restore_column_map(table->write_set, old_write_map);
432
 
      dbug_tmp_restore_column_map(table->read_set, old_read_map);
433
 
    }
 
477
    session->variables.sql_mode= orig_sql_mode;
 
478
    session->count_cuted_fields= orig_count_cuted_fields;
434
479
  }
435
480
  return result;
436
481
}
439
484
void Item_bool_func2::fix_length_and_dec()
440
485
{
441
486
  max_length= 1;                                     // Function returns 0 or 1
442
 
  THD *thd;
 
487
  Session *session;
443
488
 
444
489
  /*
445
490
    As some compare functions are generated after sql_yacc,
448
493
  if (!args[0] || !args[1])
449
494
    return;
450
495
 
451
 
  /* 
 
496
  /*
452
497
    We allow to convert to Unicode character sets in some cases.
453
498
    The conditions when conversion is possible are:
454
499
    - arguments A and B have different charsets
455
500
    - A wins according to coercibility rules
456
501
    - character set of A is superset for character set of B
457
 
   
 
502
 
458
503
    If all of the above is true, then it's possible to convert
459
504
    B into the character set of A, and then compare according
460
505
    to the collation of A.
461
506
  */
462
507
 
463
 
  
 
508
 
464
509
  DTCollation coll;
465
510
  if (args[0]->result_type() == STRING_RESULT &&
466
511
      args[1]->result_type() == STRING_RESULT &&
467
512
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
468
513
    return;
469
 
    
 
514
 
470
515
  args[0]->cmp_context= args[1]->cmp_context=
471
516
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
472
517
  // Make a special case of compare with fields to get nicer DATE comparisons
477
522
    return;
478
523
  }
479
524
 
480
 
  thd= current_thd;
 
525
  session= current_session;
 
526
  Item_field *field_item= NULL;
481
527
 
482
528
  if (args[0]->real_item()->type() == FIELD_ITEM)
483
529
  {
484
 
    Item_field *field_item= (Item_field*) (args[0]->real_item());
 
530
    field_item= static_cast<Item_field*>(args[0]->real_item());
485
531
    if (field_item->field->can_be_compared_as_int64_t() &&
486
532
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
487
533
    {
488
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
534
      if (convert_constant_item(session, field_item, &args[1]))
489
535
      {
490
536
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
491
537
                         INT_RESULT);           // Works for all types.
496
542
 
497
543
    if (args[1]->real_item()->type() == FIELD_ITEM)
498
544
    {
499
 
      Item_field *field_item= (Item_field*) (args[1]->real_item());
 
545
      field_item= static_cast<Item_field*>(args[1]->real_item());
500
546
      if (field_item->field->can_be_compared_as_int64_t() &&
501
547
          !(field_item->is_datetime() &&
502
548
            args[0]->result_type() == STRING_RESULT))
503
549
      {
504
 
        if (convert_constant_item(thd, field_item, &args[0]))
 
550
        if (convert_constant_item(session, field_item, &args[0]))
505
551
        {
506
552
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
507
553
                           INT_RESULT); // Works for all types.
523
569
  switch (type) {
524
570
  case ROW_RESULT:
525
571
  {
526
 
    uint n= (*a)->cols();
 
572
    uint32_t n= (*a)->cols();
527
573
    if (n != (*b)->cols())
528
574
    {
529
575
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
532
578
    }
533
579
    if (!(comparators= new Arg_comparator[n]))
534
580
      return 1;
535
 
    for (uint i=0; i < n; i++)
 
581
    for (uint32_t i=0; i < n; i++)
536
582
    {
537
583
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
538
584
      {
549
595
      We must set cmp_charset here as we may be called from for an automatic
550
596
      generated item, like in natural join
551
597
    */
552
 
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
598
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
553
599
        cmp_collation.derivation == DERIVATION_NONE)
554
600
    {
555
601
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
574
620
        which would be transformed to:
575
621
        WHERE col= 'j'
576
622
      */
577
 
      (*a)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
578
 
      (*b)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
 
623
      (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
 
624
      (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
579
625
    }
580
626
    break;
581
627
  }
621
667
/**
622
668
  @brief Convert date provided in a string to the int representation.
623
669
 
624
 
  @param[in]   thd        thread handle
 
670
  @param[in]   session        thread handle
625
671
  @param[in]   str        a string to convert
626
672
  @param[in]   warn_type  type of the timestamp for issuing the warning
627
673
  @param[in]   warn_name  field name for issuing the warning
641
687
*/
642
688
 
643
689
static uint64_t
644
 
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
 
690
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
645
691
                  char *warn_name, bool *error_arg)
646
692
{
647
693
  uint64_t value= 0;
648
694
  int error;
649
695
  DRIZZLE_TIME l_time;
650
 
  enum_drizzle_timestamp_type ret;
 
696
  enum enum_drizzle_timestamp_type ret;
651
697
 
652
698
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
653
699
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
654
 
                        (thd->variables.sql_mode &
655
 
                         (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
 
700
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
656
701
                       &error);
657
702
 
658
703
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
671
716
  }
672
717
 
673
718
  if (error > 0)
674
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
719
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
675
720
                                 str->ptr(), str->length(),
676
721
                                 warn_type, warn_name);
677
722
 
696
741
         int result and the other item (b or a) is an item with string result.
697
742
         If the second item is a constant one then it's checked to be
698
743
         convertible to the DATE/DATETIME type. If the constant can't be
699
 
         converted to a DATE/DATETIME then the compare_datetime() comparator
700
 
         isn't used and the warning about wrong DATE/DATETIME value is issued.
 
744
         converted to a DATE/DATETIME then an error is issued back to the Session.
701
745
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
702
746
      the comparison is handled by other comparators.
 
747
 
703
748
    If the datetime comparator can be used and one the operands of the
704
749
    comparison is a string constant that was successfully converted to a
705
750
    DATE/DATETIME type then the result of the conversion is returned in the
748
793
        (str_arg->type() != Item::FUNC_ITEM ||
749
794
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
750
795
    {
751
 
      THD *thd= current_thd;
 
796
      /*
 
797
       * OK, we are here if we've got a date field (or something which can be 
 
798
       * compared as a date field) on one side of the equation, and a constant
 
799
       * string on the other side.  In this case, we must verify that the constant
 
800
       * string expression can indeed be evaluated as a datetime.  If it cannot, 
 
801
       * we throw an error here and stop processsing.  Bad data should ALWAYS 
 
802
       * produce an error, and no implicit conversion or truncation should take place.
 
803
       *
 
804
       * If the conversion to a DateTime temporal is successful, then we convert
 
805
       * the Temporal instance to a uint64_t for the comparison operator, which
 
806
       * compares date(times) using int64_t semantics.
 
807
       *
 
808
       * @TODO
 
809
       *
 
810
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
 
811
       * from val_int(), not uint64_t...
 
812
       */
752
813
      uint64_t value;
753
 
      bool error;
754
 
      String tmp, *str_val= 0;
755
 
      timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
756
 
                              DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
 
814
      String *str_val;
 
815
      String tmp;
 
816
      /* DateTime used to pick up as many string conversion possibilities as possible. */
 
817
      drizzled::DateTime temporal;
757
818
 
758
819
      str_val= str_arg->val_str(&tmp);
759
 
      if (str_arg->null_value)
760
 
        return CMP_DATE_DFLT;
761
 
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
762
 
      if (error)
763
 
        return CMP_DATE_DFLT;
 
820
      if (! str_val)
 
821
      {
 
822
        /* 
 
823
         * If we are here, it is most likely due to the comparison item
 
824
         * being a NULL.  Although this is incorrect (SQL demands that the term IS NULL
 
825
         * be used, not = NULL since no item can be equal to NULL).
 
826
         *
 
827
         * So, return gracefully.
 
828
         */
 
829
        return CMP_DATE_DFLT;
 
830
      }
 
831
      if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
 
832
      {
 
833
        /* Chuck an error. Bad datetime input. */
 
834
        my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
 
835
        return CMP_DATE_DFLT; /* :( What else can I return... */
 
836
      }
 
837
 
 
838
      /* String conversion was good.  Convert to an integer for comparison purposes. */
 
839
      int64_t int_value;
 
840
      temporal.to_int64_t(&int_value);
 
841
      value= (uint64_t) int_value;
 
842
 
764
843
      if (const_value)
765
844
        *const_value= value;
766
845
    }
769
848
}
770
849
 
771
850
 
772
 
/*
773
 
  Retrieves correct TIME value from the given item.
774
 
 
775
 
  SYNOPSIS
776
 
    get_time_value()
777
 
    thd                 thread handle
778
 
    item_arg   [in/out] item to retrieve TIME value from
779
 
    cache_arg  [in/out] pointer to place to store the cache item to
780
 
    warn_item  [in]     unused
781
 
    is_null    [out]    true <=> the item_arg is null
782
 
 
783
 
  DESCRIPTION
784
 
    Retrieves the correct TIME value from given item for comparison by the
785
 
    compare_datetime() function.
786
 
    If item's result can be compared as int64_t then its int value is used
787
 
    and a value returned by get_time function is used otherwise.
788
 
    If an item is a constant one then its value is cached and it isn't
789
 
    get parsed again. An Item_cache_int object is used for for cached values.
790
 
    It seamlessly substitutes the original item.  The cache item is marked as
791
 
    non-constant to prevent re-caching it again.
792
 
 
793
 
  RETURN
794
 
    obtained value
795
 
*/
796
 
 
797
 
uint64_t
798
 
get_time_value(THD *thd __attribute__((unused)),
799
 
               Item ***item_arg, Item **cache_arg,
800
 
               Item *warn_item __attribute__((unused)),
801
 
               bool *is_null)
802
 
{
803
 
  uint64_t value;
804
 
  Item *item= **item_arg;
805
 
  DRIZZLE_TIME ltime;
806
 
 
807
 
  if (item->result_as_int64_t())
808
 
  {
809
 
    value= item->val_int();
810
 
    *is_null= item->null_value;
811
 
  }
812
 
  else
813
 
  {
814
 
    *is_null= item->get_time(&ltime);
815
 
    value= !*is_null ? TIME_to_uint64_t_datetime(&ltime) : 0;
816
 
  }
817
 
  /*
818
 
    Do not cache GET_USER_VAR() function as its const_item() may return true
819
 
    for the current thread but it still may change during the execution.
820
 
  */
821
 
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
822
 
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
823
 
  {
824
 
    Item_cache_int *cache= new Item_cache_int();
825
 
    /* Mark the cache as non-const to prevent re-caching. */
826
 
    cache->set_used_tables(1);
827
 
    cache->store(item, value);
828
 
    *cache_arg= cache;
829
 
    *item_arg= cache_arg;
830
 
  }
831
 
  return value;
832
 
}
833
 
 
834
 
 
835
851
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
836
852
                                        Item **a1, Item **a2,
837
853
                                        Item_result type)
843
859
 
844
860
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
845
861
  {
846
 
    thd= current_thd;
 
862
    session= current_session;
847
863
    owner= owner_arg;
848
864
    a_type= (*a)->field_type();
849
865
    b_type= (*b)->field_type();
873
889
    get_value_func= &get_datetime_value;
874
890
    return 0;
875
891
  }
876
 
  else if (type == STRING_RESULT && (*a)->field_type() == DRIZZLE_TYPE_TIME &&
877
 
           (*b)->field_type() == DRIZZLE_TYPE_TIME)
878
 
  {
879
 
    /* Compare TIME values as integers. */
880
 
    thd= current_thd;
881
 
    owner= owner_arg;
882
 
    a_cache= 0;
883
 
    b_cache= 0;
884
 
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
885
 
    func= &Arg_comparator::compare_datetime;
886
 
    get_value_func= &get_time_value;
887
 
    return 0;
888
 
  }
889
892
 
890
893
  return set_compare_func(owner_arg, type);
891
894
}
893
896
 
894
897
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
895
898
{
896
 
  thd= current_thd;
 
899
  session= current_session;
897
900
  /* A caller will handle null values by itself. */
898
901
  owner= NULL;
899
902
  a= a1;
913
916
 
914
917
  SYNOPSIS
915
918
    get_datetime_value()
916
 
    thd                 thread handle
 
919
    session                 thread handle
917
920
    item_arg   [in/out] item to retrieve DATETIME value from
918
921
    cache_arg  [in/out] pointer to place to store the caching item to
919
922
    warn_item  [in]     item for issuing the conversion warning
938
941
*/
939
942
 
940
943
uint64_t
941
 
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
 
944
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
942
945
                   Item *warn_item, bool *is_null)
943
946
{
944
947
  uint64_t value= 0;
956
959
      compare it with 100000000L - any DATE value should be less than it.
957
960
      Don't shift cached DATETIME values up for the second time.
958
961
    */
959
 
    if (f_type == DRIZZLE_TYPE_NEWDATE ||
 
962
    if (f_type == DRIZZLE_TYPE_DATE ||
960
963
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
961
964
      value*= 1000000L;
962
965
  }
977
980
  {
978
981
    bool error;
979
982
    enum_field_types f_type= warn_item->field_type();
980
 
    timestamp_type t_type= f_type ==
981
 
      DRIZZLE_TYPE_NEWDATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
982
 
    value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
 
983
    enum enum_drizzle_timestamp_type t_type= f_type ==
 
984
      DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
 
985
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
983
986
    /*
984
987
      If str did not contain a valid date according to the current
985
988
      SQL_MODE, get_date_from_str() has already thrown a warning,
1031
1034
  uint64_t a_value, b_value;
1032
1035
 
1033
1036
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1034
 
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
 
1037
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
1035
1038
  if (!is_nulls_eq && is_null)
1036
1039
  {
1037
1040
    if (owner)
1040
1043
  }
1041
1044
 
1042
1045
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1043
 
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
 
1046
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
1044
1047
  if (is_null)
1045
1048
  {
1046
1049
    if (owner)
1054
1057
  /* Compare values. */
1055
1058
  if (is_nulls_eq)
1056
1059
    return (a_value == b_value);
1057
 
  return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
 
1060
  return (a_value < b_value) ? -1 : ((a_value > b_value) ? 1 : 0);
1058
1061
}
1059
1062
 
1060
1063
 
1093
1096
    if ((res2= (*b)->val_str(&owner->tmp_value2)))
1094
1097
    {
1095
1098
      owner->null_value= 0;
1096
 
      uint res1_length= res1->length();
1097
 
      uint res2_length= res2->length();
 
1099
      uint32_t res1_length= res1->length();
 
1100
      uint32_t res2_length= res2->length();
1098
1101
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
1099
1102
      return cmp ? cmp : (int) (res1_length - res2_length);
1100
1103
    }
1351
1354
  bool was_null= 0;
1352
1355
  (*a)->bring_value();
1353
1356
  (*b)->bring_value();
1354
 
  uint n= (*a)->cols();
1355
 
  for (uint i= 0; i<n; i++)
 
1357
  uint32_t n= (*a)->cols();
 
1358
  for (uint32_t i= 0; i<n; i++)
1356
1359
  {
1357
1360
    res= comparators[i].compare();
1358
1361
    if (owner->null_value)
1394
1397
{
1395
1398
  (*a)->bring_value();
1396
1399
  (*b)->bring_value();
1397
 
  uint n= (*a)->cols();
1398
 
  for (uint i= 0; i<n; i++)
 
1400
  uint32_t n= (*a)->cols();
 
1401
  for (uint32_t i= 0; i<n; i++)
1399
1402
  {
1400
1403
    if (!comparators[i].compare())
1401
1404
      return 0;
1457
1460
}
1458
1461
 
1459
1462
 
1460
 
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
 
1463
bool Item_in_optimizer::fix_left(Session *session, Item **)
1461
1464
{
1462
 
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
 
1465
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
1463
1466
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1464
1467
    return 1;
1465
1468
 
1473
1476
  }
1474
1477
  else
1475
1478
  {
1476
 
    uint n= cache->cols();
1477
 
    for (uint i= 0; i < n; i++)
 
1479
    uint32_t n= cache->cols();
 
1480
    for (uint32_t i= 0; i < n; i++)
1478
1481
    {
1479
1482
      if (args[0]->element_index(i)->used_tables())
1480
1483
        ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
1491
1494
}
1492
1495
 
1493
1496
 
1494
 
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
 
1497
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
1495
1498
{
1496
1499
  assert(fixed == 0);
1497
 
  if (fix_left(thd, ref))
 
1500
  if (fix_left(session, ref))
1498
1501
    return true;
1499
1502
  if (args[0]->maybe_null)
1500
1503
    maybe_null=1;
1501
1504
 
1502
 
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
 
1505
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
1503
1506
    return true;
1504
1507
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1505
1508
  if (args[0]->cols() != sub->engine->cols())
1523
1526
  bool tmp;
1524
1527
  assert(fixed == 1);
1525
1528
  cache->store(args[0]);
1526
 
  
 
1529
 
1527
1530
  if (cache->null_value)
1528
1531
  {
1529
1532
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1551
1554
          We disable the predicates we've pushed down into subselect, run the
1552
1555
          subselect and see if it has produced any rows.
1553
1556
        */
1554
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
 
1557
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
1555
1558
        if (cache->cols() == 1)
1556
1559
        {
1557
1560
          item_subs->set_cond_guard_var(0, false);
1561
1564
        }
1562
1565
        else
1563
1566
        {
1564
 
          uint i;
1565
 
          uint ncols= cache->cols();
 
1567
          uint32_t i;
 
1568
          uint32_t ncols= cache->cols();
1566
1569
          /*
1567
1570
            Turn off the predicates that are based on column compares for
1568
1571
            which the left part is currently NULL
1572
1575
            if (cache->element_index(i)->null_value)
1573
1576
              item_subs->set_cond_guard_var(i, false);
1574
1577
          }
1575
 
          
 
1578
 
1576
1579
          (void) args[1]->val_bool_result();
1577
1580
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1578
 
          
 
1581
 
1579
1582
          /* Turn all predicates back on */
1580
1583
          for (i= 0; i < ncols; i++)
1581
1584
            item_subs->set_cond_guard_var(i, true);
1635
1638
    @retval NULL if an error occurred
1636
1639
*/
1637
1640
 
1638
 
Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument)
 
1641
Item *Item_in_optimizer::transform(Item_transformer transformer, unsigned char *argument)
1639
1642
{
1640
1643
  Item *new_item;
1641
1644
 
1646
1649
  if (!new_item)
1647
1650
    return 0;
1648
1651
  /*
1649
 
    THD::change_item_tree() should be called only if the tree was
 
1652
    Session::change_item_tree() should be called only if the tree was
1650
1653
    really transformed, i.e. when a new item has been created.
1651
1654
    Otherwise we'll be allocating a lot of unnecessary memory for
1652
1655
    change records at each execution.
1653
1656
  */
1654
1657
  if ((*args) != new_item)
1655
 
    current_thd->change_item_tree(args, new_item);
 
1658
    current_session->change_item_tree(args, new_item);
1656
1659
 
1657
1660
  /*
1658
1661
    Transform the right IN operand which should be an Item_in_subselect or a
1767
1770
    return 0;
1768
1771
  if (negated != ((Item_func_opt_neg *) item_func)->negated)
1769
1772
    return 0;
1770
 
  for (uint i=0; i < arg_count ; i++)
 
1773
  for (uint32_t i=0; i < arg_count ; i++)
1771
1774
    if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
1772
1775
      return 0;
1773
1776
  return 1;
1776
1779
 
1777
1780
void Item_func_interval::fix_length_and_dec()
1778
1781
{
1779
 
  uint rows= row->cols();
1780
 
  
 
1782
  uint32_t rows= row->cols();
 
1783
 
1781
1784
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1782
1785
                            DECIMAL_RESULT) ||
1783
1786
                           (row->element_index(0)->result_type() ==
1786
1789
  {
1787
1790
    bool not_null_consts= true;
1788
1791
 
1789
 
    for (uint i= 1; not_null_consts && i < rows; i++)
 
1792
    for (uint32_t i= 1; not_null_consts && i < rows; i++)
1790
1793
    {
1791
1794
      Item *el= row->element_index(i);
1792
1795
      not_null_consts&= el->const_item() & !el->is_null();
1798
1801
    {
1799
1802
      if (use_decimal_comparison)
1800
1803
      {
1801
 
        for (uint i= 1; i < rows; i++)
 
1804
        for (uint32_t i= 1; i < rows; i++)
1802
1805
        {
1803
1806
          Item *el= row->element_index(i);
1804
1807
          interval_range *range= intervals + (i-1);
1823
1826
      }
1824
1827
      else
1825
1828
      {
1826
 
        for (uint i= 1; i < rows; i++)
 
1829
        for (uint32_t i= 1; i < rows; i++)
1827
1830
        {
1828
1831
          intervals[i-1].dbl= row->element_index(i)->val_real();
1829
1832
        }
1858
1861
  assert(fixed == 1);
1859
1862
  double value;
1860
1863
  my_decimal dec_buf, *dec= NULL;
1861
 
  uint i;
 
1864
  uint32_t i;
1862
1865
 
1863
1866
  if (use_decimal_comparison)
1864
1867
  {
1876
1879
 
1877
1880
  if (intervals)
1878
1881
  {                                     // Use binary search to find interval
1879
 
    uint start,end;
 
1882
    uint32_t start,end;
1880
1883
    start= 0;
1881
1884
    end=   row->cols()-2;
1882
1885
    while (start != end)
1883
1886
    {
1884
 
      uint mid= (start + end + 1) / 2;
 
1887
      uint32_t mid= (start + end + 1) / 2;
1885
1888
      interval_range *range= intervals + mid;
1886
1889
      bool cmp_result;
1887
1890
      /*
1918
1921
      if (my_decimal_cmp(e_dec, dec) > 0)
1919
1922
        return i - 1;
1920
1923
    }
1921
 
    else 
 
1924
    else
1922
1925
    {
1923
1926
      double val= el->val_real();
1924
1927
      /* Skip NULL ranges. */
1940
1943
    The function saves in ref the pointer to the item or to a newly created
1941
1944
    item that is considered as a replacement for the original one.
1942
1945
 
1943
 
  @param thd     reference to the global context of the query thread
 
1946
  @param session     reference to the global context of the query thread
1944
1947
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1945
1948
                 item is to be assigned
1946
1949
 
1960
1963
    1   got error
1961
1964
*/
1962
1965
 
1963
 
bool Item_func_between::fix_fields(THD *thd, Item **ref)
 
1966
bool Item_func_between::fix_fields(Session *session, Item **ref)
1964
1967
{
1965
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
1968
  if (Item_func_opt_neg::fix_fields(session, ref))
1966
1969
    return 1;
1967
1970
 
1968
 
  thd->lex->current_select->between_count++;
 
1971
  session->lex->current_select->between_count++;
1969
1972
 
1970
1973
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1971
1974
  if (pred_level && !negated)
1985
1988
  max_length= 1;
1986
1989
  int i;
1987
1990
  bool datetime_found= false;
1988
 
  int time_items_found= 0;
1989
1991
  compare_as_dates= true;
1990
 
  THD *thd= current_thd;
 
1992
  Session *session= current_session;
1991
1993
 
1992
1994
  /*
1993
1995
    As some compare functions are generated after sql_yacc,
2015
2017
        datetime_found= true;
2016
2018
        continue;
2017
2019
      }
2018
 
      if (args[i]->field_type() == DRIZZLE_TYPE_TIME &&
2019
 
          args[i]->result_as_int64_t())
2020
 
        time_items_found++;
2021
2020
    }
2022
2021
  }
2023
2022
  if (!datetime_found)
2028
2027
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2029
2028
    le_cmp.set_datetime_cmp_func(args, args + 2);
2030
2029
  }
2031
 
  else if (time_items_found == 3)
2032
 
  {
2033
 
    /* Compare TIME items as integers. */
2034
 
    cmp_type= INT_RESULT;
2035
 
  }
2036
2030
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
2037
 
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
 
2031
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2038
2032
  {
2039
2033
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2040
2034
    if (field_item->field->can_be_compared_as_int64_t())
2043
2037
        The following can't be recoded with || as convert_constant_item
2044
2038
        changes the argument
2045
2039
      */
2046
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
2040
      if (convert_constant_item(session, field_item, &args[1]))
2047
2041
        cmp_type=INT_RESULT;                    // Works for all types.
2048
 
      if (convert_constant_item(thd, field_item, &args[2]))
 
2042
      if (convert_constant_item(session, field_item, &args[2]))
2049
2043
        cmp_type=INT_RESULT;                    // Works for all types.
2050
2044
    }
2051
2045
  }
2104
2098
  {
2105
2099
    int64_t value=args[0]->val_int(), a, b;
2106
2100
    if ((null_value=args[0]->null_value))
2107
 
      return 0;                                 /* purecov: inspected */
 
2101
      return 0;
2108
2102
    a=args[1]->val_int();
2109
2103
    b=args[2]->val_int();
2110
2104
    if (!args[1]->null_value && !args[2]->null_value)
2125
2119
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2126
2120
               a_buf, *a_dec, b_buf, *b_dec;
2127
2121
    if ((null_value=args[0]->null_value))
2128
 
      return 0;                                 /* purecov: inspected */
 
2122
      return 0;
2129
2123
    a_dec= args[1]->val_decimal(&a_buf);
2130
2124
    b_dec= args[2]->val_decimal(&b_buf);
2131
2125
    if (!args[1]->null_value && !args[2]->null_value)
2142
2136
  {
2143
2137
    double value= args[0]->val_real(),a,b;
2144
2138
    if ((null_value=args[0]->null_value))
2145
 
      return 0;                                 /* purecov: inspected */
 
2139
      return 0;
2146
2140
    a= args[1]->val_real();
2147
2141
    b= args[2]->val_real();
2148
2142
    if (!args[1]->null_value && !args[2]->null_value)
2179
2173
Item_func_ifnull::fix_length_and_dec()
2180
2174
{
2181
2175
  agg_result_type(&hybrid_type, args, 2);
2182
 
  maybe_null=args[1]->maybe_null;
 
2176
  maybe_null= args[1]->maybe_null;
2183
2177
  decimals= max(args[0]->decimals, args[1]->decimals);
2184
2178
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2185
2179
 
2186
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
 
2180
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2187
2181
  {
2188
2182
    int len0= args[0]->max_length - args[0]->decimals
2189
2183
      - (args[0]->unsigned_flag ? 0 : 1);
2196
2190
  else
2197
2191
    max_length= max(args[0]->max_length, args[1]->max_length);
2198
2192
 
2199
 
  switch (hybrid_type) {
 
2193
  switch (hybrid_type)
 
2194
  {
2200
2195
  case STRING_RESULT:
2201
2196
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2202
2197
    break;
2214
2209
}
2215
2210
 
2216
2211
 
2217
 
uint Item_func_ifnull::decimal_precision() const
 
2212
uint32_t Item_func_ifnull::decimal_precision() const
2218
2213
{
2219
 
  int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
 
2214
  int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2220
2215
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2221
2216
}
2222
2217
 
2223
2218
 
2224
 
enum_field_types Item_func_ifnull::field_type() const 
 
2219
enum_field_types Item_func_ifnull::field_type() const
2225
2220
{
2226
2221
  return cached_field_type;
2227
2222
}
2228
2223
 
2229
 
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
 
2224
Field *Item_func_ifnull::tmp_table_field(Table *table)
2230
2225
{
2231
2226
  return tmp_table_field_from_field_type(table, 0);
2232
2227
}
2307
2302
    The function saves in ref the pointer to the item or to a newly created
2308
2303
    item that is considered as a replacement for the original one.
2309
2304
 
2310
 
  @param thd     reference to the global context of the query thread
 
2305
  @param session     reference to the global context of the query thread
2311
2306
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2312
2307
                 item is to be assigned
2313
2308
 
2326
2321
*/
2327
2322
 
2328
2323
bool
2329
 
Item_func_if::fix_fields(THD *thd, Item **ref)
 
2324
Item_func_if::fix_fields(Session *session, Item **ref)
2330
2325
{
2331
2326
  assert(fixed == 0);
2332
2327
  args[0]->top_level_item();
2333
2328
 
2334
 
  if (Item_func::fix_fields(thd, ref))
 
2329
  if (Item_func::fix_fields(session, ref))
2335
2330
    return 1;
2336
2331
 
2337
2332
  not_null_tables_cache= (args[1]->not_null_tables() &
2344
2339
void
2345
2340
Item_func_if::fix_length_and_dec()
2346
2341
{
2347
 
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
 
2342
  maybe_null= args[1]->maybe_null || args[2]->maybe_null;
2348
2343
  decimals= max(args[1]->decimals, args[2]->decimals);
2349
 
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
 
2344
  unsigned_flag= args[1]->unsigned_flag && args[2]->unsigned_flag;
2350
2345
 
2351
 
  enum Item_result arg1_type=args[1]->result_type();
2352
 
  enum Item_result arg2_type=args[2]->result_type();
2353
 
  bool null1=args[1]->const_item() && args[1]->null_value;
2354
 
  bool null2=args[2]->const_item() && args[2]->null_value;
 
2346
  enum Item_result arg1_type= args[1]->result_type();
 
2347
  enum Item_result arg2_type= args[2]->result_type();
 
2348
  bool null1= args[1]->const_item() && args[1]->null_value;
 
2349
  bool null2= args[2]->const_item() && args[2]->null_value;
2355
2350
 
2356
2351
  if (null1)
2357
2352
  {
2389
2384
    int len2= args[2]->max_length - args[2]->decimals
2390
2385
      - (args[2]->unsigned_flag ? 0 : 1);
2391
2386
 
2392
 
    max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2387
    max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2393
2388
  }
2394
2389
  else
2395
2390
    max_length= max(args[1]->max_length, args[2]->max_length);
2396
2391
}
2397
2392
 
2398
2393
 
2399
 
uint Item_func_if::decimal_precision() const
 
2394
uint32_t Item_func_if::decimal_precision() const
2400
2395
{
2401
 
  int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2402
 
                 decimals);
 
2396
  int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
 
2397
                  decimals);
2403
2398
  return min(precision, DECIMAL_MAX_PRECISION);
2404
2399
}
2405
2400
 
2541
2536
bool
2542
2537
Item_func_nullif::is_null()
2543
2538
{
2544
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
 
2539
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
2545
2540
}
2546
2541
 
2547
2542
 
2566
2561
           failed
2567
2562
*/
2568
2563
 
2569
 
Item *Item_func_case::find_item(String *str __attribute__((unused)))
 
2564
Item *Item_func_case::find_item(String *)
2570
2565
{
2571
 
  uint value_added_map= 0;
 
2566
  uint32_t value_added_map= 0;
2572
2567
 
2573
2568
  if (first_expr_num == -1)
2574
2569
  {
2575
 
    for (uint i=0 ; i < ncases ; i+=2)
 
2570
    for (uint32_t i=0 ; i < ncases ; i+=2)
2576
2571
    {
2577
2572
      // No expression between CASE and the first WHEN
2578
2573
      if (args[i]->val_bool())
2583
2578
  else
2584
2579
  {
2585
2580
    /* Compare every WHEN argument with it and return the first match */
2586
 
    for (uint i=0 ; i < ncases ; i+=2)
 
2581
    for (uint32_t i=0 ; i < ncases ; i+=2)
2587
2582
    {
2588
2583
      cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2589
2584
      assert(cmp_type != ROW_RESULT);
2590
 
      assert(cmp_items[(uint)cmp_type]);
2591
 
      if (!(value_added_map & (1<<(uint)cmp_type)))
 
2585
      assert(cmp_items[(uint32_t)cmp_type]);
 
2586
      if (!(value_added_map & (1<<(uint32_t)cmp_type)))
2592
2587
      {
2593
 
        cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
 
2588
        cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
2594
2589
        if ((null_value=args[first_expr_num]->null_value))
2595
2590
          return else_expr_num != -1 ? args[else_expr_num] : 0;
2596
 
        value_added_map|= 1<<(uint)cmp_type;
 
2591
        value_added_map|= 1<<(uint32_t)cmp_type;
2597
2592
      }
2598
 
      if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
 
2593
      if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2599
2594
        return args[i + 1];
2600
2595
    }
2601
2596
  }
2679
2674
}
2680
2675
 
2681
2676
 
2682
 
bool Item_func_case::fix_fields(THD *thd, Item **ref)
 
2677
bool Item_func_case::fix_fields(Session *session, Item **ref)
2683
2678
{
2684
2679
  /*
2685
2680
    buff should match stack usage from
2686
2681
    Item_func_case::val_int() -> Item_func_case::find_item()
2687
2682
  */
2688
 
  uchar buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(int64_t)*2];
2689
 
  bool res= Item_func::fix_fields(thd, ref);
 
2683
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
 
2684
                     +sizeof(double)*2+sizeof(int64_t)*2];
 
2685
  bool res= Item_func::fix_fields(session, ref);
2690
2686
  /*
2691
2687
    Call check_stack_overrun after fix_fields to be sure that stack variable
2692
2688
    is not optimized away
2693
2689
  */
2694
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
2690
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2695
2691
    return true;                                // Fatal error flag is set!
2696
2692
  return res;
2697
2693
}
2707
2703
 
2708
2704
void Item_func_case::agg_num_lengths(Item *arg)
2709
2705
{
2710
 
  uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
 
2706
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2711
2707
                                           arg->unsigned_flag) - arg->decimals;
2712
 
  set_if_bigger(max_length, len); 
 
2708
  set_if_bigger(max_length, len);
2713
2709
  set_if_bigger(decimals, arg->decimals);
2714
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
 
2710
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
2715
2711
}
2716
2712
 
2717
2713
 
2718
2714
void Item_func_case::fix_length_and_dec()
2719
2715
{
2720
2716
  Item **agg;
2721
 
  uint nagg;
2722
 
  uint found_types= 0;
 
2717
  uint32_t nagg;
 
2718
  uint32_t found_types= 0;
2723
2719
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2724
2720
    return;
2725
 
  
 
2721
 
2726
2722
  /*
2727
2723
    Aggregate all THEN and ELSE expression types
2728
2724
    and collations when string result
2729
2725
  */
2730
 
  
 
2726
 
2731
2727
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2732
2728
    agg[nagg]= args[nagg*2+1];
2733
 
  
 
2729
 
2734
2730
  if (else_expr_num != -1)
2735
2731
    agg[nagg++]= args[else_expr_num];
2736
 
  
 
2732
 
2737
2733
  agg_result_type(&cached_result_type, agg, nagg);
2738
2734
  if ((cached_result_type == STRING_RESULT) &&
2739
2735
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2740
2736
    return;
2741
 
  
 
2737
 
2742
2738
  cached_field_type= agg_field_type(agg, nagg);
2743
2739
  /*
2744
2740
    Aggregate first expression and all THEN expression types
2746
2742
  */
2747
2743
  if (first_expr_num != -1)
2748
2744
  {
2749
 
    uint i;
 
2745
    uint32_t i;
2750
2746
    agg[0]= args[first_expr_num];
2751
2747
    left_result_type= agg[0]->result_type();
2752
2748
 
2756
2752
    if (!(found_types= collect_cmp_types(agg, nagg)))
2757
2753
      return;
2758
2754
 
2759
 
    for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
 
2755
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2760
2756
    {
2761
2757
      if (found_types & (1 << i) && !cmp_items[i])
2762
2758
      {
2774
2770
 
2775
2771
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2776
2772
    maybe_null=1;
2777
 
  
 
2773
 
2778
2774
  max_length=0;
2779
2775
  decimals=0;
2780
2776
  unsigned_flag= true;
2781
2777
  if (cached_result_type == STRING_RESULT)
2782
2778
  {
2783
 
    for (uint i= 0; i < ncases; i+= 2)
 
2779
    for (uint32_t i= 0; i < ncases; i+= 2)
2784
2780
      agg_str_lengths(args[i + 1]);
2785
2781
    if (else_expr_num != -1)
2786
2782
      agg_str_lengths(args[else_expr_num]);
2787
2783
  }
2788
2784
  else
2789
2785
  {
2790
 
    for (uint i= 0; i < ncases; i+= 2)
 
2786
    for (uint32_t i= 0; i < ncases; i+= 2)
2791
2787
      agg_num_lengths(args[i + 1]);
2792
 
    if (else_expr_num != -1) 
 
2788
    if (else_expr_num != -1)
2793
2789
      agg_num_lengths(args[else_expr_num]);
2794
2790
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2795
2791
                                               unsigned_flag);
2797
2793
}
2798
2794
 
2799
2795
 
2800
 
uint Item_func_case::decimal_precision() const
 
2796
uint32_t Item_func_case::decimal_precision() const
2801
2797
{
2802
2798
  int max_int_part=0;
2803
 
  for (uint i=0 ; i < ncases ; i+=2)
 
2799
  for (uint32_t i=0 ; i < ncases ; i+=2)
2804
2800
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2805
2801
 
2806
 
  if (else_expr_num != -1) 
 
2802
  if (else_expr_num != -1)
2807
2803
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2808
2804
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2809
2805
}
2822
2818
    args[first_expr_num]->print(str, query_type);
2823
2819
    str->append(' ');
2824
2820
  }
2825
 
  for (uint i=0 ; i < ncases ; i+=2)
 
2821
  for (uint32_t i=0 ; i < ncases ; i+=2)
2826
2822
  {
2827
2823
    str->append(STRING_WITH_LEN("when "));
2828
2824
    args[i]->print(str, query_type);
2842
2838
 
2843
2839
void Item_func_case::cleanup()
2844
2840
{
2845
 
  uint i;
 
2841
  uint32_t i;
2846
2842
  Item_func::cleanup();
2847
 
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
 
2843
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2848
2844
  {
2849
2845
    delete cmp_items[i];
2850
2846
    cmp_items[i]= 0;
2861
2857
{
2862
2858
  assert(fixed == 1);
2863
2859
  null_value=0;
2864
 
  for (uint i=0 ; i < arg_count ; i++)
 
2860
  for (uint32_t i=0 ; i < arg_count ; i++)
2865
2861
  {
2866
2862
    String *res;
2867
2863
    if ((res=args[i]->val_str(str)))
2875
2871
{
2876
2872
  assert(fixed == 1);
2877
2873
  null_value=0;
2878
 
  for (uint i=0 ; i < arg_count ; i++)
 
2874
  for (uint32_t i=0 ; i < arg_count ; i++)
2879
2875
  {
2880
2876
    int64_t res=args[i]->val_int();
2881
2877
    if (!args[i]->null_value)
2889
2885
{
2890
2886
  assert(fixed == 1);
2891
2887
  null_value=0;
2892
 
  for (uint i=0 ; i < arg_count ; i++)
 
2888
  for (uint32_t i=0 ; i < arg_count ; i++)
2893
2889
  {
2894
2890
    double res= args[i]->val_real();
2895
2891
    if (!args[i]->null_value)
2904
2900
{
2905
2901
  assert(fixed == 1);
2906
2902
  null_value= 0;
2907
 
  for (uint i= 0; i < arg_count; i++)
 
2903
  for (uint32_t i= 0; i < arg_count; i++)
2908
2904
  {
2909
2905
    my_decimal *res= args[i]->val_decimal(decimal_value);
2910
2906
    if (!args[i]->null_value)
2994
2990
 
2995
2991
 
2996
2992
/*
2997
 
  Compare two integers in IN value list format (packed_int64_t) 
 
2993
  Compare two integers in IN value list format (packed_int64_t)
2998
2994
 
2999
2995
  SYNOPSIS
3000
2996
    cmp_int64_t()
3016
3012
    0           left argument is equal to the right argument.
3017
3013
    1           left argument is greater than the right argument.
3018
3014
*/
3019
 
int cmp_int64_t(void *cmp_arg __attribute__((unused)),
3020
 
                 in_int64_t::packed_int64_t *a,
3021
 
                 in_int64_t::packed_int64_t *b)
 
3015
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
 
3016
                in_int64_t::packed_int64_t *b)
3022
3017
{
3023
3018
  if (a->unsigned_flag != b->unsigned_flag)
3024
 
  { 
3025
 
    /* 
3026
 
      One of the args is unsigned and is too big to fit into the 
 
3019
  {
 
3020
    /*
 
3021
      One of the args is unsigned and is too big to fit into the
3027
3022
      positive signed range. Report no match.
3028
 
    */  
 
3023
    */
3029
3024
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3030
3025
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3031
3026
      return a->unsigned_flag ? 1 : -1;
3032
3027
    /*
3033
 
      Although the signedness differs both args can fit into the signed 
 
3028
      Although the signedness differs both args can fit into the signed
3034
3029
      positive range. Make them signed and compare as usual.
3035
 
    */  
 
3030
    */
3036
3031
    return cmp_longs (a->val, b->val);
3037
3032
  }
3038
3033
  if (a->unsigned_flag)
3041
3036
    return cmp_longs (a->val, b->val);
3042
3037
}
3043
3038
 
3044
 
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
 
3039
static int cmp_double(void *, double *a, double *b)
3045
3040
{
3046
3041
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3047
3042
}
3048
3043
 
3049
 
static int cmp_row(void *cmp_arg __attribute__((unused)), cmp_item_row *a, cmp_item_row *b)
 
3044
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
3050
3045
{
3051
3046
  return a->compare(b);
3052
3047
}
3053
3048
 
3054
3049
 
3055
 
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
 
3050
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
3056
3051
{
3057
3052
  /*
3058
3053
    We need call of fixing buffer pointer, because fast sort just copy
3066
3061
 
3067
3062
int in_vector::find(Item *item)
3068
3063
{
3069
 
  uchar *result=get_value(item);
 
3064
  unsigned char *result=get_value(item);
3070
3065
  if (!result || !used_count)
3071
3066
    return 0;                           // Null value
3072
3067
 
3073
 
  uint start,end;
 
3068
  uint32_t start,end;
3074
3069
  start=0; end=used_count-1;
3075
3070
  while (start != end)
3076
3071
  {
3077
 
    uint mid=(start+end+1)/2;
 
3072
    uint32_t mid=(start+end+1)/2;
3078
3073
    int res;
3079
3074
    if ((res=(*compare)(collation, base+mid*size, result)) == 0)
3080
3075
      return 1;
3086
3081
  return (int) ((*compare)(collation, base+start*size, result) == 0);
3087
3082
}
3088
3083
 
3089
 
in_string::in_string(uint elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
 
3084
in_string::in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
3090
3085
  :in_vector(elements, sizeof(String), cmp_func, cs),
3091
3086
   tmp(buff, sizeof(buff), &my_charset_bin)
3092
3087
{}
3096
3091
  if (base)
3097
3092
  {
3098
3093
    // base was allocated with help of sql_alloc => following is OK
3099
 
    for (uint i=0 ; i < count ; i++)
 
3094
    for (uint32_t i=0 ; i < count ; i++)
3100
3095
      ((String*) base)[i].free();
3101
3096
  }
3102
3097
}
3103
3098
 
3104
 
void in_string::set(uint pos,Item *item)
 
3099
void in_string::set(uint32_t pos,Item *item)
3105
3100
{
3106
3101
  String *str=((String*) base)+pos;
3107
3102
  String *res=item->val_str(str);
3124
3119
}
3125
3120
 
3126
3121
 
3127
 
uchar *in_string::get_value(Item *item)
 
3122
unsigned char *in_string::get_value(Item *item)
3128
3123
{
3129
 
  return (uchar*) item->val_str(&tmp);
 
3124
  return (unsigned char*) item->val_str(&tmp);
3130
3125
}
3131
3126
 
3132
 
in_row::in_row(uint elements, Item * item __attribute__((unused)))
 
3127
in_row::in_row(uint32_t elements, Item *)
3133
3128
{
3134
3129
  base= (char*) new cmp_item_row[count= elements];
3135
3130
  size= sizeof(cmp_item_row);
3148
3143
    delete [] (cmp_item_row*) base;
3149
3144
}
3150
3145
 
3151
 
uchar *in_row::get_value(Item *item)
 
3146
unsigned char *in_row::get_value(Item *item)
3152
3147
{
3153
3148
  tmp.store_value(item);
3154
3149
  if (item->is_null())
3155
3150
    return 0;
3156
 
  return (uchar *)&tmp;
 
3151
  return (unsigned char *)&tmp;
3157
3152
}
3158
3153
 
3159
 
void in_row::set(uint pos, Item *item)
 
3154
void in_row::set(uint32_t pos, Item *item)
3160
3155
{
3161
3156
  ((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
3162
3157
  return;
3163
3158
}
3164
3159
 
3165
 
in_int64_t::in_int64_t(uint elements)
 
3160
in_int64_t::in_int64_t(uint32_t elements)
3166
3161
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3167
3162
{}
3168
3163
 
3169
 
void in_int64_t::set(uint pos,Item *item)
 
3164
void in_int64_t::set(uint32_t pos,Item *item)
3170
3165
{
3171
3166
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3172
 
  
 
3167
 
3173
3168
  buff->val= item->val_int();
3174
3169
  buff->unsigned_flag= item->unsigned_flag;
3175
3170
}
3176
3171
 
3177
 
uchar *in_int64_t::get_value(Item *item)
 
3172
unsigned char *in_int64_t::get_value(Item *item)
3178
3173
{
3179
3174
  tmp.val= item->val_int();
3180
3175
  if (item->null_value)
3181
3176
    return 0;
3182
3177
  tmp.unsigned_flag= item->unsigned_flag;
3183
 
  return (uchar*) &tmp;
 
3178
  return (unsigned char*) &tmp;
3184
3179
}
3185
3180
 
3186
 
void in_datetime::set(uint pos,Item *item)
 
3181
void in_datetime::set(uint32_t pos,Item *item)
3187
3182
{
3188
3183
  Item **tmp_item= &item;
3189
3184
  bool is_null;
3190
3185
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3191
3186
 
3192
 
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3187
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3193
3188
  buff->unsigned_flag= 1L;
3194
3189
}
3195
3190
 
3196
 
uchar *in_datetime::get_value(Item *item)
 
3191
unsigned char *in_datetime::get_value(Item *item)
3197
3192
{
3198
3193
  bool is_null;
3199
3194
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3200
 
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3195
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3201
3196
  if (item->null_value)
3202
3197
    return 0;
3203
3198
  tmp.unsigned_flag= 1L;
3204
 
  return (uchar*) &tmp;
 
3199
  return (unsigned char*) &tmp;
3205
3200
}
3206
3201
 
3207
 
in_double::in_double(uint elements)
 
3202
in_double::in_double(uint32_t elements)
3208
3203
  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
3209
3204
{}
3210
3205
 
3211
 
void in_double::set(uint pos,Item *item)
 
3206
void in_double::set(uint32_t pos,Item *item)
3212
3207
{
3213
3208
  ((double*) base)[pos]= item->val_real();
3214
3209
}
3215
3210
 
3216
 
uchar *in_double::get_value(Item *item)
 
3211
unsigned char *in_double::get_value(Item *item)
3217
3212
{
3218
3213
  tmp= item->val_real();
3219
3214
  if (item->null_value)
3220
 
    return 0;                                   /* purecov: inspected */
3221
 
  return (uchar*) &tmp;
 
3215
    return 0;
 
3216
  return (unsigned char*) &tmp;
3222
3217
}
3223
3218
 
3224
3219
 
3225
 
in_decimal::in_decimal(uint elements)
 
3220
in_decimal::in_decimal(uint32_t elements)
3226
3221
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3227
3222
{}
3228
3223
 
3229
3224
 
3230
 
void in_decimal::set(uint pos, Item *item)
 
3225
void in_decimal::set(uint32_t pos, Item *item)
3231
3226
{
3232
3227
  /* as far as 'item' is constant, we can store reference on my_decimal */
3233
3228
  my_decimal *dec= ((my_decimal *)base) + pos;
3234
3229
  dec->len= DECIMAL_BUFF_LENGTH;
3235
3230
  dec->fix_buffer_pointer();
3236
3231
  my_decimal *res= item->val_decimal(dec);
3237
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
 
3232
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
3238
3233
  if (!item->null_value && res != dec)
3239
3234
    my_decimal2decimal(res, dec);
3240
3235
}
3241
3236
 
3242
3237
 
3243
 
uchar *in_decimal::get_value(Item *item)
 
3238
unsigned char *in_decimal::get_value(Item *item)
3244
3239
{
3245
3240
  my_decimal *result= item->val_decimal(&val);
3246
3241
  if (item->null_value)
3247
3242
    return 0;
3248
 
  return (uchar *)result;
 
3243
  return (unsigned char *)result;
3249
3244
}
3250
3245
 
3251
3246
 
3296
3291
{
3297
3292
  if (comparators)
3298
3293
  {
3299
 
    for (uint i= 0; i < n; i++)
 
3294
    for (uint32_t i= 0; i < n; i++)
3300
3295
    {
3301
3296
      if (comparators[i])
3302
3297
        delete comparators[i];
3309
3304
void cmp_item_row::alloc_comparators()
3310
3305
{
3311
3306
  if (!comparators)
3312
 
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
 
3307
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
3313
3308
}
3314
3309
 
3315
3310
 
3321
3316
  {
3322
3317
    item->bring_value();
3323
3318
    item->null_value= 0;
3324
 
    for (uint i=0; i < n; i++)
 
3319
    for (uint32_t i=0; i < n; i++)
3325
3320
    {
3326
3321
      if (!comparators[i])
3327
3322
        if (!(comparators[i]=
3349
3344
  {
3350
3345
    item->bring_value();
3351
3346
    item->null_value= 0;
3352
 
    for (uint i=0; i < n; i++)
 
3347
    for (uint32_t i=0; i < n; i++)
3353
3348
    {
3354
3349
      if (!(comparators[i]= tmpl->comparators[i]->make_same()))
3355
3350
        break;                                  // new failed
3371
3366
  }
3372
3367
  bool was_null= 0;
3373
3368
  arg->bring_value();
3374
 
  for (uint i=0; i < n; i++)
 
3369
  for (uint32_t i=0; i < n; i++)
3375
3370
  {
3376
3371
    if (comparators[i]->cmp(arg->element_index(i)))
3377
3372
    {
3387
3382
int cmp_item_row::compare(cmp_item *c)
3388
3383
{
3389
3384
  cmp_item_row *l_cmp= (cmp_item_row *) c;
3390
 
  for (uint i=0; i < n; i++)
 
3385
  for (uint32_t i=0; i < n; i++)
3391
3386
  {
3392
3387
    int res;
3393
3388
    if ((res= comparators[i]->compare(l_cmp->comparators[i])))
3432
3427
{
3433
3428
  bool is_null;
3434
3429
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3435
 
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3430
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3436
3431
}
3437
3432
 
3438
3433
 
3441
3436
  bool is_null;
3442
3437
  Item **tmp_item= &arg;
3443
3438
  return value !=
3444
 
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3439
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3445
3440
}
3446
3441
 
3447
3442
 
3478
3473
    The function saves in ref the pointer to the item or to a newly created
3479
3474
    item that is considered as a replacement for the original one.
3480
3475
 
3481
 
  @param thd     reference to the global context of the query thread
 
3476
  @param session     reference to the global context of the query thread
3482
3477
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3483
3478
                 item is to be assigned
3484
3479
 
3499
3494
*/
3500
3495
 
3501
3496
bool
3502
 
Item_func_in::fix_fields(THD *thd, Item **ref)
 
3497
Item_func_in::fix_fields(Session *session, Item **ref)
3503
3498
{
3504
3499
  Item **arg, **arg_end;
3505
3500
 
3506
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
3501
  if (Item_func_opt_neg::fix_fields(session, ref))
3507
3502
    return 1;
3508
3503
 
3509
3504
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3522
3517
static int srtcmp_in(const CHARSET_INFO * const cs, const String *x,const String *y)
3523
3518
{
3524
3519
  return cs->coll->strnncollsp(cs,
3525
 
                               (uchar *) x->ptr(),x->length(),
3526
 
                               (uchar *) y->ptr(),y->length(), 0);
 
3520
                               (unsigned char *) x->ptr(),x->length(),
 
3521
                               (unsigned char *) y->ptr(),y->length(), 0);
3527
3522
}
3528
3523
 
3529
3524
 
3531
3526
{
3532
3527
  Item **arg, **arg_end;
3533
3528
  bool const_itm= 1;
3534
 
  THD *thd= current_thd;
 
3529
  Session *session= current_session;
3535
3530
  bool datetime_found= false;
3536
3531
  /* true <=> arguments values will be compared as DATETIMEs. */
3537
3532
  bool compare_as_datetime= false;
3538
3533
  Item *date_arg= 0;
3539
 
  uint found_types= 0;
3540
 
  uint type_cnt= 0, i;
 
3534
  uint32_t found_types= 0;
 
3535
  uint32_t type_cnt= 0, i;
3541
3536
  Item_result cmp_type= STRING_RESULT;
3542
3537
  left_result_type= args[0]->result_type();
3543
 
  if (!(found_types= collect_cmp_types(args, arg_count)))
 
3538
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
3544
3539
    return;
3545
 
  
 
3540
 
3546
3541
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3547
3542
  {
3548
3543
    if (!arg[0]->const_item())
3551
3546
      break;
3552
3547
    }
3553
3548
  }
3554
 
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
 
3549
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
3555
3550
  {
3556
3551
    if (found_types & 1 << i)
3557
3552
    {
3562
3557
 
3563
3558
  if (type_cnt == 1)
3564
3559
  {
3565
 
    if (cmp_type == STRING_RESULT && 
 
3560
    if (cmp_type == STRING_RESULT &&
3566
3561
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3567
3562
      return;
3568
3563
    arg_types_compatible= true;
3593
3588
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3594
3589
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3595
3590
    {
3596
 
      uint col, cols= args[0]->cols();
 
3591
      uint32_t col, num_cols= args[0]->cols();
3597
3592
 
3598
 
      for (col= 0; col < cols; col++)
 
3593
      for (col= 0; col < num_cols; col++)
3599
3594
      {
3600
3595
        bool skip_column= false;
3601
3596
        /*
3664
3659
      /*
3665
3660
        IN must compare INT columns and constants as int values (the same
3666
3661
        way as equality does).
3667
 
        So we must check here if the column on the left and all the constant 
3668
 
        values on the right can be compared as integers and adjust the 
 
3662
        So we must check here if the column on the left and all the constant
 
3663
        values on the right can be compared as integers and adjust the
3669
3664
        comparison type accordingly.
3670
 
      */  
 
3665
      */
3671
3666
      if (args[0]->real_item()->type() == FIELD_ITEM &&
3672
 
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
 
3667
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3673
3668
          cmp_type != INT_RESULT)
3674
3669
      {
3675
3670
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3678
3673
          bool all_converted= true;
3679
3674
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3680
3675
          {
3681
 
            if (!convert_constant_item (thd, field_item, &arg[0]))
 
3676
            if (!convert_constant_item (session, field_item, &arg[0]))
3682
3677
              all_converted= false;
3683
3678
          }
3684
3679
          if (all_converted)
3687
3682
      }
3688
3683
      switch (cmp_type) {
3689
3684
      case STRING_RESULT:
3690
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
 
3685
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3691
3686
                            cmp_collation.collation);
3692
3687
        break;
3693
3688
      case INT_RESULT:
3712
3707
        return;
3713
3708
      }
3714
3709
    }
3715
 
    if (array && !(thd->is_fatal_error))                // If not EOM
 
3710
    if (array && !(session->is_fatal_error))            // If not EOM
3716
3711
    {
3717
 
      uint j=0;
3718
 
      for (uint i=1 ; i < arg_count ; i++)
 
3712
      uint32_t j=0;
 
3713
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3719
3714
      {
3720
 
        array->set(j,args[i]);
3721
 
        if (!args[i]->null_value)                       // Skip NULL values
 
3715
        if (!args[arg_num]->null_value)                 // Skip NULL values
 
3716
        {
 
3717
          array->set(j,args[arg_num]);
3722
3718
          j++;
 
3719
        }
3723
3720
        else
3724
3721
          have_null= 1;
3725
3722
      }
3733
3730
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3734
3731
    else
3735
3732
    {
3736
 
      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
 
3733
      for (i= 0; i <= (uint32_t) DECIMAL_RESULT; i++)
3737
3734
      {
3738
3735
        if (found_types & (1 << i) && !cmp_items[i])
3739
3736
        {
3794
3791
{
3795
3792
  cmp_item *in_item;
3796
3793
  assert(fixed == 1);
3797
 
  uint value_added_map= 0;
 
3794
  uint32_t value_added_map= 0;
3798
3795
  if (array)
3799
3796
  {
3800
3797
    int tmp=array->find(args[0]);
3802
3799
    return (int64_t) (!null_value && tmp != negated);
3803
3800
  }
3804
3801
 
3805
 
  for (uint i= 1 ; i < arg_count ; i++)
 
3802
  for (uint32_t i= 1 ; i < arg_count ; i++)
3806
3803
  {
3807
3804
    Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3808
 
    in_item= cmp_items[(uint)cmp_type];
 
3805
    in_item= cmp_items[(uint32_t)cmp_type];
3809
3806
    assert(in_item);
3810
 
    if (!(value_added_map & (1 << (uint)cmp_type)))
 
3807
    if (!(value_added_map & (1 << (uint32_t)cmp_type)))
3811
3808
    {
3812
3809
      in_item->store_value(args[0]);
3813
3810
      if ((null_value=args[0]->null_value))
3814
3811
        return 0;
3815
3812
      have_null= 0;
3816
 
      value_added_map|= 1 << (uint)cmp_type;
 
3813
      value_added_map|= 1 << (uint32_t)cmp_type;
3817
3814
    }
3818
3815
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
3819
3816
      return (int64_t) (!negated);
3825
3822
}
3826
3823
 
3827
3824
 
3828
 
int64_t Item_func_bit_or::val_int()
3829
 
{
3830
 
  assert(fixed == 1);
3831
 
  uint64_t arg1= (uint64_t) args[0]->val_int();
3832
 
  if (args[0]->null_value)
3833
 
  {
3834
 
    null_value=1; /* purecov: inspected */
3835
 
    return 0; /* purecov: inspected */
3836
 
  }
3837
 
  uint64_t arg2= (uint64_t) args[1]->val_int();
3838
 
  if (args[1]->null_value)
3839
 
  {
3840
 
    null_value=1;
3841
 
    return 0;
3842
 
  }
3843
 
  null_value=0;
3844
 
  return (int64_t) (arg1 | arg2);
3845
 
}
3846
 
 
3847
 
 
3848
 
int64_t Item_func_bit_and::val_int()
3849
 
{
3850
 
  assert(fixed == 1);
3851
 
  uint64_t arg1= (uint64_t) args[0]->val_int();
3852
 
  if (args[0]->null_value)
3853
 
  {
3854
 
    null_value=1; /* purecov: inspected */
3855
 
    return 0; /* purecov: inspected */
3856
 
  }
3857
 
  uint64_t arg2= (uint64_t) args[1]->val_int();
3858
 
  if (args[1]->null_value)
3859
 
  {
3860
 
    null_value=1; /* purecov: inspected */
3861
 
    return 0; /* purecov: inspected */
3862
 
  }
3863
 
  null_value=0;
3864
 
  return (int64_t) (arg1 & arg2);
3865
 
}
3866
 
 
3867
 
Item_cond::Item_cond(THD *thd, Item_cond *item)
3868
 
  :Item_bool_func(thd, item),
 
3825
Item_cond::Item_cond(Session *session, Item_cond *item)
 
3826
  :Item_bool_func(session, item),
3869
3827
   abort_on_null(item->abort_on_null),
3870
3828
   and_tables_cache(item->and_tables_cache)
3871
3829
{
3875
3833
}
3876
3834
 
3877
3835
 
3878
 
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
 
3836
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3879
3837
{
3880
3838
  List_iterator_fast<Item> li(item->list);
3881
3839
  while (Item *it= li++)
3882
 
    list.push_back(it->copy_andor_structure(thd));
 
3840
    list.push_back(it->copy_andor_structure(session));
3883
3841
}
3884
3842
 
3885
3843
 
3886
3844
bool
3887
 
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
 
3845
Item_cond::fix_fields(Session *session, Item **)
3888
3846
{
3889
3847
  assert(fixed == 0);
3890
3848
  List_iterator<Item> li(list);
3891
3849
  Item *item;
3892
 
  void *orig_thd_marker= thd->thd_marker;
3893
 
  uchar buff[sizeof(char*)];                    // Max local vars in function
 
3850
  void *orig_session_marker= session->session_marker;
 
3851
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3894
3852
  not_null_tables_cache= used_tables_cache= 0;
3895
3853
  const_item_cache= 1;
3896
3854
 
3897
3855
  if (functype() == COND_OR_FUNC)
3898
 
    thd->thd_marker= 0;
 
3856
    session->session_marker= 0;
3899
3857
  /*
3900
3858
    and_table_cache is the value that Item_cond_or() returns for
3901
3859
    not_null_tables()
3902
3860
  */
3903
3861
  and_tables_cache= ~(table_map) 0;
3904
3862
 
3905
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
3863
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3906
3864
    return true;                                // Fatal error flag is set!
3907
3865
  /*
3908
3866
    The following optimization reduces the depth of an AND-OR tree.
3935
3893
 
3936
3894
    // item can be substituted in fix_fields
3937
3895
    if ((!item->fixed &&
3938
 
         item->fix_fields(thd, li.ref())) ||
 
3896
         item->fix_fields(session, li.ref())) ||
3939
3897
        (item= *li.ref())->check_cols(1))
3940
 
      return true; /* purecov: inspected */
 
3898
      return true;
3941
3899
    used_tables_cache|=     item->used_tables();
3942
3900
    if (item->const_item())
3943
3901
      and_tables_cache= (table_map) 0;
3947
3905
      not_null_tables_cache|= tmp_table_map;
3948
3906
      and_tables_cache&= tmp_table_map;
3949
3907
      const_item_cache= false;
3950
 
    }  
 
3908
    }
3951
3909
    with_sum_func=          with_sum_func || item->with_sum_func;
3952
3910
    with_subselect|=        item->with_subselect;
3953
3911
    if (item->maybe_null)
3954
3912
      maybe_null=1;
3955
3913
  }
3956
 
  thd->lex->current_select->cond_count+= list.elements;
3957
 
  thd->thd_marker= orig_thd_marker;
 
3914
  session->lex->current_select->cond_count+= list.elements;
 
3915
  session->session_marker= orig_session_marker;
3958
3916
  fix_length_and_dec();
3959
3917
  fixed= 1;
3960
3918
  return false;
3961
3919
}
3962
3920
 
3963
3921
 
3964
 
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
 
3922
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3965
3923
{
3966
3924
  List_iterator<Item> li(list);
3967
3925
  Item *item;
3988
3946
      not_null_tables_cache|= tmp_table_map;
3989
3947
      and_tables_cache&= tmp_table_map;
3990
3948
      const_item_cache= false;
3991
 
    }  
 
3949
    }
3992
3950
  }
3993
3951
}
3994
3952
 
3995
3953
 
3996
 
bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
 
3954
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
3997
3955
{
3998
3956
  List_iterator_fast<Item> li(list);
3999
3957
  Item *item;
4006
3964
 
4007
3965
/**
4008
3966
  Transform an Item_cond object with a transformer callback function.
4009
 
  
 
3967
 
4010
3968
    The function recursively applies the transform method to each
4011
3969
     member item of the condition list.
4012
3970
    If the call of the method for a member item returns a new item
4013
3971
    the old item is substituted for a new one.
4014
3972
    After this the transformer is applied to the root node
4015
 
    of the Item_cond object. 
4016
 
     
 
3973
    of the Item_cond object.
 
3974
 
4017
3975
  @param transformer   the transformer callback function to be applied to
4018
3976
                       the nodes of the tree of the object
4019
3977
  @param arg           parameter to be passed to the transformer
4020
3978
 
4021
3979
  @return
4022
 
    Item returned as the result of transformation of the root node 
 
3980
    Item returned as the result of transformation of the root node
4023
3981
*/
4024
3982
 
4025
 
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
 
3983
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4026
3984
{
4027
3985
  List_iterator<Item> li(list);
4028
3986
  Item *item;
4033
3991
      return 0;
4034
3992
 
4035
3993
    /*
4036
 
      THD::change_item_tree() should be called only if the tree was
 
3994
      Session::change_item_tree() should be called only if the tree was
4037
3995
      really transformed, i.e. when a new item has been created.
4038
3996
      Otherwise we'll be allocating a lot of unnecessary memory for
4039
3997
      change records at each execution.
4040
3998
    */
4041
3999
    if (new_item != item)
4042
 
      current_thd->change_item_tree(li.ref(), new_item);
 
4000
      current_session->change_item_tree(li.ref(), new_item);
4043
4001
  }
4044
4002
  return Item_func::transform(transformer, arg);
4045
4003
}
4048
4006
/**
4049
4007
  Compile Item_cond object with a processor and a transformer
4050
4008
  callback functions.
4051
 
  
 
4009
 
4052
4010
    First the function applies the analyzer to the root node of
4053
4011
    the Item_func object. Then if the analyzer succeeeds (returns true)
4054
4012
    the function recursively applies the compile method to member
4056
4014
    If the call of the method for a member item returns a new item
4057
4015
    the old item is substituted for a new one.
4058
4016
    After this the transformer is applied to the root node
4059
 
    of the Item_cond object. 
4060
 
     
 
4017
    of the Item_cond object.
 
4018
 
4061
4019
  @param analyzer      the analyzer callback function to be applied to the
4062
4020
                       nodes of the tree of the object
4063
4021
  @param[in,out] arg_p parameter to be passed to the analyzer
4066
4024
  @param arg_t         parameter to be passed to the transformer
4067
4025
 
4068
4026
  @return
4069
 
    Item returned as the result of transformation of the root node 
 
4027
    Item returned as the result of transformation of the root node
4070
4028
*/
4071
4029
 
4072
 
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
4073
 
                         Item_transformer transformer, uchar *arg_t)
 
4030
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
 
4031
                         Item_transformer transformer, unsigned char *arg_t)
4074
4032
{
4075
4033
  if (!(this->*analyzer)(arg_p))
4076
4034
    return 0;
4077
 
  
 
4035
 
4078
4036
  List_iterator<Item> li(list);
4079
4037
  Item *item;
4080
4038
  while ((item= li++))
4081
4039
  {
4082
 
    /* 
 
4040
    /*
4083
4041
      The same parameter value of arg_p must be passed
4084
4042
      to analyze any argument of the condition formula.
4085
 
    */   
4086
 
    uchar *arg_v= *arg_p;
 
4043
    */
 
4044
    unsigned char *arg_v= *arg_p;
4087
4045
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4088
4046
    if (new_item && new_item != item)
4089
4047
      li.replace(new_item);
4097
4055
  List_iterator<Item> li(list);
4098
4056
  Item *item;
4099
4057
 
4100
 
  switch(order) {
4101
 
  case(PREFIX):
 
4058
  switch (order) {
 
4059
  case (T_PREFIX):
4102
4060
    (*traverser)(this, arg);
4103
4061
    while ((item= li++))
4104
4062
    {
4106
4064
    }
4107
4065
    (*traverser)(NULL, arg);
4108
4066
    break;
4109
 
  case(POSTFIX):
 
4067
  case (T_POSTFIX):
4110
4068
    while ((item= li++))
4111
4069
    {
4112
4070
      item->traverse_cond(traverser, arg, order);
4123
4081
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4124
4082
  sql_select.cc)
4125
4083
 
4126
 
  @param thd                    Thread handler
 
4084
  @param session                        Thread handler
4127
4085
  @param ref_pointer_array      Pointer to array of reference fields
4128
4086
  @param fields         All fields in select
4129
4087
 
4132
4090
    that have or refer (HAVING) to a SUM expression.
4133
4091
*/
4134
4092
 
4135
 
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
 
4093
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4136
4094
                               List<Item> &fields)
4137
4095
{
4138
4096
  List_iterator<Item> li(list);
4139
4097
  Item *item;
4140
4098
  while ((item= li++))
4141
 
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
 
4099
    item->split_sum_func(session, ref_pointer_array,
 
4100
                         fields, li.ref(), true);
4142
4101
}
4143
4102
 
4144
4103
 
4183
4142
}
4184
4143
 
4185
4144
 
4186
 
void Item_cond::neg_arguments(THD *thd)
 
4145
void Item_cond::neg_arguments(Session *session)
4187
4146
{
4188
4147
  List_iterator<Item> li(list);
4189
4148
  Item *item;
4190
4149
  while ((item= li++))          /* Apply not transformation to the arguments */
4191
4150
  {
4192
 
    Item *new_item= item->neg_transformer(thd);
 
4151
    Item *new_item= item->neg_transformer(session);
4193
4152
    if (!new_item)
4194
4153
    {
4195
4154
      if (!(new_item= new Item_func_not(item)))
4196
4155
        return;                                 // Fatal OEM error
4197
4156
    }
4198
 
    VOID(li.replace(new_item));
 
4157
    li.replace(new_item);
4199
4158
  }
4200
4159
}
4201
4160
 
4384
4343
  if (canDoTurboBM)
4385
4344
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4386
4345
  return my_wildcmp(cmp.cmp_collation.collation,
4387
 
                    res->ptr(),res->ptr()+res->length(),
 
4346
                    res->ptr(),res->ptr()+res->length(),
4388
4347
                    res2->ptr(),res2->ptr()+res2->length(),
4389
 
                    escape,wild_one,wild_many) ? 0 : 1;
 
4348
                    make_escape_code(cmp.cmp_collation.collation, escape),
 
4349
                    wild_one,wild_many) ? 0 : 1;
4390
4350
}
4391
4351
 
4392
4352
 
4413
4373
}
4414
4374
 
4415
4375
 
4416
 
bool Item_func_like::fix_fields(THD *thd, Item **ref)
 
4376
bool Item_func_like::fix_fields(Session *session, Item **ref)
4417
4377
{
4418
4378
  assert(fixed == 0);
4419
 
  if (Item_bool_func2::fix_fields(thd, ref) ||
4420
 
      escape_item->fix_fields(thd, &escape_item))
 
4379
  if (Item_bool_func2::fix_fields(session, ref) ||
 
4380
      escape_item->fix_fields(session, &escape_item))
4421
4381
    return true;
4422
4382
 
4423
4383
  if (!escape_item->const_during_execution())
4425
4385
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4426
4386
    return true;
4427
4387
  }
4428
 
  
 
4388
 
4429
4389
  if (escape_item->const_item())
4430
4390
  {
 
4391
    
4431
4392
    /* If we are on execution stage */
4432
4393
    String *escape_str= escape_item->val_str(&tmp_value1);
4433
4394
    if (escape_str)
4434
4395
    {
4435
 
      if (escape_used_in_parsing && (
4436
 
             (((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
4437
 
                escape_str->numchars() != 1) ||
4438
 
               escape_str->numchars() > 1)))
4439
 
      {
4440
 
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4441
 
        return true;
4442
 
      }
4443
 
 
4444
 
      if (use_mb(cmp.cmp_collation.collation))
4445
 
      {
4446
 
        const CHARSET_INFO * const cs= escape_str->charset();
4447
 
        my_wc_t wc;
4448
 
        int rc= cs->cset->mb_wc(cs, &wc,
4449
 
                                (const uchar*) escape_str->ptr(),
4450
 
                                (const uchar*) escape_str->ptr() +
4451
 
                                               escape_str->length());
4452
 
        escape= (int) (rc > 0 ? wc : '\\');
4453
 
      }
4454
 
      else
4455
 
      {
4456
 
        /*
4457
 
          In the case of 8bit character set, we pass native
4458
 
          code instead of Unicode code as "escape" argument.
4459
 
          Convert to "cs" if charset of escape differs.
4460
 
        */
4461
 
        const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
4462
 
        uint32_t unused;
4463
 
        if (escape_str->needs_conversion(escape_str->length(),
4464
 
                                         escape_str->charset(), cs, &unused))
4465
 
        {
4466
 
          char ch;
4467
 
          uint errors;
4468
 
          uint32_t cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
4469
 
                                          escape_str->length(),
4470
 
                                          escape_str->charset(), &errors);
4471
 
          escape= cnvlen ? ch : '\\';
4472
 
        }
4473
 
        else
4474
 
          escape= *(escape_str->ptr());
4475
 
      }
 
4396
      escape= (char *)sql_alloc(escape_str->length());
 
4397
      strcpy(escape, escape_str->ptr()); 
4476
4398
    }
4477
4399
    else
4478
 
      escape= '\\';
4479
 
 
 
4400
    {
 
4401
      escape= (char *)sql_alloc(1);
 
4402
      strcpy(escape, "\\");
 
4403
    } 
 
4404
   
4480
4405
    /*
4481
4406
      We could also do boyer-more for non-const items, but as we would have to
4482
4407
      recompute the tables for each row it's not worth it.
4483
4408
    */
4484
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
4485
 
       !(specialflag & SPECIAL_NO_NEW_FUNC))
 
4409
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4486
4410
    {
4487
4411
      String* res2 = args[1]->val_str(&tmp_value2);
4488
4412
      if (!res2)
4489
4413
        return false;                           // Null argument
4490
 
      
 
4414
 
4491
4415
      const size_t len   = res2->length();
4492
4416
      const char*  first = res2->ptr();
4493
4417
      const char*  last  = first + len - 1;
4495
4419
        len must be > 2 ('%pattern%')
4496
4420
        heuristic: only do TurboBM for pattern_len > 2
4497
4421
      */
4498
 
      
 
4422
 
4499
4423
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4500
4424
          *first == wild_many &&
4501
4425
          *last  == wild_many)
4502
4426
      {
4503
4427
        const char* tmp = first + 1;
4504
 
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
 
4428
        for (; *tmp != wild_many && *tmp != wild_one; tmp++)
 
4429
        {
 
4430
          if (escape == tmp)
 
4431
            break;
 
4432
        }
 
4433
  
4505
4434
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
4506
4435
      }
4507
4436
      if (canDoTurboBM)
4508
4437
      {
4509
4438
        pattern     = first + 1;
4510
4439
        pattern_len = (int) len - 2;
4511
 
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
 
4440
        int *suff = (int*) session->alloc((int) (sizeof(int)*
4512
4441
                                      ((pattern_len + 1)*2+
4513
4442
                                      alphabet_size)));
4514
4443
        bmGs      = suff + pattern_len + 1;
4528
4457
}
4529
4458
 
4530
4459
#ifdef LIKE_CMP_TOUPPER
4531
 
#define likeconv(cs,A) (uchar) (cs)->toupper(A)
 
4460
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
4532
4461
#else
4533
 
#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
 
4462
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
4534
4463
#endif
4535
4464
 
4536
4465
 
4550
4479
 
4551
4480
  if (!cs->sort_order)
4552
4481
  {
4553
 
    int i;
4554
 
    for (i = pattern_len - 2; i >= 0; i--)
 
4482
    for (int i = pattern_len - 2; i >= 0; i--)
4555
4483
    {
4556
4484
      int tmp = *(splm1 + i - f);
4557
4485
      if (g < i && tmp < i - g)
4558
 
        suff[i] = tmp;
 
4486
        suff[i] = tmp;
4559
4487
      else
4560
4488
      {
4561
 
        if (i < g)
4562
 
          g = i; // g = min(i, g)
4563
 
        f = i;
4564
 
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4565
 
          g--;
4566
 
        suff[i] = f - g;
 
4489
        if (i < g)
 
4490
          g = i;
 
4491
        f = i;
 
4492
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
 
4493
          g--;
 
4494
        suff[i] = f - g;
4567
4495
      }
4568
4496
    }
4569
4497
  }
4570
4498
  else
4571
4499
  {
4572
 
    int i;
4573
 
    for (i = pattern_len - 2; 0 <= i; --i)
 
4500
    for (int i = pattern_len - 2; 0 <= i; --i)
4574
4501
    {
4575
4502
      int tmp = *(splm1 + i - f);
4576
4503
      if (g < i && tmp < i - g)
4577
 
        suff[i] = tmp;
 
4504
        suff[i] = tmp;
4578
4505
      else
4579
4506
      {
4580
 
        if (i < g)
4581
 
          g = i; // g = min(i, g)
4582
 
        f = i;
4583
 
        while (g >= 0 &&
4584
 
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4585
 
          g--;
4586
 
        suff[i] = f - g;
 
4507
        if (i < g)
 
4508
          g = i;
 
4509
        f = i;
 
4510
        while (g >= 0 &&
 
4511
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
 
4512
          g--;
 
4513
        suff[i] = f - g;
4587
4514
      }
4588
4515
    }
4589
4516
  }
4652
4579
  if (!cs->sort_order)
4653
4580
  {
4654
4581
    for (j = 0; j < plm1; j++)
4655
 
      bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
 
4582
      bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
4656
4583
  }
4657
4584
  else
4658
4585
  {
4659
4586
    for (j = 0; j < plm1; j++)
4660
 
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
 
4587
      bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
4661
4588
  }
4662
4589
}
4663
4590
 
4698
4625
 
4699
4626
      register const int v = plm1 - i;
4700
4627
      turboShift = u - v;
4701
 
      bcShift    = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
 
4628
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
4702
4629
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4703
4630
      shift      = (shift > bmGs[i]) ? shift : bmGs[i];
4704
4631
      if (shift == bmGs[i])
4705
4632
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4706
4633
      else
4707
4634
      {
4708
 
        if (turboShift < bcShift)
4709
 
          shift = max(shift, u + 1);
4710
 
        u = 0;
 
4635
        if (turboShift < bcShift)
 
4636
          shift= max(shift, u + 1);
 
4637
        u = 0;
4711
4638
      }
4712
4639
      j+= shift;
4713
4640
    }
4720
4647
      register int i = plm1;
4721
4648
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4722
4649
      {
4723
 
        i--;
4724
 
        if (i == plm1 - shift)
4725
 
          i-= u;
 
4650
        i--;
 
4651
        if (i == plm1 - shift)
 
4652
          i-= u;
4726
4653
      }
 
4654
 
4727
4655
      if (i < 0)
4728
 
        return 1;
 
4656
        return 1;
4729
4657
 
4730
 
      register const int v = plm1 - i;
4731
 
      turboShift = u - v;
4732
 
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
4733
 
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4734
 
      shift      = max(shift, bmGs[i]);
 
4658
      register const int v= plm1 - i;
 
4659
      turboShift= u - v;
 
4660
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
 
4661
      shift= (turboShift > bcShift) ? turboShift : bcShift;
 
4662
      shift= max(shift, bmGs[i]);
 
4663
      
4735
4664
      if (shift == bmGs[i])
4736
 
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
 
4665
        u= (pattern_len - shift < v) ? pattern_len - shift : v;
4737
4666
      else
4738
4667
      {
4739
 
        if (turboShift < bcShift)
4740
 
          shift = max(shift, u + 1);
4741
 
        u = 0;
 
4668
        if (turboShift < bcShift)
 
4669
          shift= max(shift, u + 1);
 
4670
        u = 0;
4742
4671
      }
 
4672
 
4743
4673
      j+= shift;
4744
4674
    }
4745
4675
    return 0;
4768
4698
  assert(fixed == 1);
4769
4699
  List_iterator<Item> li(list);
4770
4700
  Item *item;
4771
 
  int result=0; 
 
4701
  int result=0;
4772
4702
  null_value=0;
4773
4703
  while ((item=li++))
4774
4704
  {
4801
4731
       IS NOT NULL(a)     -> IS NULL(a)
4802
4732
    @endverbatim
4803
4733
 
4804
 
  @param thd            thread handler
 
4734
  @param session                thread handler
4805
4735
 
4806
4736
  @return
4807
4737
    New item or
4808
4738
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4809
4739
*/
4810
4740
 
4811
 
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
 
4741
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
4812
4742
{
4813
4743
  return args[0];
4814
4744
}
4815
4745
 
4816
4746
 
4817
 
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
 
4747
Item *Item_bool_rowready_func2::neg_transformer(Session *)
4818
4748
{
4819
4749
  Item *item= negated_item();
4820
4750
  return item;
4824
4754
/**
4825
4755
  a IS NULL  ->  a IS NOT NULL.
4826
4756
*/
4827
 
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
 
4757
Item *Item_func_isnull::neg_transformer(Session *)
4828
4758
{
4829
4759
  Item *item= new Item_func_isnotnull(args[0]);
4830
4760
  return item;
4834
4764
/**
4835
4765
  a IS NOT NULL  ->  a IS NULL.
4836
4766
*/
4837
 
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
 
4767
Item *Item_func_isnotnull::neg_transformer(Session *)
4838
4768
{
4839
4769
  Item *item= new Item_func_isnull(args[0]);
4840
4770
  return item;
4841
4771
}
4842
4772
 
4843
4773
 
4844
 
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
 
4774
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
4845
4775
                                        /* NOT a OR NOT b OR ... */
4846
4776
{
4847
 
  neg_arguments(thd);
 
4777
  neg_arguments(session);
4848
4778
  Item *item= new Item_cond_or(list);
4849
4779
  return item;
4850
4780
}
4851
4781
 
4852
4782
 
4853
 
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
 
4783
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
4854
4784
                                        /* NOT a AND NOT b AND ... */
4855
4785
{
4856
 
  neg_arguments(thd);
 
4786
  neg_arguments(session);
4857
4787
  Item *item= new Item_cond_and(list);
4858
4788
  return item;
4859
4789
}
4860
4790
 
4861
4791
 
4862
 
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
 
4792
Item *Item_func_nop_all::neg_transformer(Session *)
4863
4793
{
4864
4794
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4865
4795
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4870
4800
  return new_item;
4871
4801
}
4872
4802
 
4873
 
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
 
4803
Item *Item_func_not_all::neg_transformer(Session *)
4874
4804
{
4875
4805
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4876
4806
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4977
4907
  fields.push_back(f);
4978
4908
}
4979
4909
 
4980
 
uint Item_equal::members()
 
4910
uint32_t Item_equal::members()
4981
4911
{
4982
4912
  return fields.elements;
4983
4913
}
4993
4923
  @retval
4994
4924
    1       if nultiple equality contains a reference to field
4995
4925
  @retval
4996
 
    0       otherwise    
 
4926
    0       otherwise
4997
4927
*/
4998
4928
 
4999
4929
bool Item_equal::contains(Field *field)
5011
4941
 
5012
4942
/**
5013
4943
  Join members of another Item_equal object.
5014
 
  
 
4944
 
5015
4945
    The function actually merges two multiple equalities.
5016
4946
    After this operation the Item_equal object additionally contains
5017
4947
    the field items of another item of the type Item_equal.
5018
4948
    If the optional constant items are not equal the cond_false flag is
5019
 
    set to 1.  
 
4949
    set to 1.
5020
4950
  @param item    multiple equality whose members are to be joined
5021
4951
*/
5022
4952
 
5026
4956
  Item *c= item->const_item;
5027
4957
  if (c)
5028
4958
  {
5029
 
    /* 
5030
 
      The flag cond_false will be set to 1 after this, if 
5031
 
      the multiple equality already contains a constant and its 
 
4959
    /*
 
4960
      The flag cond_false will be set to 1 after this, if
 
4961
      the multiple equality already contains a constant and its
5032
4962
      value is  not equal to the value of c.
5033
4963
    */
5034
4964
    add(c);
5035
4965
  }
5036
4966
  cond_false|= item->cond_false;
5037
 
 
4967
}
5038
4968
 
5039
4969
 
5040
4970
/**
5110
5040
  }
5111
5041
}
5112
5042
 
5113
 
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
 
5043
bool Item_equal::fix_fields(Session *, Item **)
5114
5044
{
5115
5045
  List_iterator_fast<Item_field> li(fields);
5116
5046
  Item *item;
5174
5104
                                      item->collation.collation);
5175
5105
}
5176
5106
 
5177
 
bool Item_equal::walk(Item_processor processor, bool walk_subquery, uchar *arg)
 
5107
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
5178
5108
{
5179
5109
  List_iterator_fast<Item_field> it(fields);
5180
5110
  Item *item;
5186
5116
  return Item_func::walk(processor, walk_subquery, arg);
5187
5117
}
5188
5118
 
5189
 
Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
 
5119
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
5190
5120
{
5191
5121
  List_iterator<Item_field> it(fields);
5192
5122
  Item *item;
5197
5127
      return 0;
5198
5128
 
5199
5129
    /*
5200
 
      THD::change_item_tree() should be called only if the tree was
 
5130
      Session::change_item_tree() should be called only if the tree was
5201
5131
      really transformed, i.e. when a new item has been created.
5202
5132
      Otherwise we'll be allocating a lot of unnecessary memory for
5203
5133
      change records at each execution.
5204
5134
    */
5205
5135
    if (new_item != item)
5206
 
      current_thd->change_item_tree((Item **) it.ref(), new_item);
 
5136
      current_session->change_item_tree((Item **) it.ref(), new_item);
5207
5137
  }
5208
5138
  return Item_func::transform(transformer, arg);
5209
5139
}