~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

pandora-build v0.100 - Fixes several bugs found by cb1kenobi. Add several thoughts from folks at LCA.

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