~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

Removing global errbuff and cleaning up two remaining instances that referenced it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  This file defines all compare functions
22
22
*/
23
23
 
24
 
#include <drizzled/server_includes.h>
25
 
#include <drizzled/sql_select.h>
26
 
 
27
 
static bool convert_constant_item(THD *, Item_field *, Item **);
 
24
#include "drizzled/server_includes.h"
 
25
#include "drizzled/sql_select.h"
 
26
#include "drizzled/error.h"
 
27
#include "drizzled/temporal.h"
 
28
#include "drizzled/item/cmpfunc.h"
 
29
#include "drizzled/cached_item.h"
 
30
#include "drizzled/item/cache_int.h"
 
31
#include "drizzled/item/int_with_ref.h"
 
32
#include "drizzled/function/bit.h"
 
33
#include "drizzled/check_stack_overrun.h"
 
34
 
 
35
 
 
36
static Eq_creator eq_creator;
 
37
static Ne_creator ne_creator;
 
38
static Gt_creator gt_creator;
 
39
static Lt_creator lt_creator;
 
40
static Ge_creator ge_creator;
 
41
static Le_creator le_creator;
 
42
 
 
43
static bool convert_constant_item(Session *, Item_field *, Item **);
28
44
 
29
45
static Item_result item_store_type(Item_result a, Item *item,
30
46
                                   bool unsigned_flag)
79
95
  DESCRIPTION
80
96
    The function checks that two expressions have compatible row signatures
81
97
    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 
 
98
    are both row expressions then each component from the first expression has
83
99
    a row signature compatible with the signature of the corresponding component
84
100
    of the second expression.
85
101
 
140
156
      of the first row expression has a compatible row signature with
141
157
      the signature of the corresponding component of the second row
142
158
      expression.
143
 
    */ 
 
159
    */
144
160
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
145
161
      return 1;     // error found: invalid usage of rows
146
162
  }
203
219
  found_types= 0;
204
220
  for (i= 1; i < nitems ; i++)
205
221
  {
206
 
    if ((left_result == ROW_RESULT || 
 
222
    if ((left_result == ROW_RESULT ||
207
223
         items[i]->result_type() == ROW_RESULT) &&
208
224
        cmp_row_type(items[0], items[i]))
209
225
      return 0;
210
 
    found_types|= 1<< (uint)item_cmp_type(left_result,
 
226
    found_types|= 1<< (uint32_t)item_cmp_type(left_result,
211
227
                                           items[i]->result_type());
212
228
  }
213
229
  return found_types;
214
230
}
215
231
 
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
232
 
226
233
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
227
234
{
229
236
}
230
237
 
231
238
 
 
239
const Eq_creator* Eq_creator::instance()
 
240
{
 
241
  return &eq_creator;
 
242
}
 
243
 
 
244
 
232
245
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
233
246
{
234
247
  return new Item_func_ne(a, b);
235
248
}
236
249
 
237
250
 
 
251
const Ne_creator* Ne_creator::instance()
 
252
{
 
253
  return &ne_creator;
 
254
}
 
255
 
 
256
 
238
257
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
239
258
{
240
259
  return new Item_func_gt(a, b);
241
260
}
242
261
 
243
262
 
 
263
const Gt_creator* Gt_creator::instance()
 
264
{
 
265
  return &gt_creator;
 
266
}
 
267
 
 
268
 
244
269
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
245
270
{
246
271
  return new Item_func_lt(a, b);
247
272
}
248
273
 
249
274
 
 
275
const Lt_creator* Lt_creator::instance()
 
276
{
 
277
  return &lt_creator;
 
278
}
 
279
 
 
280
 
250
281
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
251
282
{
252
283
  return new Item_func_ge(a, b);
253
284
}
254
285
 
255
286
 
 
287
const Ge_creator* Ge_creator::instance()
 
288
{
 
289
  return &ge_creator;
 
290
}
 
291
 
 
292
 
256
293
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
257
294
{
258
295
  return new Item_func_le(a, b);
259
296
}
260
297
 
 
298
const Le_creator* Le_creator::instance()
 
299
{
 
300
  return &le_creator;
 
301
}
 
302
 
 
303
 
261
304
/*
262
305
  Test functions
263
306
  Most of these  returns 0LL if false and 1LL if true and
361
404
    also when comparing bigint to strings (in which case strings
362
405
    are converted to bigints).
363
406
 
364
 
  @param  thd             thread handle
 
407
  @param  session             thread handle
365
408
  @param  field_item      item will be converted using the type of this field
366
409
  @param[in,out] item     reference to the item to convert
367
410
 
378
421
    1  Item was replaced with an integer version of the item
379
422
*/
380
423
 
381
 
static bool convert_constant_item(THD *thd, Item_field *field_item,
 
424
static bool convert_constant_item(Session *session, Item_field *field_item,
382
425
                                  Item **item)
383
426
{
384
427
  Field *field= field_item->field;
386
429
 
387
430
  if (!(*item)->with_subselect && (*item)->const_item())
388
431
  {
389
 
    ulong orig_sql_mode= thd->variables.sql_mode;
390
 
    enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
 
432
    ulong orig_sql_mode= session->variables.sql_mode;
 
433
    enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
391
434
    uint64_t orig_field_val= 0; /* original field value if valid */
392
435
 
393
436
    /* For comparison purposes allow invalid dates like 2000-01-32 */
394
 
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
 
437
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
395
438
                             MODE_INVALID_DATES;
396
 
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
439
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
397
440
 
398
441
    /*
399
442
      Store the value of the field if it references an outer field because
406
449
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
407
450
                                       test(field->flags & UNSIGNED_FLAG));
408
451
      if (tmp)
409
 
        thd->change_item_tree(item, tmp);
 
452
        session->change_item_tree(item, tmp);
410
453
      result= 1;                                        // Item was replaced
411
454
    }
412
455
    /* Restore the original field value. */
416
459
      /* orig_field_val must be a valid value that can be restored back. */
417
460
      assert(!result);
418
461
    }
419
 
    thd->variables.sql_mode= orig_sql_mode;
420
 
    thd->count_cuted_fields= orig_count_cuted_fields;
 
462
    session->variables.sql_mode= orig_sql_mode;
 
463
    session->count_cuted_fields= orig_count_cuted_fields;
421
464
  }
422
465
  return result;
423
466
}
426
469
void Item_bool_func2::fix_length_and_dec()
427
470
{
428
471
  max_length= 1;                                     // Function returns 0 or 1
429
 
  THD *thd;
 
472
  Session *session;
430
473
 
431
474
  /*
432
475
    As some compare functions are generated after sql_yacc,
435
478
  if (!args[0] || !args[1])
436
479
    return;
437
480
 
438
 
  /* 
 
481
  /*
439
482
    We allow to convert to Unicode character sets in some cases.
440
483
    The conditions when conversion is possible are:
441
484
    - arguments A and B have different charsets
442
485
    - A wins according to coercibility rules
443
486
    - character set of A is superset for character set of B
444
 
   
 
487
 
445
488
    If all of the above is true, then it's possible to convert
446
489
    B into the character set of A, and then compare according
447
490
    to the collation of A.
448
491
  */
449
492
 
450
 
  
 
493
 
451
494
  DTCollation coll;
452
495
  if (args[0]->result_type() == STRING_RESULT &&
453
496
      args[1]->result_type() == STRING_RESULT &&
454
497
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
455
498
    return;
456
 
    
 
499
 
457
500
  args[0]->cmp_context= args[1]->cmp_context=
458
501
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
459
502
  // Make a special case of compare with fields to get nicer DATE comparisons
464
507
    return;
465
508
  }
466
509
 
467
 
  thd= current_thd;
 
510
  session= current_session;
 
511
  Item_field *field_item= NULL;
468
512
 
469
513
  if (args[0]->real_item()->type() == FIELD_ITEM)
470
514
  {
471
 
    Item_field *field_item= (Item_field*) (args[0]->real_item());
 
515
    field_item= static_cast<Item_field*>(args[0]->real_item());
472
516
    if (field_item->field->can_be_compared_as_int64_t() &&
473
517
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
474
518
    {
475
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
519
      if (convert_constant_item(session, field_item, &args[1]))
476
520
      {
477
521
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
478
522
                         INT_RESULT);           // Works for all types.
483
527
 
484
528
    if (args[1]->real_item()->type() == FIELD_ITEM)
485
529
    {
486
 
      Item_field *field_item= (Item_field*) (args[1]->real_item());
 
530
      field_item= static_cast<Item_field*>(args[1]->real_item());
487
531
      if (field_item->field->can_be_compared_as_int64_t() &&
488
532
          !(field_item->is_datetime() &&
489
533
            args[0]->result_type() == STRING_RESULT))
490
534
      {
491
 
        if (convert_constant_item(thd, field_item, &args[0]))
 
535
        if (convert_constant_item(session, field_item, &args[0]))
492
536
        {
493
537
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
494
538
                           INT_RESULT); // Works for all types.
536
580
      We must set cmp_charset here as we may be called from for an automatic
537
581
      generated item, like in natural join
538
582
    */
539
 
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
583
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
540
584
        cmp_collation.derivation == DERIVATION_NONE)
541
585
    {
542
586
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
608
652
/**
609
653
  @brief Convert date provided in a string to the int representation.
610
654
 
611
 
  @param[in]   thd        thread handle
 
655
  @param[in]   session        thread handle
612
656
  @param[in]   str        a string to convert
613
657
  @param[in]   warn_type  type of the timestamp for issuing the warning
614
658
  @param[in]   warn_name  field name for issuing the warning
628
672
*/
629
673
 
630
674
static uint64_t
631
 
get_date_from_str(THD *thd, String *str, enum enum_drizzle_timestamp_type warn_type,
 
675
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
632
676
                  char *warn_name, bool *error_arg)
633
677
{
634
678
  uint64_t value= 0;
638
682
 
639
683
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
640
684
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
641
 
                        (thd->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
685
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
642
686
                       &error);
643
687
 
644
688
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
657
701
  }
658
702
 
659
703
  if (error > 0)
660
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
704
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
661
705
                                 str->ptr(), str->length(),
662
706
                                 warn_type, warn_name);
663
707
 
682
726
         int result and the other item (b or a) is an item with string result.
683
727
         If the second item is a constant one then it's checked to be
684
728
         convertible to the DATE/DATETIME type. If the constant can't be
685
 
         converted to a DATE/DATETIME then the compare_datetime() comparator
686
 
         isn't used and the warning about wrong DATE/DATETIME value is issued.
 
729
         converted to a DATE/DATETIME then an error is issued back to the Session.
687
730
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
688
731
      the comparison is handled by other comparators.
 
732
 
689
733
    If the datetime comparator can be used and one the operands of the
690
734
    comparison is a string constant that was successfully converted to a
691
735
    DATE/DATETIME type then the result of the conversion is returned in the
734
778
        (str_arg->type() != Item::FUNC_ITEM ||
735
779
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
736
780
    {
737
 
      THD *thd= current_thd;
 
781
      /*
 
782
       * OK, we are here if we've got a date field (or something which can be 
 
783
       * compared as a date field) on one side of the equation, and a constant
 
784
       * string on the other side.  In this case, we must verify that the constant
 
785
       * string expression can indeed be evaluated as a datetime.  If it cannot, 
 
786
       * we throw an error here and stop processsing.  Bad data should ALWAYS 
 
787
       * produce an error, and no implicit conversion or truncation should take place.
 
788
       *
 
789
       * If the conversion to a DateTime temporal is successful, then we convert
 
790
       * the Temporal instance to a uint64_t for the comparison operator, which
 
791
       * compares date(times) using int64_t semantics.
 
792
       *
 
793
       * @TODO
 
794
       *
 
795
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
 
796
       * from val_int(), not uint64_t...
 
797
       */
738
798
      uint64_t value;
739
 
      bool error;
740
 
      String tmp, *str_val= 0;
741
 
      enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
742
 
                              DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
 
799
      String *str_val;
 
800
      String tmp;
 
801
      /* DateTime used to pick up as many string conversion possibilities as possible. */
 
802
      drizzled::DateTime temporal;
743
803
 
744
804
      str_val= str_arg->val_str(&tmp);
745
 
      if (str_arg->null_value)
746
 
        return CMP_DATE_DFLT;
747
 
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
748
 
      if (error)
749
 
        return CMP_DATE_DFLT;
 
805
      if (! str_val)
 
806
      {
 
807
        /* 
 
808
         * If we are here, it is most likely due to the comparison item
 
809
         * being a NULL.  Although this is incorrect (SQL demands that the term IS NULL
 
810
         * be used, not = NULL since no item can be equal to NULL).
 
811
         *
 
812
         * So, return gracefully.
 
813
         */
 
814
        return CMP_DATE_DFLT;
 
815
      }
 
816
      if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
 
817
      {
 
818
        /* Chuck an error. Bad datetime input. */
 
819
        my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
 
820
        return CMP_DATE_DFLT; /* :( What else can I return... */
 
821
      }
 
822
 
 
823
      /* String conversion was good.  Convert to an integer for comparison purposes. */
 
824
      int64_t int_value;
 
825
      temporal.to_int64_t(&int_value);
 
826
      value= (uint64_t) int_value;
 
827
 
750
828
      if (const_value)
751
829
        *const_value= value;
752
830
    }
760
838
 
761
839
  SYNOPSIS
762
840
    get_time_value()
763
 
    thd                 thread handle
 
841
    session                 thread handle
764
842
    item_arg   [in/out] item to retrieve TIME value from
765
843
    cache_arg  [in/out] pointer to place to store the cache item to
766
844
    warn_item  [in]     unused
781
859
*/
782
860
 
783
861
uint64_t
784
 
get_time_value(THD *thd __attribute__((unused)),
 
862
get_time_value(Session *,
785
863
               Item ***item_arg, Item **cache_arg,
786
 
               Item *warn_item __attribute__((unused)),
787
 
               bool *is_null)
 
864
               Item *, bool *is_null)
788
865
{
789
866
  uint64_t value;
790
867
  Item *item= **item_arg;
829
906
 
830
907
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
831
908
  {
832
 
    thd= current_thd;
 
909
    session= current_session;
833
910
    owner= owner_arg;
834
911
    a_type= (*a)->field_type();
835
912
    b_type= (*b)->field_type();
859
936
    get_value_func= &get_datetime_value;
860
937
    return 0;
861
938
  }
862
 
  else if (type == STRING_RESULT && (*a)->field_type() == DRIZZLE_TYPE_TIME &&
863
 
           (*b)->field_type() == DRIZZLE_TYPE_TIME)
864
 
  {
865
 
    /* Compare TIME values as integers. */
866
 
    thd= current_thd;
867
 
    owner= owner_arg;
868
 
    a_cache= 0;
869
 
    b_cache= 0;
870
 
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
871
 
    func= &Arg_comparator::compare_datetime;
872
 
    get_value_func= &get_time_value;
873
 
    return 0;
874
 
  }
875
939
 
876
940
  return set_compare_func(owner_arg, type);
877
941
}
879
943
 
880
944
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
881
945
{
882
 
  thd= current_thd;
 
946
  session= current_session;
883
947
  /* A caller will handle null values by itself. */
884
948
  owner= NULL;
885
949
  a= a1;
899
963
 
900
964
  SYNOPSIS
901
965
    get_datetime_value()
902
 
    thd                 thread handle
 
966
    session                 thread handle
903
967
    item_arg   [in/out] item to retrieve DATETIME value from
904
968
    cache_arg  [in/out] pointer to place to store the caching item to
905
969
    warn_item  [in]     item for issuing the conversion warning
924
988
*/
925
989
 
926
990
uint64_t
927
 
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
 
991
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
928
992
                   Item *warn_item, bool *is_null)
929
993
{
930
994
  uint64_t value= 0;
942
1006
      compare it with 100000000L - any DATE value should be less than it.
943
1007
      Don't shift cached DATETIME values up for the second time.
944
1008
    */
945
 
    if (f_type == DRIZZLE_TYPE_NEWDATE ||
 
1009
    if (f_type == DRIZZLE_TYPE_DATE ||
946
1010
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
947
1011
      value*= 1000000L;
948
1012
  }
964
1028
    bool error;
965
1029
    enum_field_types f_type= warn_item->field_type();
966
1030
    enum enum_drizzle_timestamp_type t_type= f_type ==
967
 
      DRIZZLE_TYPE_NEWDATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
968
 
    value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
 
1031
      DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
 
1032
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
969
1033
    /*
970
1034
      If str did not contain a valid date according to the current
971
1035
      SQL_MODE, get_date_from_str() has already thrown a warning,
1017
1081
  uint64_t a_value, b_value;
1018
1082
 
1019
1083
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1020
 
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
 
1084
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
1021
1085
  if (!is_nulls_eq && is_null)
1022
1086
  {
1023
1087
    if (owner)
1026
1090
  }
1027
1091
 
1028
1092
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1029
 
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
 
1093
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
1030
1094
  if (is_null)
1031
1095
  {
1032
1096
    if (owner)
1443
1507
}
1444
1508
 
1445
1509
 
1446
 
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
 
1510
bool Item_in_optimizer::fix_left(Session *session, Item **)
1447
1511
{
1448
 
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
 
1512
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
1449
1513
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1450
1514
    return 1;
1451
1515
 
1477
1541
}
1478
1542
 
1479
1543
 
1480
 
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
 
1544
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
1481
1545
{
1482
1546
  assert(fixed == 0);
1483
 
  if (fix_left(thd, ref))
 
1547
  if (fix_left(session, ref))
1484
1548
    return true;
1485
1549
  if (args[0]->maybe_null)
1486
1550
    maybe_null=1;
1487
1551
 
1488
 
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
 
1552
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
1489
1553
    return true;
1490
1554
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1491
1555
  if (args[0]->cols() != sub->engine->cols())
1509
1573
  bool tmp;
1510
1574
  assert(fixed == 1);
1511
1575
  cache->store(args[0]);
1512
 
  
 
1576
 
1513
1577
  if (cache->null_value)
1514
1578
  {
1515
1579
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1537
1601
          We disable the predicates we've pushed down into subselect, run the
1538
1602
          subselect and see if it has produced any rows.
1539
1603
        */
1540
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
 
1604
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
1541
1605
        if (cache->cols() == 1)
1542
1606
        {
1543
1607
          item_subs->set_cond_guard_var(0, false);
1558
1622
            if (cache->element_index(i)->null_value)
1559
1623
              item_subs->set_cond_guard_var(i, false);
1560
1624
          }
1561
 
          
 
1625
 
1562
1626
          (void) args[1]->val_bool_result();
1563
1627
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1564
 
          
 
1628
 
1565
1629
          /* Turn all predicates back on */
1566
1630
          for (i= 0; i < ncols; i++)
1567
1631
            item_subs->set_cond_guard_var(i, true);
1632
1696
  if (!new_item)
1633
1697
    return 0;
1634
1698
  /*
1635
 
    THD::change_item_tree() should be called only if the tree was
 
1699
    Session::change_item_tree() should be called only if the tree was
1636
1700
    really transformed, i.e. when a new item has been created.
1637
1701
    Otherwise we'll be allocating a lot of unnecessary memory for
1638
1702
    change records at each execution.
1639
1703
  */
1640
1704
  if ((*args) != new_item)
1641
 
    current_thd->change_item_tree(args, new_item);
 
1705
    current_session->change_item_tree(args, new_item);
1642
1706
 
1643
1707
  /*
1644
1708
    Transform the right IN operand which should be an Item_in_subselect or a
1763
1827
void Item_func_interval::fix_length_and_dec()
1764
1828
{
1765
1829
  uint32_t rows= row->cols();
1766
 
  
 
1830
 
1767
1831
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1768
1832
                            DECIMAL_RESULT) ||
1769
1833
                           (row->element_index(0)->result_type() ==
1904
1968
      if (my_decimal_cmp(e_dec, dec) > 0)
1905
1969
        return i - 1;
1906
1970
    }
1907
 
    else 
 
1971
    else
1908
1972
    {
1909
1973
      double val= el->val_real();
1910
1974
      /* Skip NULL ranges. */
1926
1990
    The function saves in ref the pointer to the item or to a newly created
1927
1991
    item that is considered as a replacement for the original one.
1928
1992
 
1929
 
  @param thd     reference to the global context of the query thread
 
1993
  @param session     reference to the global context of the query thread
1930
1994
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1931
1995
                 item is to be assigned
1932
1996
 
1946
2010
    1   got error
1947
2011
*/
1948
2012
 
1949
 
bool Item_func_between::fix_fields(THD *thd, Item **ref)
 
2013
bool Item_func_between::fix_fields(Session *session, Item **ref)
1950
2014
{
1951
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
2015
  if (Item_func_opt_neg::fix_fields(session, ref))
1952
2016
    return 1;
1953
2017
 
1954
 
  thd->lex->current_select->between_count++;
 
2018
  session->lex->current_select->between_count++;
1955
2019
 
1956
2020
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1957
2021
  if (pred_level && !negated)
1971
2035
  max_length= 1;
1972
2036
  int i;
1973
2037
  bool datetime_found= false;
1974
 
  int time_items_found= 0;
1975
2038
  compare_as_dates= true;
1976
 
  THD *thd= current_thd;
 
2039
  Session *session= current_session;
1977
2040
 
1978
2041
  /*
1979
2042
    As some compare functions are generated after sql_yacc,
2001
2064
        datetime_found= true;
2002
2065
        continue;
2003
2066
      }
2004
 
      if (args[i]->field_type() == DRIZZLE_TYPE_TIME &&
2005
 
          args[i]->result_as_int64_t())
2006
 
        time_items_found++;
2007
2067
    }
2008
2068
  }
2009
2069
  if (!datetime_found)
2014
2074
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2015
2075
    le_cmp.set_datetime_cmp_func(args, args + 2);
2016
2076
  }
2017
 
  else if (time_items_found == 3)
2018
 
  {
2019
 
    /* Compare TIME items as integers. */
2020
 
    cmp_type= INT_RESULT;
2021
 
  }
2022
2077
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
2023
 
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
 
2078
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2024
2079
  {
2025
2080
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2026
2081
    if (field_item->field->can_be_compared_as_int64_t())
2029
2084
        The following can't be recoded with || as convert_constant_item
2030
2085
        changes the argument
2031
2086
      */
2032
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
2087
      if (convert_constant_item(session, field_item, &args[1]))
2033
2088
        cmp_type=INT_RESULT;                    // Works for all types.
2034
 
      if (convert_constant_item(thd, field_item, &args[2]))
 
2089
      if (convert_constant_item(session, field_item, &args[2]))
2035
2090
        cmp_type=INT_RESULT;                    // Works for all types.
2036
2091
    }
2037
2092
  }
2169
2224
  decimals= cmax(args[0]->decimals, args[1]->decimals);
2170
2225
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2171
2226
 
2172
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
 
2227
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2173
2228
  {
2174
2229
    int len0= args[0]->max_length - args[0]->decimals
2175
2230
      - (args[0]->unsigned_flag ? 0 : 1);
2207
2262
}
2208
2263
 
2209
2264
 
2210
 
enum_field_types Item_func_ifnull::field_type() const 
 
2265
enum_field_types Item_func_ifnull::field_type() const
2211
2266
{
2212
2267
  return cached_field_type;
2213
2268
}
2293
2348
    The function saves in ref the pointer to the item or to a newly created
2294
2349
    item that is considered as a replacement for the original one.
2295
2350
 
2296
 
  @param thd     reference to the global context of the query thread
 
2351
  @param session     reference to the global context of the query thread
2297
2352
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2298
2353
                 item is to be assigned
2299
2354
 
2312
2367
*/
2313
2368
 
2314
2369
bool
2315
 
Item_func_if::fix_fields(THD *thd, Item **ref)
 
2370
Item_func_if::fix_fields(Session *session, Item **ref)
2316
2371
{
2317
2372
  assert(fixed == 0);
2318
2373
  args[0]->top_level_item();
2319
2374
 
2320
 
  if (Item_func::fix_fields(thd, ref))
 
2375
  if (Item_func::fix_fields(session, ref))
2321
2376
    return 1;
2322
2377
 
2323
2378
  not_null_tables_cache= (args[1]->not_null_tables() &
2527
2582
bool
2528
2583
Item_func_nullif::is_null()
2529
2584
{
2530
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
 
2585
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
2531
2586
}
2532
2587
 
2533
2588
 
2552
2607
           failed
2553
2608
*/
2554
2609
 
2555
 
Item *Item_func_case::find_item(String *str __attribute__((unused)))
 
2610
Item *Item_func_case::find_item(String *)
2556
2611
{
2557
2612
  uint32_t value_added_map= 0;
2558
2613
 
2573
2628
    {
2574
2629
      cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2575
2630
      assert(cmp_type != ROW_RESULT);
2576
 
      assert(cmp_items[(uint)cmp_type]);
2577
 
      if (!(value_added_map & (1<<(uint)cmp_type)))
 
2631
      assert(cmp_items[(uint32_t)cmp_type]);
 
2632
      if (!(value_added_map & (1<<(uint32_t)cmp_type)))
2578
2633
      {
2579
 
        cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
 
2634
        cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
2580
2635
        if ((null_value=args[first_expr_num]->null_value))
2581
2636
          return else_expr_num != -1 ? args[else_expr_num] : 0;
2582
 
        value_added_map|= 1<<(uint)cmp_type;
 
2637
        value_added_map|= 1<<(uint32_t)cmp_type;
2583
2638
      }
2584
 
      if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
 
2639
      if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2585
2640
        return args[i + 1];
2586
2641
    }
2587
2642
  }
2665
2720
}
2666
2721
 
2667
2722
 
2668
 
bool Item_func_case::fix_fields(THD *thd, Item **ref)
 
2723
bool Item_func_case::fix_fields(Session *session, Item **ref)
2669
2724
{
2670
2725
  /*
2671
2726
    buff should match stack usage from
2672
2727
    Item_func_case::val_int() -> Item_func_case::find_item()
2673
2728
  */
2674
 
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(int64_t)*2];
2675
 
  bool res= Item_func::fix_fields(thd, ref);
 
2729
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
 
2730
                     +sizeof(double)*2+sizeof(int64_t)*2];
 
2731
  bool res= Item_func::fix_fields(session, ref);
2676
2732
  /*
2677
2733
    Call check_stack_overrun after fix_fields to be sure that stack variable
2678
2734
    is not optimized away
2679
2735
  */
2680
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
2736
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2681
2737
    return true;                                // Fatal error flag is set!
2682
2738
  return res;
2683
2739
}
2695
2751
{
2696
2752
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2697
2753
                                           arg->unsigned_flag) - arg->decimals;
2698
 
  set_if_bigger(max_length, len); 
 
2754
  set_if_bigger(max_length, len);
2699
2755
  set_if_bigger(decimals, arg->decimals);
2700
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
 
2756
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
2701
2757
}
2702
2758
 
2703
2759
 
2708
2764
  uint32_t found_types= 0;
2709
2765
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2710
2766
    return;
2711
 
  
 
2767
 
2712
2768
  /*
2713
2769
    Aggregate all THEN and ELSE expression types
2714
2770
    and collations when string result
2715
2771
  */
2716
 
  
 
2772
 
2717
2773
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2718
2774
    agg[nagg]= args[nagg*2+1];
2719
 
  
 
2775
 
2720
2776
  if (else_expr_num != -1)
2721
2777
    agg[nagg++]= args[else_expr_num];
2722
 
  
 
2778
 
2723
2779
  agg_result_type(&cached_result_type, agg, nagg);
2724
2780
  if ((cached_result_type == STRING_RESULT) &&
2725
2781
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2726
2782
    return;
2727
 
  
 
2783
 
2728
2784
  cached_field_type= agg_field_type(agg, nagg);
2729
2785
  /*
2730
2786
    Aggregate first expression and all THEN expression types
2742
2798
    if (!(found_types= collect_cmp_types(agg, nagg)))
2743
2799
      return;
2744
2800
 
2745
 
    for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
 
2801
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2746
2802
    {
2747
2803
      if (found_types & (1 << i) && !cmp_items[i])
2748
2804
      {
2760
2816
 
2761
2817
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2762
2818
    maybe_null=1;
2763
 
  
 
2819
 
2764
2820
  max_length=0;
2765
2821
  decimals=0;
2766
2822
  unsigned_flag= true;
2775
2831
  {
2776
2832
    for (uint32_t i= 0; i < ncases; i+= 2)
2777
2833
      agg_num_lengths(args[i + 1]);
2778
 
    if (else_expr_num != -1) 
 
2834
    if (else_expr_num != -1)
2779
2835
      agg_num_lengths(args[else_expr_num]);
2780
2836
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2781
2837
                                               unsigned_flag);
2789
2845
  for (uint32_t i=0 ; i < ncases ; i+=2)
2790
2846
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2791
2847
 
2792
 
  if (else_expr_num != -1) 
 
2848
  if (else_expr_num != -1)
2793
2849
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2794
2850
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2795
2851
}
2830
2886
{
2831
2887
  uint32_t i;
2832
2888
  Item_func::cleanup();
2833
 
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
 
2889
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2834
2890
  {
2835
2891
    delete cmp_items[i];
2836
2892
    cmp_items[i]= 0;
2980
3036
 
2981
3037
 
2982
3038
/*
2983
 
  Compare two integers in IN value list format (packed_int64_t) 
 
3039
  Compare two integers in IN value list format (packed_int64_t)
2984
3040
 
2985
3041
  SYNOPSIS
2986
3042
    cmp_int64_t()
3002
3058
    0           left argument is equal to the right argument.
3003
3059
    1           left argument is greater than the right argument.
3004
3060
*/
3005
 
int cmp_int64_t(void *cmp_arg __attribute__((unused)),
3006
 
                 in_int64_t::packed_int64_t *a,
3007
 
                 in_int64_t::packed_int64_t *b)
 
3061
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
 
3062
                in_int64_t::packed_int64_t *b)
3008
3063
{
3009
3064
  if (a->unsigned_flag != b->unsigned_flag)
3010
 
  { 
3011
 
    /* 
3012
 
      One of the args is unsigned and is too big to fit into the 
 
3065
  {
 
3066
    /*
 
3067
      One of the args is unsigned and is too big to fit into the
3013
3068
      positive signed range. Report no match.
3014
 
    */  
 
3069
    */
3015
3070
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3016
3071
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3017
3072
      return a->unsigned_flag ? 1 : -1;
3018
3073
    /*
3019
 
      Although the signedness differs both args can fit into the signed 
 
3074
      Although the signedness differs both args can fit into the signed
3020
3075
      positive range. Make them signed and compare as usual.
3021
 
    */  
 
3076
    */
3022
3077
    return cmp_longs (a->val, b->val);
3023
3078
  }
3024
3079
  if (a->unsigned_flag)
3027
3082
    return cmp_longs (a->val, b->val);
3028
3083
}
3029
3084
 
3030
 
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
 
3085
static int cmp_double(void *, double *a, double *b)
3031
3086
{
3032
3087
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3033
3088
}
3034
3089
 
3035
 
static int cmp_row(void *cmp_arg __attribute__((unused)), cmp_item_row *a, cmp_item_row *b)
 
3090
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
3036
3091
{
3037
3092
  return a->compare(b);
3038
3093
}
3039
3094
 
3040
3095
 
3041
 
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
 
3096
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
3042
3097
{
3043
3098
  /*
3044
3099
    We need call of fixing buffer pointer, because fast sort just copy
3115
3170
  return (unsigned char*) item->val_str(&tmp);
3116
3171
}
3117
3172
 
3118
 
in_row::in_row(uint32_t elements, Item * item __attribute__((unused)))
 
3173
in_row::in_row(uint32_t elements, Item *)
3119
3174
{
3120
3175
  base= (char*) new cmp_item_row[count= elements];
3121
3176
  size= sizeof(cmp_item_row);
3155
3210
void in_int64_t::set(uint32_t pos,Item *item)
3156
3211
{
3157
3212
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3158
 
  
 
3213
 
3159
3214
  buff->val= item->val_int();
3160
3215
  buff->unsigned_flag= item->unsigned_flag;
3161
3216
}
3175
3230
  bool is_null;
3176
3231
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3177
3232
 
3178
 
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3233
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3179
3234
  buff->unsigned_flag= 1L;
3180
3235
}
3181
3236
 
3183
3238
{
3184
3239
  bool is_null;
3185
3240
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3186
 
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3241
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3187
3242
  if (item->null_value)
3188
3243
    return 0;
3189
3244
  tmp.unsigned_flag= 1L;
3220
3275
  dec->len= DECIMAL_BUFF_LENGTH;
3221
3276
  dec->fix_buffer_pointer();
3222
3277
  my_decimal *res= item->val_decimal(dec);
3223
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
 
3278
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
3224
3279
  if (!item->null_value && res != dec)
3225
3280
    my_decimal2decimal(res, dec);
3226
3281
}
3295
3350
void cmp_item_row::alloc_comparators()
3296
3351
{
3297
3352
  if (!comparators)
3298
 
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
 
3353
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
3299
3354
}
3300
3355
 
3301
3356
 
3418
3473
{
3419
3474
  bool is_null;
3420
3475
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3421
 
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3476
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3422
3477
}
3423
3478
 
3424
3479
 
3427
3482
  bool is_null;
3428
3483
  Item **tmp_item= &arg;
3429
3484
  return value !=
3430
 
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3485
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3431
3486
}
3432
3487
 
3433
3488
 
3464
3519
    The function saves in ref the pointer to the item or to a newly created
3465
3520
    item that is considered as a replacement for the original one.
3466
3521
 
3467
 
  @param thd     reference to the global context of the query thread
 
3522
  @param session     reference to the global context of the query thread
3468
3523
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3469
3524
                 item is to be assigned
3470
3525
 
3485
3540
*/
3486
3541
 
3487
3542
bool
3488
 
Item_func_in::fix_fields(THD *thd, Item **ref)
 
3543
Item_func_in::fix_fields(Session *session, Item **ref)
3489
3544
{
3490
3545
  Item **arg, **arg_end;
3491
3546
 
3492
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
3547
  if (Item_func_opt_neg::fix_fields(session, ref))
3493
3548
    return 1;
3494
3549
 
3495
3550
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3517
3572
{
3518
3573
  Item **arg, **arg_end;
3519
3574
  bool const_itm= 1;
3520
 
  THD *thd= current_thd;
 
3575
  Session *session= current_session;
3521
3576
  bool datetime_found= false;
3522
3577
  /* true <=> arguments values will be compared as DATETIMEs. */
3523
3578
  bool compare_as_datetime= false;
3528
3583
  left_result_type= args[0]->result_type();
3529
3584
  if (!(found_types= collect_cmp_types(args, arg_count)))
3530
3585
    return;
3531
 
  
 
3586
 
3532
3587
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3533
3588
  {
3534
3589
    if (!arg[0]->const_item())
3537
3592
      break;
3538
3593
    }
3539
3594
  }
3540
 
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
 
3595
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
3541
3596
  {
3542
3597
    if (found_types & 1 << i)
3543
3598
    {
3548
3603
 
3549
3604
  if (type_cnt == 1)
3550
3605
  {
3551
 
    if (cmp_type == STRING_RESULT && 
 
3606
    if (cmp_type == STRING_RESULT &&
3552
3607
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3553
3608
      return;
3554
3609
    arg_types_compatible= true;
3579
3634
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3580
3635
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3581
3636
    {
3582
 
      uint32_t col, cols= args[0]->cols();
 
3637
      uint32_t col, num_cols= args[0]->cols();
3583
3638
 
3584
 
      for (col= 0; col < cols; col++)
 
3639
      for (col= 0; col < num_cols; col++)
3585
3640
      {
3586
3641
        bool skip_column= false;
3587
3642
        /*
3650
3705
      /*
3651
3706
        IN must compare INT columns and constants as int values (the same
3652
3707
        way as equality does).
3653
 
        So we must check here if the column on the left and all the constant 
3654
 
        values on the right can be compared as integers and adjust the 
 
3708
        So we must check here if the column on the left and all the constant
 
3709
        values on the right can be compared as integers and adjust the
3655
3710
        comparison type accordingly.
3656
 
      */  
 
3711
      */
3657
3712
      if (args[0]->real_item()->type() == FIELD_ITEM &&
3658
 
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
 
3713
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3659
3714
          cmp_type != INT_RESULT)
3660
3715
      {
3661
3716
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3664
3719
          bool all_converted= true;
3665
3720
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3666
3721
          {
3667
 
            if (!convert_constant_item (thd, field_item, &arg[0]))
 
3722
            if (!convert_constant_item (session, field_item, &arg[0]))
3668
3723
              all_converted= false;
3669
3724
          }
3670
3725
          if (all_converted)
3673
3728
      }
3674
3729
      switch (cmp_type) {
3675
3730
      case STRING_RESULT:
3676
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
 
3731
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3677
3732
                            cmp_collation.collation);
3678
3733
        break;
3679
3734
      case INT_RESULT:
3698
3753
        return;
3699
3754
      }
3700
3755
    }
3701
 
    if (array && !(thd->is_fatal_error))                // If not EOM
 
3756
    if (array && !(session->is_fatal_error))            // If not EOM
3702
3757
    {
3703
3758
      uint32_t j=0;
3704
 
      for (uint32_t i=1 ; i < arg_count ; i++)
 
3759
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3705
3760
      {
3706
 
        array->set(j,args[i]);
3707
 
        if (!args[i]->null_value)                       // Skip NULL values
 
3761
        array->set(j,args[arg_num]);
 
3762
        if (!args[arg_num]->null_value)                 // Skip NULL values
3708
3763
          j++;
3709
3764
        else
3710
3765
          have_null= 1;
3719
3774
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3720
3775
    else
3721
3776
    {
3722
 
      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
 
3777
      for (i= 0; i <= (uint32_t) DECIMAL_RESULT; i++)
3723
3778
      {
3724
3779
        if (found_types & (1 << i) && !cmp_items[i])
3725
3780
        {
3791
3846
  for (uint32_t i= 1 ; i < arg_count ; i++)
3792
3847
  {
3793
3848
    Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3794
 
    in_item= cmp_items[(uint)cmp_type];
 
3849
    in_item= cmp_items[(uint32_t)cmp_type];
3795
3850
    assert(in_item);
3796
 
    if (!(value_added_map & (1 << (uint)cmp_type)))
 
3851
    if (!(value_added_map & (1 << (uint32_t)cmp_type)))
3797
3852
    {
3798
3853
      in_item->store_value(args[0]);
3799
3854
      if ((null_value=args[0]->null_value))
3800
3855
        return 0;
3801
3856
      have_null= 0;
3802
 
      value_added_map|= 1 << (uint)cmp_type;
 
3857
      value_added_map|= 1 << (uint32_t)cmp_type;
3803
3858
    }
3804
3859
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
3805
3860
      return (int64_t) (!negated);
3850
3905
  return (int64_t) (arg1 & arg2);
3851
3906
}
3852
3907
 
3853
 
Item_cond::Item_cond(THD *thd, Item_cond *item)
3854
 
  :Item_bool_func(thd, item),
 
3908
Item_cond::Item_cond(Session *session, Item_cond *item)
 
3909
  :Item_bool_func(session, item),
3855
3910
   abort_on_null(item->abort_on_null),
3856
3911
   and_tables_cache(item->and_tables_cache)
3857
3912
{
3861
3916
}
3862
3917
 
3863
3918
 
3864
 
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
 
3919
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3865
3920
{
3866
3921
  List_iterator_fast<Item> li(item->list);
3867
3922
  while (Item *it= li++)
3868
 
    list.push_back(it->copy_andor_structure(thd));
 
3923
    list.push_back(it->copy_andor_structure(session));
3869
3924
}
3870
3925
 
3871
3926
 
3872
3927
bool
3873
 
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
 
3928
Item_cond::fix_fields(Session *session, Item **)
3874
3929
{
3875
3930
  assert(fixed == 0);
3876
3931
  List_iterator<Item> li(list);
3877
3932
  Item *item;
3878
 
  void *orig_thd_marker= thd->thd_marker;
 
3933
  void *orig_session_marker= session->session_marker;
3879
3934
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3880
3935
  not_null_tables_cache= used_tables_cache= 0;
3881
3936
  const_item_cache= 1;
3882
3937
 
3883
3938
  if (functype() == COND_OR_FUNC)
3884
 
    thd->thd_marker= 0;
 
3939
    session->session_marker= 0;
3885
3940
  /*
3886
3941
    and_table_cache is the value that Item_cond_or() returns for
3887
3942
    not_null_tables()
3888
3943
  */
3889
3944
  and_tables_cache= ~(table_map) 0;
3890
3945
 
3891
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
3946
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3892
3947
    return true;                                // Fatal error flag is set!
3893
3948
  /*
3894
3949
    The following optimization reduces the depth of an AND-OR tree.
3921
3976
 
3922
3977
    // item can be substituted in fix_fields
3923
3978
    if ((!item->fixed &&
3924
 
         item->fix_fields(thd, li.ref())) ||
 
3979
         item->fix_fields(session, li.ref())) ||
3925
3980
        (item= *li.ref())->check_cols(1))
3926
3981
      return true; /* purecov: inspected */
3927
3982
    used_tables_cache|=     item->used_tables();
3933
3988
      not_null_tables_cache|= tmp_table_map;
3934
3989
      and_tables_cache&= tmp_table_map;
3935
3990
      const_item_cache= false;
3936
 
    }  
 
3991
    }
3937
3992
    with_sum_func=          with_sum_func || item->with_sum_func;
3938
3993
    with_subselect|=        item->with_subselect;
3939
3994
    if (item->maybe_null)
3940
3995
      maybe_null=1;
3941
3996
  }
3942
 
  thd->lex->current_select->cond_count+= list.elements;
3943
 
  thd->thd_marker= orig_thd_marker;
 
3997
  session->lex->current_select->cond_count+= list.elements;
 
3998
  session->session_marker= orig_session_marker;
3944
3999
  fix_length_and_dec();
3945
4000
  fixed= 1;
3946
4001
  return false;
3947
4002
}
3948
4003
 
3949
4004
 
3950
 
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
 
4005
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3951
4006
{
3952
4007
  List_iterator<Item> li(list);
3953
4008
  Item *item;
3974
4029
      not_null_tables_cache|= tmp_table_map;
3975
4030
      and_tables_cache&= tmp_table_map;
3976
4031
      const_item_cache= false;
3977
 
    }  
 
4032
    }
3978
4033
  }
3979
4034
}
3980
4035
 
3992
4047
 
3993
4048
/**
3994
4049
  Transform an Item_cond object with a transformer callback function.
3995
 
  
 
4050
 
3996
4051
    The function recursively applies the transform method to each
3997
4052
     member item of the condition list.
3998
4053
    If the call of the method for a member item returns a new item
3999
4054
    the old item is substituted for a new one.
4000
4055
    After this the transformer is applied to the root node
4001
 
    of the Item_cond object. 
4002
 
     
 
4056
    of the Item_cond object.
 
4057
 
4003
4058
  @param transformer   the transformer callback function to be applied to
4004
4059
                       the nodes of the tree of the object
4005
4060
  @param arg           parameter to be passed to the transformer
4006
4061
 
4007
4062
  @return
4008
 
    Item returned as the result of transformation of the root node 
 
4063
    Item returned as the result of transformation of the root node
4009
4064
*/
4010
4065
 
4011
4066
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4019
4074
      return 0;
4020
4075
 
4021
4076
    /*
4022
 
      THD::change_item_tree() should be called only if the tree was
 
4077
      Session::change_item_tree() should be called only if the tree was
4023
4078
      really transformed, i.e. when a new item has been created.
4024
4079
      Otherwise we'll be allocating a lot of unnecessary memory for
4025
4080
      change records at each execution.
4026
4081
    */
4027
4082
    if (new_item != item)
4028
 
      current_thd->change_item_tree(li.ref(), new_item);
 
4083
      current_session->change_item_tree(li.ref(), new_item);
4029
4084
  }
4030
4085
  return Item_func::transform(transformer, arg);
4031
4086
}
4034
4089
/**
4035
4090
  Compile Item_cond object with a processor and a transformer
4036
4091
  callback functions.
4037
 
  
 
4092
 
4038
4093
    First the function applies the analyzer to the root node of
4039
4094
    the Item_func object. Then if the analyzer succeeeds (returns true)
4040
4095
    the function recursively applies the compile method to member
4042
4097
    If the call of the method for a member item returns a new item
4043
4098
    the old item is substituted for a new one.
4044
4099
    After this the transformer is applied to the root node
4045
 
    of the Item_cond object. 
4046
 
     
 
4100
    of the Item_cond object.
 
4101
 
4047
4102
  @param analyzer      the analyzer callback function to be applied to the
4048
4103
                       nodes of the tree of the object
4049
4104
  @param[in,out] arg_p parameter to be passed to the analyzer
4052
4107
  @param arg_t         parameter to be passed to the transformer
4053
4108
 
4054
4109
  @return
4055
 
    Item returned as the result of transformation of the root node 
 
4110
    Item returned as the result of transformation of the root node
4056
4111
*/
4057
4112
 
4058
4113
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4060
4115
{
4061
4116
  if (!(this->*analyzer)(arg_p))
4062
4117
    return 0;
4063
 
  
 
4118
 
4064
4119
  List_iterator<Item> li(list);
4065
4120
  Item *item;
4066
4121
  while ((item= li++))
4067
4122
  {
4068
 
    /* 
 
4123
    /*
4069
4124
      The same parameter value of arg_p must be passed
4070
4125
      to analyze any argument of the condition formula.
4071
 
    */   
 
4126
    */
4072
4127
    unsigned char *arg_v= *arg_p;
4073
4128
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4074
4129
    if (new_item && new_item != item)
4083
4138
  List_iterator<Item> li(list);
4084
4139
  Item *item;
4085
4140
 
4086
 
  switch(order) {
4087
 
  case(PREFIX):
 
4141
  switch (order) {
 
4142
  case (T_PREFIX):
4088
4143
    (*traverser)(this, arg);
4089
4144
    while ((item= li++))
4090
4145
    {
4092
4147
    }
4093
4148
    (*traverser)(NULL, arg);
4094
4149
    break;
4095
 
  case(POSTFIX):
 
4150
  case (T_POSTFIX):
4096
4151
    while ((item= li++))
4097
4152
    {
4098
4153
      item->traverse_cond(traverser, arg, order);
4109
4164
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4110
4165
  sql_select.cc)
4111
4166
 
4112
 
  @param thd                    Thread handler
 
4167
  @param session                        Thread handler
4113
4168
  @param ref_pointer_array      Pointer to array of reference fields
4114
4169
  @param fields         All fields in select
4115
4170
 
4118
4173
    that have or refer (HAVING) to a SUM expression.
4119
4174
*/
4120
4175
 
4121
 
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
 
4176
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4122
4177
                               List<Item> &fields)
4123
4178
{
4124
4179
  List_iterator<Item> li(list);
4125
4180
  Item *item;
4126
4181
  while ((item= li++))
4127
 
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
 
4182
    item->split_sum_func(session, ref_pointer_array,
 
4183
                         fields, li.ref(), true);
4128
4184
}
4129
4185
 
4130
4186
 
4169
4225
}
4170
4226
 
4171
4227
 
4172
 
void Item_cond::neg_arguments(THD *thd)
 
4228
void Item_cond::neg_arguments(Session *session)
4173
4229
{
4174
4230
  List_iterator<Item> li(list);
4175
4231
  Item *item;
4176
4232
  while ((item= li++))          /* Apply not transformation to the arguments */
4177
4233
  {
4178
 
    Item *new_item= item->neg_transformer(thd);
 
4234
    Item *new_item= item->neg_transformer(session);
4179
4235
    if (!new_item)
4180
4236
    {
4181
4237
      if (!(new_item= new Item_func_not(item)))
4399
4455
}
4400
4456
 
4401
4457
 
4402
 
bool Item_func_like::fix_fields(THD *thd, Item **ref)
 
4458
bool Item_func_like::fix_fields(Session *session, Item **ref)
4403
4459
{
4404
4460
  assert(fixed == 0);
4405
 
  if (Item_bool_func2::fix_fields(thd, ref) ||
4406
 
      escape_item->fix_fields(thd, &escape_item))
 
4461
  if (Item_bool_func2::fix_fields(session, ref) ||
 
4462
      escape_item->fix_fields(session, &escape_item))
4407
4463
    return true;
4408
4464
 
4409
4465
  if (!escape_item->const_during_execution())
4411
4467
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4412
4468
    return true;
4413
4469
  }
4414
 
  
 
4470
 
4415
4471
  if (escape_item->const_item())
4416
4472
  {
4417
4473
    /* If we are on execution stage */
4464
4520
      We could also do boyer-more for non-const items, but as we would have to
4465
4521
      recompute the tables for each row it's not worth it.
4466
4522
    */
4467
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation)) 
 
4523
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4468
4524
    {
4469
4525
      String* res2 = args[1]->val_str(&tmp_value2);
4470
4526
      if (!res2)
4471
4527
        return false;                           // Null argument
4472
 
      
 
4528
 
4473
4529
      const size_t len   = res2->length();
4474
4530
      const char*  first = res2->ptr();
4475
4531
      const char*  last  = first + len - 1;
4477
4533
        len must be > 2 ('%pattern%')
4478
4534
        heuristic: only do TurboBM for pattern_len > 2
4479
4535
      */
4480
 
      
 
4536
 
4481
4537
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4482
4538
          *first == wild_many &&
4483
4539
          *last  == wild_many)
4490
4546
      {
4491
4547
        pattern     = first + 1;
4492
4548
        pattern_len = (int) len - 2;
4493
 
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
 
4549
        int *suff = (int*) session->alloc((int) (sizeof(int)*
4494
4550
                                      ((pattern_len + 1)*2+
4495
4551
                                      alphabet_size)));
4496
4552
        bmGs      = suff + pattern_len + 1;
4634
4690
  if (!cs->sort_order)
4635
4691
  {
4636
4692
    for (j = 0; j < plm1; j++)
4637
 
      bmBc[(uint) (unsigned char) pattern[j]] = plm1 - j;
 
4693
      bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
4638
4694
  }
4639
4695
  else
4640
4696
  {
4641
4697
    for (j = 0; j < plm1; j++)
4642
 
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
 
4698
      bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
4643
4699
  }
4644
4700
}
4645
4701
 
4680
4736
 
4681
4737
      register const int v = plm1 - i;
4682
4738
      turboShift = u - v;
4683
 
      bcShift    = bmBc[(uint) (unsigned char) text[i + j]] - plm1 + i;
 
4739
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
4684
4740
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4685
4741
      shift      = (shift > bmGs[i]) ? shift : bmGs[i];
4686
4742
      if (shift == bmGs[i])
4711
4767
 
4712
4768
      register const int v = plm1 - i;
4713
4769
      turboShift = u - v;
4714
 
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
 
4770
      bcShift    = bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4715
4771
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4716
4772
      shift      = cmax(shift, bmGs[i]);
4717
4773
      if (shift == bmGs[i])
4750
4806
  assert(fixed == 1);
4751
4807
  List_iterator<Item> li(list);
4752
4808
  Item *item;
4753
 
  int result=0; 
 
4809
  int result=0;
4754
4810
  null_value=0;
4755
4811
  while ((item=li++))
4756
4812
  {
4783
4839
       IS NOT NULL(a)     -> IS NULL(a)
4784
4840
    @endverbatim
4785
4841
 
4786
 
  @param thd            thread handler
 
4842
  @param session                thread handler
4787
4843
 
4788
4844
  @return
4789
4845
    New item or
4790
4846
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4791
4847
*/
4792
4848
 
4793
 
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
 
4849
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
4794
4850
{
4795
4851
  return args[0];
4796
4852
}
4797
4853
 
4798
4854
 
4799
 
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
 
4855
Item *Item_bool_rowready_func2::neg_transformer(Session *)
4800
4856
{
4801
4857
  Item *item= negated_item();
4802
4858
  return item;
4806
4862
/**
4807
4863
  a IS NULL  ->  a IS NOT NULL.
4808
4864
*/
4809
 
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
 
4865
Item *Item_func_isnull::neg_transformer(Session *)
4810
4866
{
4811
4867
  Item *item= new Item_func_isnotnull(args[0]);
4812
4868
  return item;
4816
4872
/**
4817
4873
  a IS NOT NULL  ->  a IS NULL.
4818
4874
*/
4819
 
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
 
4875
Item *Item_func_isnotnull::neg_transformer(Session *)
4820
4876
{
4821
4877
  Item *item= new Item_func_isnull(args[0]);
4822
4878
  return item;
4823
4879
}
4824
4880
 
4825
4881
 
4826
 
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
 
4882
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
4827
4883
                                        /* NOT a OR NOT b OR ... */
4828
4884
{
4829
 
  neg_arguments(thd);
 
4885
  neg_arguments(session);
4830
4886
  Item *item= new Item_cond_or(list);
4831
4887
  return item;
4832
4888
}
4833
4889
 
4834
4890
 
4835
 
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
 
4891
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
4836
4892
                                        /* NOT a AND NOT b AND ... */
4837
4893
{
4838
 
  neg_arguments(thd);
 
4894
  neg_arguments(session);
4839
4895
  Item *item= new Item_cond_and(list);
4840
4896
  return item;
4841
4897
}
4842
4898
 
4843
4899
 
4844
 
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
 
4900
Item *Item_func_nop_all::neg_transformer(Session *)
4845
4901
{
4846
4902
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4847
4903
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4852
4908
  return new_item;
4853
4909
}
4854
4910
 
4855
 
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
 
4911
Item *Item_func_not_all::neg_transformer(Session *)
4856
4912
{
4857
4913
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4858
4914
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4975
5031
  @retval
4976
5032
    1       if nultiple equality contains a reference to field
4977
5033
  @retval
4978
 
    0       otherwise    
 
5034
    0       otherwise
4979
5035
*/
4980
5036
 
4981
5037
bool Item_equal::contains(Field *field)
4993
5049
 
4994
5050
/**
4995
5051
  Join members of another Item_equal object.
4996
 
  
 
5052
 
4997
5053
    The function actually merges two multiple equalities.
4998
5054
    After this operation the Item_equal object additionally contains
4999
5055
    the field items of another item of the type Item_equal.
5000
5056
    If the optional constant items are not equal the cond_false flag is
5001
 
    set to 1.  
 
5057
    set to 1.
5002
5058
  @param item    multiple equality whose members are to be joined
5003
5059
*/
5004
5060
 
5008
5064
  Item *c= item->const_item;
5009
5065
  if (c)
5010
5066
  {
5011
 
    /* 
5012
 
      The flag cond_false will be set to 1 after this, if 
5013
 
      the multiple equality already contains a constant and its 
 
5067
    /*
 
5068
      The flag cond_false will be set to 1 after this, if
 
5069
      the multiple equality already contains a constant and its
5014
5070
      value is  not equal to the value of c.
5015
5071
    */
5016
5072
    add(c);
5017
5073
  }
5018
5074
  cond_false|= item->cond_false;
5019
 
 
5075
}
5020
5076
 
5021
5077
 
5022
5078
/**
5092
5148
  }
5093
5149
}
5094
5150
 
5095
 
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
 
5151
bool Item_equal::fix_fields(Session *, Item **)
5096
5152
{
5097
5153
  List_iterator_fast<Item_field> li(fields);
5098
5154
  Item *item;
5179
5235
      return 0;
5180
5236
 
5181
5237
    /*
5182
 
      THD::change_item_tree() should be called only if the tree was
 
5238
      Session::change_item_tree() should be called only if the tree was
5183
5239
      really transformed, i.e. when a new item has been created.
5184
5240
      Otherwise we'll be allocating a lot of unnecessary memory for
5185
5241
      change records at each execution.
5186
5242
    */
5187
5243
    if (new_item != item)
5188
 
      current_thd->change_item_tree((Item **) it.ref(), new_item);
 
5244
      current_session->change_item_tree((Item **) it.ref(), new_item);
5189
5245
  }
5190
5246
  return Item_func::transform(transformer, arg);
5191
5247
}