~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_cmpfunc.cc

  • Committer: Monty Taylor
  • Date: 2008-10-20 08:48:34 UTC
  • mfrom: (520.1.22 drizzle)
  • Revision ID: monty@inaugust.com-20081020084834-xpb3w01vkcp55o02
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <drizzled/server_includes.h>
25
25
#include <drizzled/sql_select.h>
26
26
 
27
 
static bool convert_constant_item(THD *, Item_field *, Item **);
 
27
static bool convert_constant_item(Session *, Item_field *, Item **);
28
28
 
29
29
static Item_result item_store_type(Item_result a, Item *item,
30
30
                                   bool unsigned_flag)
361
361
    also when comparing bigint to strings (in which case strings
362
362
    are converted to bigints).
363
363
 
364
 
  @param  thd             thread handle
 
364
  @param  session             thread handle
365
365
  @param  field_item      item will be converted using the type of this field
366
366
  @param[in,out] item     reference to the item to convert
367
367
 
378
378
    1  Item was replaced with an integer version of the item
379
379
*/
380
380
 
381
 
static bool convert_constant_item(THD *thd, Item_field *field_item,
 
381
static bool convert_constant_item(Session *session, Item_field *field_item,
382
382
                                  Item **item)
383
383
{
384
384
  Field *field= field_item->field;
386
386
 
387
387
  if (!(*item)->with_subselect && (*item)->const_item())
388
388
  {
389
 
    ulong orig_sql_mode= thd->variables.sql_mode;
390
 
    enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
 
389
    ulong orig_sql_mode= session->variables.sql_mode;
 
390
    enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
391
391
    uint64_t orig_field_val= 0; /* original field value if valid */
392
392
 
393
393
    /* For comparison purposes allow invalid dates like 2000-01-32 */
394
 
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
 
394
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
395
395
                             MODE_INVALID_DATES;
396
 
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
396
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
397
397
 
398
398
    /*
399
399
      Store the value of the field if it references an outer field because
406
406
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
407
407
                                       test(field->flags & UNSIGNED_FLAG));
408
408
      if (tmp)
409
 
        thd->change_item_tree(item, tmp);
 
409
        session->change_item_tree(item, tmp);
410
410
      result= 1;                                        // Item was replaced
411
411
    }
412
412
    /* Restore the original field value. */
416
416
      /* orig_field_val must be a valid value that can be restored back. */
417
417
      assert(!result);
418
418
    }
419
 
    thd->variables.sql_mode= orig_sql_mode;
420
 
    thd->count_cuted_fields= orig_count_cuted_fields;
 
419
    session->variables.sql_mode= orig_sql_mode;
 
420
    session->count_cuted_fields= orig_count_cuted_fields;
421
421
  }
422
422
  return result;
423
423
}
426
426
void Item_bool_func2::fix_length_and_dec()
427
427
{
428
428
  max_length= 1;                                     // Function returns 0 or 1
429
 
  THD *thd;
 
429
  Session *session;
430
430
 
431
431
  /*
432
432
    As some compare functions are generated after sql_yacc,
464
464
    return;
465
465
  }
466
466
 
467
 
  thd= current_thd;
 
467
  session= current_session;
468
468
 
469
469
  if (args[0]->real_item()->type() == FIELD_ITEM)
470
470
  {
472
472
    if (field_item->field->can_be_compared_as_int64_t() &&
473
473
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
474
474
    {
475
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
475
      if (convert_constant_item(session, field_item, &args[1]))
476
476
      {
477
477
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
478
478
                         INT_RESULT);           // Works for all types.
488
488
          !(field_item->is_datetime() &&
489
489
            args[0]->result_type() == STRING_RESULT))
490
490
      {
491
 
        if (convert_constant_item(thd, field_item, &args[0]))
 
491
        if (convert_constant_item(session, field_item, &args[0]))
492
492
        {
493
493
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
494
494
                           INT_RESULT); // Works for all types.
608
608
/**
609
609
  @brief Convert date provided in a string to the int representation.
610
610
 
611
 
  @param[in]   thd        thread handle
 
611
  @param[in]   session        thread handle
612
612
  @param[in]   str        a string to convert
613
613
  @param[in]   warn_type  type of the timestamp for issuing the warning
614
614
  @param[in]   warn_name  field name for issuing the warning
628
628
*/
629
629
 
630
630
static uint64_t
631
 
get_date_from_str(THD *thd, String *str, enum enum_drizzle_timestamp_type warn_type,
 
631
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
632
632
                  char *warn_name, bool *error_arg)
633
633
{
634
634
  uint64_t value= 0;
638
638
 
639
639
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
640
640
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
641
 
                        (thd->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
641
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
642
642
                       &error);
643
643
 
644
644
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
657
657
  }
658
658
 
659
659
  if (error > 0)
660
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
660
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
661
661
                                 str->ptr(), str->length(),
662
662
                                 warn_type, warn_name);
663
663
 
734
734
        (str_arg->type() != Item::FUNC_ITEM ||
735
735
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
736
736
    {
737
 
      THD *thd= current_thd;
 
737
      Session *session= current_session;
738
738
      uint64_t value;
739
739
      bool error;
740
740
      String tmp, *str_val= 0;
744
744
      str_val= str_arg->val_str(&tmp);
745
745
      if (str_arg->null_value)
746
746
        return CMP_DATE_DFLT;
747
 
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
 
747
      value= get_date_from_str(session, str_val, t_type, date_arg->name, &error);
748
748
      if (error)
749
749
        return CMP_DATE_DFLT;
750
750
      if (const_value)
760
760
 
761
761
  SYNOPSIS
762
762
    get_time_value()
763
 
    thd                 thread handle
 
763
    session                 thread handle
764
764
    item_arg   [in/out] item to retrieve TIME value from
765
765
    cache_arg  [in/out] pointer to place to store the cache item to
766
766
    warn_item  [in]     unused
781
781
*/
782
782
 
783
783
uint64_t
784
 
get_time_value(THD *thd __attribute__((unused)),
 
784
get_time_value(Session *session __attribute__((unused)),
785
785
               Item ***item_arg, Item **cache_arg,
786
786
               Item *warn_item __attribute__((unused)),
787
787
               bool *is_null)
829
829
 
830
830
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
831
831
  {
832
 
    thd= current_thd;
 
832
    session= current_session;
833
833
    owner= owner_arg;
834
834
    a_type= (*a)->field_type();
835
835
    b_type= (*b)->field_type();
863
863
           (*b)->field_type() == DRIZZLE_TYPE_TIME)
864
864
  {
865
865
    /* Compare TIME values as integers. */
866
 
    thd= current_thd;
 
866
    session= current_session;
867
867
    owner= owner_arg;
868
868
    a_cache= 0;
869
869
    b_cache= 0;
879
879
 
880
880
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
881
881
{
882
 
  thd= current_thd;
 
882
  session= current_session;
883
883
  /* A caller will handle null values by itself. */
884
884
  owner= NULL;
885
885
  a= a1;
899
899
 
900
900
  SYNOPSIS
901
901
    get_datetime_value()
902
 
    thd                 thread handle
 
902
    session                 thread handle
903
903
    item_arg   [in/out] item to retrieve DATETIME value from
904
904
    cache_arg  [in/out] pointer to place to store the caching item to
905
905
    warn_item  [in]     item for issuing the conversion warning
924
924
*/
925
925
 
926
926
uint64_t
927
 
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
 
927
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
928
928
                   Item *warn_item, bool *is_null)
929
929
{
930
930
  uint64_t value= 0;
965
965
    enum_field_types f_type= warn_item->field_type();
966
966
    enum enum_drizzle_timestamp_type t_type= f_type ==
967
967
      DRIZZLE_TYPE_NEWDATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
968
 
    value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
 
968
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
969
969
    /*
970
970
      If str did not contain a valid date according to the current
971
971
      SQL_MODE, get_date_from_str() has already thrown a warning,
1017
1017
  uint64_t a_value, b_value;
1018
1018
 
1019
1019
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1020
 
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
 
1020
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
1021
1021
  if (!is_nulls_eq && is_null)
1022
1022
  {
1023
1023
    if (owner)
1026
1026
  }
1027
1027
 
1028
1028
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1029
 
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
 
1029
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
1030
1030
  if (is_null)
1031
1031
  {
1032
1032
    if (owner)
1443
1443
}
1444
1444
 
1445
1445
 
1446
 
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
 
1446
bool Item_in_optimizer::fix_left(Session *session, Item **ref __attribute__((unused)))
1447
1447
{
1448
 
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
 
1448
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
1449
1449
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1450
1450
    return 1;
1451
1451
 
1477
1477
}
1478
1478
 
1479
1479
 
1480
 
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
 
1480
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
1481
1481
{
1482
1482
  assert(fixed == 0);
1483
 
  if (fix_left(thd, ref))
 
1483
  if (fix_left(session, ref))
1484
1484
    return true;
1485
1485
  if (args[0]->maybe_null)
1486
1486
    maybe_null=1;
1487
1487
 
1488
 
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
 
1488
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
1489
1489
    return true;
1490
1490
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1491
1491
  if (args[0]->cols() != sub->engine->cols())
1632
1632
  if (!new_item)
1633
1633
    return 0;
1634
1634
  /*
1635
 
    THD::change_item_tree() should be called only if the tree was
 
1635
    Session::change_item_tree() should be called only if the tree was
1636
1636
    really transformed, i.e. when a new item has been created.
1637
1637
    Otherwise we'll be allocating a lot of unnecessary memory for
1638
1638
    change records at each execution.
1639
1639
  */
1640
1640
  if ((*args) != new_item)
1641
 
    current_thd->change_item_tree(args, new_item);
 
1641
    current_session->change_item_tree(args, new_item);
1642
1642
 
1643
1643
  /*
1644
1644
    Transform the right IN operand which should be an Item_in_subselect or a
1926
1926
    The function saves in ref the pointer to the item or to a newly created
1927
1927
    item that is considered as a replacement for the original one.
1928
1928
 
1929
 
  @param thd     reference to the global context of the query thread
 
1929
  @param session     reference to the global context of the query thread
1930
1930
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1931
1931
                 item is to be assigned
1932
1932
 
1946
1946
    1   got error
1947
1947
*/
1948
1948
 
1949
 
bool Item_func_between::fix_fields(THD *thd, Item **ref)
 
1949
bool Item_func_between::fix_fields(Session *session, Item **ref)
1950
1950
{
1951
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
1951
  if (Item_func_opt_neg::fix_fields(session, ref))
1952
1952
    return 1;
1953
1953
 
1954
 
  thd->lex->current_select->between_count++;
 
1954
  session->lex->current_select->between_count++;
1955
1955
 
1956
1956
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1957
1957
  if (pred_level && !negated)
1973
1973
  bool datetime_found= false;
1974
1974
  int time_items_found= 0;
1975
1975
  compare_as_dates= true;
1976
 
  THD *thd= current_thd;
 
1976
  Session *session= current_session;
1977
1977
 
1978
1978
  /*
1979
1979
    As some compare functions are generated after sql_yacc,
2020
2020
    cmp_type= INT_RESULT;
2021
2021
  }
2022
2022
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
2023
 
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
 
2023
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2024
2024
  {
2025
2025
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2026
2026
    if (field_item->field->can_be_compared_as_int64_t())
2029
2029
        The following can't be recoded with || as convert_constant_item
2030
2030
        changes the argument
2031
2031
      */
2032
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
2032
      if (convert_constant_item(session, field_item, &args[1]))
2033
2033
        cmp_type=INT_RESULT;                    // Works for all types.
2034
 
      if (convert_constant_item(thd, field_item, &args[2]))
 
2034
      if (convert_constant_item(session, field_item, &args[2]))
2035
2035
        cmp_type=INT_RESULT;                    // Works for all types.
2036
2036
    }
2037
2037
  }
2293
2293
    The function saves in ref the pointer to the item or to a newly created
2294
2294
    item that is considered as a replacement for the original one.
2295
2295
 
2296
 
  @param thd     reference to the global context of the query thread
 
2296
  @param session     reference to the global context of the query thread
2297
2297
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2298
2298
                 item is to be assigned
2299
2299
 
2312
2312
*/
2313
2313
 
2314
2314
bool
2315
 
Item_func_if::fix_fields(THD *thd, Item **ref)
 
2315
Item_func_if::fix_fields(Session *session, Item **ref)
2316
2316
{
2317
2317
  assert(fixed == 0);
2318
2318
  args[0]->top_level_item();
2319
2319
 
2320
 
  if (Item_func::fix_fields(thd, ref))
 
2320
  if (Item_func::fix_fields(session, ref))
2321
2321
    return 1;
2322
2322
 
2323
2323
  not_null_tables_cache= (args[1]->not_null_tables() &
2665
2665
}
2666
2666
 
2667
2667
 
2668
 
bool Item_func_case::fix_fields(THD *thd, Item **ref)
 
2668
bool Item_func_case::fix_fields(Session *session, Item **ref)
2669
2669
{
2670
2670
  /*
2671
2671
    buff should match stack usage from
2672
2672
    Item_func_case::val_int() -> Item_func_case::find_item()
2673
2673
  */
2674
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);
 
2675
  bool res= Item_func::fix_fields(session, ref);
2676
2676
  /*
2677
2677
    Call check_stack_overrun after fix_fields to be sure that stack variable
2678
2678
    is not optimized away
2679
2679
  */
2680
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
2680
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2681
2681
    return true;                                // Fatal error flag is set!
2682
2682
  return res;
2683
2683
}
3175
3175
  bool is_null;
3176
3176
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3177
3177
 
3178
 
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3178
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3179
3179
  buff->unsigned_flag= 1L;
3180
3180
}
3181
3181
 
3183
3183
{
3184
3184
  bool is_null;
3185
3185
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3186
 
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3186
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3187
3187
  if (item->null_value)
3188
3188
    return 0;
3189
3189
  tmp.unsigned_flag= 1L;
3295
3295
void cmp_item_row::alloc_comparators()
3296
3296
{
3297
3297
  if (!comparators)
3298
 
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
 
3298
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
3299
3299
}
3300
3300
 
3301
3301
 
3418
3418
{
3419
3419
  bool is_null;
3420
3420
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3421
 
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3421
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3422
3422
}
3423
3423
 
3424
3424
 
3427
3427
  bool is_null;
3428
3428
  Item **tmp_item= &arg;
3429
3429
  return value !=
3430
 
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3430
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3431
3431
}
3432
3432
 
3433
3433
 
3464
3464
    The function saves in ref the pointer to the item or to a newly created
3465
3465
    item that is considered as a replacement for the original one.
3466
3466
 
3467
 
  @param thd     reference to the global context of the query thread
 
3467
  @param session     reference to the global context of the query thread
3468
3468
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3469
3469
                 item is to be assigned
3470
3470
 
3485
3485
*/
3486
3486
 
3487
3487
bool
3488
 
Item_func_in::fix_fields(THD *thd, Item **ref)
 
3488
Item_func_in::fix_fields(Session *session, Item **ref)
3489
3489
{
3490
3490
  Item **arg, **arg_end;
3491
3491
 
3492
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
3492
  if (Item_func_opt_neg::fix_fields(session, ref))
3493
3493
    return 1;
3494
3494
 
3495
3495
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3517
3517
{
3518
3518
  Item **arg, **arg_end;
3519
3519
  bool const_itm= 1;
3520
 
  THD *thd= current_thd;
 
3520
  Session *session= current_session;
3521
3521
  bool datetime_found= false;
3522
3522
  /* true <=> arguments values will be compared as DATETIMEs. */
3523
3523
  bool compare_as_datetime= false;
3655
3655
        comparison type accordingly.
3656
3656
      */  
3657
3657
      if (args[0]->real_item()->type() == FIELD_ITEM &&
3658
 
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
 
3658
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3659
3659
          cmp_type != INT_RESULT)
3660
3660
      {
3661
3661
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3664
3664
          bool all_converted= true;
3665
3665
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3666
3666
          {
3667
 
            if (!convert_constant_item (thd, field_item, &arg[0]))
 
3667
            if (!convert_constant_item (session, field_item, &arg[0]))
3668
3668
              all_converted= false;
3669
3669
          }
3670
3670
          if (all_converted)
3698
3698
        return;
3699
3699
      }
3700
3700
    }
3701
 
    if (array && !(thd->is_fatal_error))                // If not EOM
 
3701
    if (array && !(session->is_fatal_error))            // If not EOM
3702
3702
    {
3703
3703
      uint32_t j=0;
3704
3704
      for (uint32_t i=1 ; i < arg_count ; i++)
3850
3850
  return (int64_t) (arg1 & arg2);
3851
3851
}
3852
3852
 
3853
 
Item_cond::Item_cond(THD *thd, Item_cond *item)
3854
 
  :Item_bool_func(thd, item),
 
3853
Item_cond::Item_cond(Session *session, Item_cond *item)
 
3854
  :Item_bool_func(session, item),
3855
3855
   abort_on_null(item->abort_on_null),
3856
3856
   and_tables_cache(item->and_tables_cache)
3857
3857
{
3861
3861
}
3862
3862
 
3863
3863
 
3864
 
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
 
3864
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3865
3865
{
3866
3866
  List_iterator_fast<Item> li(item->list);
3867
3867
  while (Item *it= li++)
3868
 
    list.push_back(it->copy_andor_structure(thd));
 
3868
    list.push_back(it->copy_andor_structure(session));
3869
3869
}
3870
3870
 
3871
3871
 
3872
3872
bool
3873
 
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
 
3873
Item_cond::fix_fields(Session *session, Item **ref __attribute__((unused)))
3874
3874
{
3875
3875
  assert(fixed == 0);
3876
3876
  List_iterator<Item> li(list);
3877
3877
  Item *item;
3878
 
  void *orig_thd_marker= thd->thd_marker;
 
3878
  void *orig_session_marker= session->session_marker;
3879
3879
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3880
3880
  not_null_tables_cache= used_tables_cache= 0;
3881
3881
  const_item_cache= 1;
3882
3882
 
3883
3883
  if (functype() == COND_OR_FUNC)
3884
 
    thd->thd_marker= 0;
 
3884
    session->session_marker= 0;
3885
3885
  /*
3886
3886
    and_table_cache is the value that Item_cond_or() returns for
3887
3887
    not_null_tables()
3888
3888
  */
3889
3889
  and_tables_cache= ~(table_map) 0;
3890
3890
 
3891
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
3891
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3892
3892
    return true;                                // Fatal error flag is set!
3893
3893
  /*
3894
3894
    The following optimization reduces the depth of an AND-OR tree.
3921
3921
 
3922
3922
    // item can be substituted in fix_fields
3923
3923
    if ((!item->fixed &&
3924
 
         item->fix_fields(thd, li.ref())) ||
 
3924
         item->fix_fields(session, li.ref())) ||
3925
3925
        (item= *li.ref())->check_cols(1))
3926
3926
      return true; /* purecov: inspected */
3927
3927
    used_tables_cache|=     item->used_tables();
3939
3939
    if (item->maybe_null)
3940
3940
      maybe_null=1;
3941
3941
  }
3942
 
  thd->lex->current_select->cond_count+= list.elements;
3943
 
  thd->thd_marker= orig_thd_marker;
 
3942
  session->lex->current_select->cond_count+= list.elements;
 
3943
  session->session_marker= orig_session_marker;
3944
3944
  fix_length_and_dec();
3945
3945
  fixed= 1;
3946
3946
  return false;
4019
4019
      return 0;
4020
4020
 
4021
4021
    /*
4022
 
      THD::change_item_tree() should be called only if the tree was
 
4022
      Session::change_item_tree() should be called only if the tree was
4023
4023
      really transformed, i.e. when a new item has been created.
4024
4024
      Otherwise we'll be allocating a lot of unnecessary memory for
4025
4025
      change records at each execution.
4026
4026
    */
4027
4027
    if (new_item != item)
4028
 
      current_thd->change_item_tree(li.ref(), new_item);
 
4028
      current_session->change_item_tree(li.ref(), new_item);
4029
4029
  }
4030
4030
  return Item_func::transform(transformer, arg);
4031
4031
}
4109
4109
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4110
4110
  sql_select.cc)
4111
4111
 
4112
 
  @param thd                    Thread handler
 
4112
  @param session                        Thread handler
4113
4113
  @param ref_pointer_array      Pointer to array of reference fields
4114
4114
  @param fields         All fields in select
4115
4115
 
4118
4118
    that have or refer (HAVING) to a SUM expression.
4119
4119
*/
4120
4120
 
4121
 
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
 
4121
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4122
4122
                               List<Item> &fields)
4123
4123
{
4124
4124
  List_iterator<Item> li(list);
4125
4125
  Item *item;
4126
4126
  while ((item= li++))
4127
 
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
 
4127
    item->split_sum_func2(session, ref_pointer_array, fields, li.ref(), true);
4128
4128
}
4129
4129
 
4130
4130
 
4169
4169
}
4170
4170
 
4171
4171
 
4172
 
void Item_cond::neg_arguments(THD *thd)
 
4172
void Item_cond::neg_arguments(Session *session)
4173
4173
{
4174
4174
  List_iterator<Item> li(list);
4175
4175
  Item *item;
4176
4176
  while ((item= li++))          /* Apply not transformation to the arguments */
4177
4177
  {
4178
 
    Item *new_item= item->neg_transformer(thd);
 
4178
    Item *new_item= item->neg_transformer(session);
4179
4179
    if (!new_item)
4180
4180
    {
4181
4181
      if (!(new_item= new Item_func_not(item)))
4399
4399
}
4400
4400
 
4401
4401
 
4402
 
bool Item_func_like::fix_fields(THD *thd, Item **ref)
 
4402
bool Item_func_like::fix_fields(Session *session, Item **ref)
4403
4403
{
4404
4404
  assert(fixed == 0);
4405
 
  if (Item_bool_func2::fix_fields(thd, ref) ||
4406
 
      escape_item->fix_fields(thd, &escape_item))
 
4405
  if (Item_bool_func2::fix_fields(session, ref) ||
 
4406
      escape_item->fix_fields(session, &escape_item))
4407
4407
    return true;
4408
4408
 
4409
4409
  if (!escape_item->const_during_execution())
4490
4490
      {
4491
4491
        pattern     = first + 1;
4492
4492
        pattern_len = (int) len - 2;
4493
 
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
 
4493
        int *suff = (int*) session->alloc((int) (sizeof(int)*
4494
4494
                                      ((pattern_len + 1)*2+
4495
4495
                                      alphabet_size)));
4496
4496
        bmGs      = suff + pattern_len + 1;
4783
4783
       IS NOT NULL(a)     -> IS NULL(a)
4784
4784
    @endverbatim
4785
4785
 
4786
 
  @param thd            thread handler
 
4786
  @param session                thread handler
4787
4787
 
4788
4788
  @return
4789
4789
    New item or
4790
4790
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4791
4791
*/
4792
4792
 
4793
 
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
 
4793
Item *Item_func_not::neg_transformer(Session *session __attribute__((unused)))  /* NOT(x)  ->  x */
4794
4794
{
4795
4795
  return args[0];
4796
4796
}
4797
4797
 
4798
4798
 
4799
 
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
 
4799
Item *Item_bool_rowready_func2::neg_transformer(Session *session __attribute__((unused)))
4800
4800
{
4801
4801
  Item *item= negated_item();
4802
4802
  return item;
4806
4806
/**
4807
4807
  a IS NULL  ->  a IS NOT NULL.
4808
4808
*/
4809
 
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
 
4809
Item *Item_func_isnull::neg_transformer(Session *session __attribute__((unused)))
4810
4810
{
4811
4811
  Item *item= new Item_func_isnotnull(args[0]);
4812
4812
  return item;
4816
4816
/**
4817
4817
  a IS NOT NULL  ->  a IS NULL.
4818
4818
*/
4819
 
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
 
4819
Item *Item_func_isnotnull::neg_transformer(Session *session __attribute__((unused)))
4820
4820
{
4821
4821
  Item *item= new Item_func_isnull(args[0]);
4822
4822
  return item;
4823
4823
}
4824
4824
 
4825
4825
 
4826
 
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
 
4826
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
4827
4827
                                        /* NOT a OR NOT b OR ... */
4828
4828
{
4829
 
  neg_arguments(thd);
 
4829
  neg_arguments(session);
4830
4830
  Item *item= new Item_cond_or(list);
4831
4831
  return item;
4832
4832
}
4833
4833
 
4834
4834
 
4835
 
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
 
4835
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
4836
4836
                                        /* NOT a AND NOT b AND ... */
4837
4837
{
4838
 
  neg_arguments(thd);
 
4838
  neg_arguments(session);
4839
4839
  Item *item= new Item_cond_and(list);
4840
4840
  return item;
4841
4841
}
4842
4842
 
4843
4843
 
4844
 
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
 
4844
Item *Item_func_nop_all::neg_transformer(Session *session __attribute__((unused)))
4845
4845
{
4846
4846
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4847
4847
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4852
4852
  return new_item;
4853
4853
}
4854
4854
 
4855
 
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
 
4855
Item *Item_func_not_all::neg_transformer(Session *session __attribute__((unused)))
4856
4856
{
4857
4857
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4858
4858
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
5092
5092
  }
5093
5093
}
5094
5094
 
5095
 
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
 
5095
bool Item_equal::fix_fields(Session *session __attribute__((unused)), Item **ref __attribute__((unused)))
5096
5096
{
5097
5097
  List_iterator_fast<Item_field> li(fields);
5098
5098
  Item *item;
5179
5179
      return 0;
5180
5180
 
5181
5181
    /*
5182
 
      THD::change_item_tree() should be called only if the tree was
 
5182
      Session::change_item_tree() should be called only if the tree was
5183
5183
      really transformed, i.e. when a new item has been created.
5184
5184
      Otherwise we'll be allocating a lot of unnecessary memory for
5185
5185
      change records at each execution.
5186
5186
    */
5187
5187
    if (new_item != item)
5188
 
      current_thd->change_item_tree((Item **) it.ref(), new_item);
 
5188
      current_session->change_item_tree((Item **) it.ref(), new_item);
5189
5189
  }
5190
5190
  return Item_func::transform(transformer, arg);
5191
5191
}