~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Mark Atwood
  • Date: 2009-01-05 04:37:22 UTC
  • mto: (758.1.1 devel)
  • mto: This revision was merged to the branch mainline in revision 759.
  • Revision ID: me@mark.atwood.name-20090105043722-03l4mzcxi4yjjjih
replace sql_print_error etc with errmsg_print

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#include <drizzled/server_includes.h>
25
25
#include <drizzled/sql_select.h>
26
 
 
27
 
static bool convert_constant_item(THD *, Item_field *, Item **);
 
26
#include <drizzled/error.h>
 
27
#include <drizzled/item/cmpfunc.h>
 
28
#include <drizzled/cached_item.h>
 
29
#include <drizzled/item/cache_int.h>
 
30
#include <drizzled/item/int_with_ref.h>
 
31
#include <drizzled/function/bit.h>
 
32
#include <drizzled/check_stack_overrun.h>
 
33
 
 
34
#include CMATH_H
 
35
 
 
36
#if defined(CMATH_NAMESPACE)
 
37
using namespace CMATH_NAMESPACE;
 
38
#endif
 
39
 
 
40
static Eq_creator eq_creator;
 
41
static Ne_creator ne_creator;
 
42
static Gt_creator gt_creator;
 
43
static Lt_creator lt_creator;
 
44
static Ge_creator ge_creator;
 
45
static Le_creator le_creator;
 
46
 
 
47
static bool convert_constant_item(Session *, Item_field *, Item **);
28
48
 
29
49
static Item_result item_store_type(Item_result a, Item *item,
30
50
                                   bool unsigned_flag)
79
99
  DESCRIPTION
80
100
    The function checks that two expressions have compatible row signatures
81
101
    i.e. that the number of columns they return are the same and that if they
82
 
    are both row expressions then each component from the first expression has 
 
102
    are both row expressions then each component from the first expression has
83
103
    a row signature compatible with the signature of the corresponding component
84
104
    of the second expression.
85
105
 
140
160
      of the first row expression has a compatible row signature with
141
161
      the signature of the corresponding component of the second row
142
162
      expression.
143
 
    */ 
 
163
    */
144
164
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
145
165
      return 1;     // error found: invalid usage of rows
146
166
  }
203
223
  found_types= 0;
204
224
  for (i= 1; i < nitems ; i++)
205
225
  {
206
 
    if ((left_result == ROW_RESULT || 
 
226
    if ((left_result == ROW_RESULT ||
207
227
         items[i]->result_type() == ROW_RESULT) &&
208
228
        cmp_row_type(items[0], items[i]))
209
229
      return 0;
213
233
  return found_types;
214
234
}
215
235
 
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
236
 
226
237
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
227
238
{
229
240
}
230
241
 
231
242
 
 
243
const Eq_creator* Eq_creator::instance()
 
244
{
 
245
  return &eq_creator;
 
246
}
 
247
 
 
248
 
232
249
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
233
250
{
234
251
  return new Item_func_ne(a, b);
235
252
}
236
253
 
237
254
 
 
255
const Ne_creator* Ne_creator::instance()
 
256
{
 
257
  return &ne_creator;
 
258
}
 
259
 
 
260
 
238
261
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
239
262
{
240
263
  return new Item_func_gt(a, b);
241
264
}
242
265
 
243
266
 
 
267
const Gt_creator* Gt_creator::instance()
 
268
{
 
269
  return &gt_creator;
 
270
}
 
271
 
 
272
 
244
273
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
245
274
{
246
275
  return new Item_func_lt(a, b);
247
276
}
248
277
 
249
278
 
 
279
const Lt_creator* Lt_creator::instance()
 
280
{
 
281
  return &lt_creator;
 
282
}
 
283
 
 
284
 
250
285
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
251
286
{
252
287
  return new Item_func_ge(a, b);
253
288
}
254
289
 
255
290
 
 
291
const Ge_creator* Ge_creator::instance()
 
292
{
 
293
  return &ge_creator;
 
294
}
 
295
 
 
296
 
256
297
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
257
298
{
258
299
  return new Item_func_le(a, b);
259
300
}
260
301
 
 
302
const Le_creator* Le_creator::instance()
 
303
{
 
304
  return &le_creator;
 
305
}
 
306
 
 
307
 
261
308
/*
262
309
  Test functions
263
310
  Most of these  returns 0LL if false and 1LL if true and
361
408
    also when comparing bigint to strings (in which case strings
362
409
    are converted to bigints).
363
410
 
364
 
  @param  thd             thread handle
 
411
  @param  session             thread handle
365
412
  @param  field_item      item will be converted using the type of this field
366
413
  @param[in,out] item     reference to the item to convert
367
414
 
378
425
    1  Item was replaced with an integer version of the item
379
426
*/
380
427
 
381
 
static bool convert_constant_item(THD *thd, Item_field *field_item,
 
428
static bool convert_constant_item(Session *session, Item_field *field_item,
382
429
                                  Item **item)
383
430
{
384
431
  Field *field= field_item->field;
386
433
 
387
434
  if (!(*item)->with_subselect && (*item)->const_item())
388
435
  {
389
 
    ulong orig_sql_mode= thd->variables.sql_mode;
390
 
    enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
 
436
    ulong orig_sql_mode= session->variables.sql_mode;
 
437
    enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
391
438
    uint64_t orig_field_val= 0; /* original field value if valid */
392
439
 
393
440
    /* For comparison purposes allow invalid dates like 2000-01-32 */
394
 
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
 
441
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
395
442
                             MODE_INVALID_DATES;
396
 
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
443
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
397
444
 
398
445
    /*
399
446
      Store the value of the field if it references an outer field because
406
453
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
407
454
                                       test(field->flags & UNSIGNED_FLAG));
408
455
      if (tmp)
409
 
        thd->change_item_tree(item, tmp);
 
456
        session->change_item_tree(item, tmp);
410
457
      result= 1;                                        // Item was replaced
411
458
    }
412
459
    /* Restore the original field value. */
416
463
      /* orig_field_val must be a valid value that can be restored back. */
417
464
      assert(!result);
418
465
    }
419
 
    thd->variables.sql_mode= orig_sql_mode;
420
 
    thd->count_cuted_fields= orig_count_cuted_fields;
 
466
    session->variables.sql_mode= orig_sql_mode;
 
467
    session->count_cuted_fields= orig_count_cuted_fields;
421
468
  }
422
469
  return result;
423
470
}
426
473
void Item_bool_func2::fix_length_and_dec()
427
474
{
428
475
  max_length= 1;                                     // Function returns 0 or 1
429
 
  THD *thd;
 
476
  Session *session;
430
477
 
431
478
  /*
432
479
    As some compare functions are generated after sql_yacc,
435
482
  if (!args[0] || !args[1])
436
483
    return;
437
484
 
438
 
  /* 
 
485
  /*
439
486
    We allow to convert to Unicode character sets in some cases.
440
487
    The conditions when conversion is possible are:
441
488
    - arguments A and B have different charsets
442
489
    - A wins according to coercibility rules
443
490
    - character set of A is superset for character set of B
444
 
   
 
491
 
445
492
    If all of the above is true, then it's possible to convert
446
493
    B into the character set of A, and then compare according
447
494
    to the collation of A.
448
495
  */
449
496
 
450
 
  
 
497
 
451
498
  DTCollation coll;
452
499
  if (args[0]->result_type() == STRING_RESULT &&
453
500
      args[1]->result_type() == STRING_RESULT &&
454
501
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
455
502
    return;
456
 
    
 
503
 
457
504
  args[0]->cmp_context= args[1]->cmp_context=
458
505
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
459
506
  // Make a special case of compare with fields to get nicer DATE comparisons
464
511
    return;
465
512
  }
466
513
 
467
 
  thd= current_thd;
 
514
  session= current_session;
468
515
 
469
516
  if (args[0]->real_item()->type() == FIELD_ITEM)
470
517
  {
472
519
    if (field_item->field->can_be_compared_as_int64_t() &&
473
520
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
474
521
    {
475
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
522
      if (convert_constant_item(session, field_item, &args[1]))
476
523
      {
477
524
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
478
525
                         INT_RESULT);           // Works for all types.
488
535
          !(field_item->is_datetime() &&
489
536
            args[0]->result_type() == STRING_RESULT))
490
537
      {
491
 
        if (convert_constant_item(thd, field_item, &args[0]))
 
538
        if (convert_constant_item(session, field_item, &args[0]))
492
539
        {
493
540
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
494
541
                           INT_RESULT); // Works for all types.
536
583
      We must set cmp_charset here as we may be called from for an automatic
537
584
      generated item, like in natural join
538
585
    */
539
 
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
586
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
540
587
        cmp_collation.derivation == DERIVATION_NONE)
541
588
    {
542
589
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
608
655
/**
609
656
  @brief Convert date provided in a string to the int representation.
610
657
 
611
 
  @param[in]   thd        thread handle
 
658
  @param[in]   session        thread handle
612
659
  @param[in]   str        a string to convert
613
660
  @param[in]   warn_type  type of the timestamp for issuing the warning
614
661
  @param[in]   warn_name  field name for issuing the warning
628
675
*/
629
676
 
630
677
static uint64_t
631
 
get_date_from_str(THD *thd, String *str, enum enum_drizzle_timestamp_type warn_type,
 
678
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
632
679
                  char *warn_name, bool *error_arg)
633
680
{
634
681
  uint64_t value= 0;
638
685
 
639
686
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
640
687
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
641
 
                        (thd->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
688
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
642
689
                       &error);
643
690
 
644
691
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
657
704
  }
658
705
 
659
706
  if (error > 0)
660
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
707
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
661
708
                                 str->ptr(), str->length(),
662
709
                                 warn_type, warn_name);
663
710
 
734
781
        (str_arg->type() != Item::FUNC_ITEM ||
735
782
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
736
783
    {
737
 
      THD *thd= current_thd;
 
784
      Session *session= current_session;
738
785
      uint64_t value;
739
786
      bool error;
740
787
      String tmp, *str_val= 0;
741
 
      enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
 
788
      enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_DATE ?
742
789
                              DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
743
790
 
744
791
      str_val= str_arg->val_str(&tmp);
745
792
      if (str_arg->null_value)
746
793
        return CMP_DATE_DFLT;
747
 
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
 
794
      value= get_date_from_str(session, str_val, t_type, date_arg->name, &error);
748
795
      if (error)
749
796
        return CMP_DATE_DFLT;
750
797
      if (const_value)
760
807
 
761
808
  SYNOPSIS
762
809
    get_time_value()
763
 
    thd                 thread handle
 
810
    session                 thread handle
764
811
    item_arg   [in/out] item to retrieve TIME value from
765
812
    cache_arg  [in/out] pointer to place to store the cache item to
766
813
    warn_item  [in]     unused
781
828
*/
782
829
 
783
830
uint64_t
784
 
get_time_value(THD *thd __attribute__((unused)),
 
831
get_time_value(Session *,
785
832
               Item ***item_arg, Item **cache_arg,
786
 
               Item *warn_item __attribute__((unused)),
787
 
               bool *is_null)
 
833
               Item *, bool *is_null)
788
834
{
789
835
  uint64_t value;
790
836
  Item *item= **item_arg;
829
875
 
830
876
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
831
877
  {
832
 
    thd= current_thd;
 
878
    session= current_session;
833
879
    owner= owner_arg;
834
880
    a_type= (*a)->field_type();
835
881
    b_type= (*b)->field_type();
863
909
           (*b)->field_type() == DRIZZLE_TYPE_TIME)
864
910
  {
865
911
    /* Compare TIME values as integers. */
866
 
    thd= current_thd;
 
912
    session= current_session;
867
913
    owner= owner_arg;
868
914
    a_cache= 0;
869
915
    b_cache= 0;
879
925
 
880
926
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
881
927
{
882
 
  thd= current_thd;
 
928
  session= current_session;
883
929
  /* A caller will handle null values by itself. */
884
930
  owner= NULL;
885
931
  a= a1;
899
945
 
900
946
  SYNOPSIS
901
947
    get_datetime_value()
902
 
    thd                 thread handle
 
948
    session                 thread handle
903
949
    item_arg   [in/out] item to retrieve DATETIME value from
904
950
    cache_arg  [in/out] pointer to place to store the caching item to
905
951
    warn_item  [in]     item for issuing the conversion warning
924
970
*/
925
971
 
926
972
uint64_t
927
 
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
 
973
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
928
974
                   Item *warn_item, bool *is_null)
929
975
{
930
976
  uint64_t value= 0;
942
988
      compare it with 100000000L - any DATE value should be less than it.
943
989
      Don't shift cached DATETIME values up for the second time.
944
990
    */
945
 
    if (f_type == DRIZZLE_TYPE_NEWDATE ||
 
991
    if (f_type == DRIZZLE_TYPE_DATE ||
946
992
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
947
993
      value*= 1000000L;
948
994
  }
964
1010
    bool error;
965
1011
    enum_field_types f_type= warn_item->field_type();
966
1012
    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);
 
1013
      DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
 
1014
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
969
1015
    /*
970
1016
      If str did not contain a valid date according to the current
971
1017
      SQL_MODE, get_date_from_str() has already thrown a warning,
1017
1063
  uint64_t a_value, b_value;
1018
1064
 
1019
1065
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1020
 
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
 
1066
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
1021
1067
  if (!is_nulls_eq && is_null)
1022
1068
  {
1023
1069
    if (owner)
1026
1072
  }
1027
1073
 
1028
1074
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1029
 
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
 
1075
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
1030
1076
  if (is_null)
1031
1077
  {
1032
1078
    if (owner)
1443
1489
}
1444
1490
 
1445
1491
 
1446
 
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
 
1492
bool Item_in_optimizer::fix_left(Session *session, Item **)
1447
1493
{
1448
 
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
 
1494
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
1449
1495
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1450
1496
    return 1;
1451
1497
 
1477
1523
}
1478
1524
 
1479
1525
 
1480
 
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
 
1526
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
1481
1527
{
1482
1528
  assert(fixed == 0);
1483
 
  if (fix_left(thd, ref))
 
1529
  if (fix_left(session, ref))
1484
1530
    return true;
1485
1531
  if (args[0]->maybe_null)
1486
1532
    maybe_null=1;
1487
1533
 
1488
 
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
 
1534
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
1489
1535
    return true;
1490
1536
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1491
1537
  if (args[0]->cols() != sub->engine->cols())
1509
1555
  bool tmp;
1510
1556
  assert(fixed == 1);
1511
1557
  cache->store(args[0]);
1512
 
  
 
1558
 
1513
1559
  if (cache->null_value)
1514
1560
  {
1515
1561
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1537
1583
          We disable the predicates we've pushed down into subselect, run the
1538
1584
          subselect and see if it has produced any rows.
1539
1585
        */
1540
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
 
1586
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
1541
1587
        if (cache->cols() == 1)
1542
1588
        {
1543
1589
          item_subs->set_cond_guard_var(0, false);
1558
1604
            if (cache->element_index(i)->null_value)
1559
1605
              item_subs->set_cond_guard_var(i, false);
1560
1606
          }
1561
 
          
 
1607
 
1562
1608
          (void) args[1]->val_bool_result();
1563
1609
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1564
 
          
 
1610
 
1565
1611
          /* Turn all predicates back on */
1566
1612
          for (i= 0; i < ncols; i++)
1567
1613
            item_subs->set_cond_guard_var(i, true);
1632
1678
  if (!new_item)
1633
1679
    return 0;
1634
1680
  /*
1635
 
    THD::change_item_tree() should be called only if the tree was
 
1681
    Session::change_item_tree() should be called only if the tree was
1636
1682
    really transformed, i.e. when a new item has been created.
1637
1683
    Otherwise we'll be allocating a lot of unnecessary memory for
1638
1684
    change records at each execution.
1639
1685
  */
1640
1686
  if ((*args) != new_item)
1641
 
    current_thd->change_item_tree(args, new_item);
 
1687
    current_session->change_item_tree(args, new_item);
1642
1688
 
1643
1689
  /*
1644
1690
    Transform the right IN operand which should be an Item_in_subselect or a
1763
1809
void Item_func_interval::fix_length_and_dec()
1764
1810
{
1765
1811
  uint32_t rows= row->cols();
1766
 
  
 
1812
 
1767
1813
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1768
1814
                            DECIMAL_RESULT) ||
1769
1815
                           (row->element_index(0)->result_type() ==
1904
1950
      if (my_decimal_cmp(e_dec, dec) > 0)
1905
1951
        return i - 1;
1906
1952
    }
1907
 
    else 
 
1953
    else
1908
1954
    {
1909
1955
      double val= el->val_real();
1910
1956
      /* Skip NULL ranges. */
1926
1972
    The function saves in ref the pointer to the item or to a newly created
1927
1973
    item that is considered as a replacement for the original one.
1928
1974
 
1929
 
  @param thd     reference to the global context of the query thread
 
1975
  @param session     reference to the global context of the query thread
1930
1976
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1931
1977
                 item is to be assigned
1932
1978
 
1946
1992
    1   got error
1947
1993
*/
1948
1994
 
1949
 
bool Item_func_between::fix_fields(THD *thd, Item **ref)
 
1995
bool Item_func_between::fix_fields(Session *session, Item **ref)
1950
1996
{
1951
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
1997
  if (Item_func_opt_neg::fix_fields(session, ref))
1952
1998
    return 1;
1953
1999
 
1954
 
  thd->lex->current_select->between_count++;
 
2000
  session->lex->current_select->between_count++;
1955
2001
 
1956
2002
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1957
2003
  if (pred_level && !negated)
1973
2019
  bool datetime_found= false;
1974
2020
  int time_items_found= 0;
1975
2021
  compare_as_dates= true;
1976
 
  THD *thd= current_thd;
 
2022
  Session *session= current_session;
1977
2023
 
1978
2024
  /*
1979
2025
    As some compare functions are generated after sql_yacc,
2020
2066
    cmp_type= INT_RESULT;
2021
2067
  }
2022
2068
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
2023
 
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
 
2069
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2024
2070
  {
2025
2071
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2026
2072
    if (field_item->field->can_be_compared_as_int64_t())
2029
2075
        The following can't be recoded with || as convert_constant_item
2030
2076
        changes the argument
2031
2077
      */
2032
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
2078
      if (convert_constant_item(session, field_item, &args[1]))
2033
2079
        cmp_type=INT_RESULT;                    // Works for all types.
2034
 
      if (convert_constant_item(thd, field_item, &args[2]))
 
2080
      if (convert_constant_item(session, field_item, &args[2]))
2035
2081
        cmp_type=INT_RESULT;                    // Works for all types.
2036
2082
    }
2037
2083
  }
2169
2215
  decimals= cmax(args[0]->decimals, args[1]->decimals);
2170
2216
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2171
2217
 
2172
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
 
2218
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2173
2219
  {
2174
2220
    int len0= args[0]->max_length - args[0]->decimals
2175
2221
      - (args[0]->unsigned_flag ? 0 : 1);
2207
2253
}
2208
2254
 
2209
2255
 
2210
 
enum_field_types Item_func_ifnull::field_type() const 
 
2256
enum_field_types Item_func_ifnull::field_type() const
2211
2257
{
2212
2258
  return cached_field_type;
2213
2259
}
2293
2339
    The function saves in ref the pointer to the item or to a newly created
2294
2340
    item that is considered as a replacement for the original one.
2295
2341
 
2296
 
  @param thd     reference to the global context of the query thread
 
2342
  @param session     reference to the global context of the query thread
2297
2343
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2298
2344
                 item is to be assigned
2299
2345
 
2312
2358
*/
2313
2359
 
2314
2360
bool
2315
 
Item_func_if::fix_fields(THD *thd, Item **ref)
 
2361
Item_func_if::fix_fields(Session *session, Item **ref)
2316
2362
{
2317
2363
  assert(fixed == 0);
2318
2364
  args[0]->top_level_item();
2319
2365
 
2320
 
  if (Item_func::fix_fields(thd, ref))
 
2366
  if (Item_func::fix_fields(session, ref))
2321
2367
    return 1;
2322
2368
 
2323
2369
  not_null_tables_cache= (args[1]->not_null_tables() &
2527
2573
bool
2528
2574
Item_func_nullif::is_null()
2529
2575
{
2530
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
 
2576
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
2531
2577
}
2532
2578
 
2533
2579
 
2552
2598
           failed
2553
2599
*/
2554
2600
 
2555
 
Item *Item_func_case::find_item(String *str __attribute__((unused)))
 
2601
Item *Item_func_case::find_item(String *)
2556
2602
{
2557
2603
  uint32_t value_added_map= 0;
2558
2604
 
2665
2711
}
2666
2712
 
2667
2713
 
2668
 
bool Item_func_case::fix_fields(THD *thd, Item **ref)
 
2714
bool Item_func_case::fix_fields(Session *session, Item **ref)
2669
2715
{
2670
2716
  /*
2671
2717
    buff should match stack usage from
2672
2718
    Item_func_case::val_int() -> Item_func_case::find_item()
2673
2719
  */
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);
 
2720
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
 
2721
                     +sizeof(double)*2+sizeof(int64_t)*2];
 
2722
  bool res= Item_func::fix_fields(session, ref);
2676
2723
  /*
2677
2724
    Call check_stack_overrun after fix_fields to be sure that stack variable
2678
2725
    is not optimized away
2679
2726
  */
2680
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
2727
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2681
2728
    return true;                                // Fatal error flag is set!
2682
2729
  return res;
2683
2730
}
2695
2742
{
2696
2743
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2697
2744
                                           arg->unsigned_flag) - arg->decimals;
2698
 
  set_if_bigger(max_length, len); 
 
2745
  set_if_bigger(max_length, len);
2699
2746
  set_if_bigger(decimals, arg->decimals);
2700
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
 
2747
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
2701
2748
}
2702
2749
 
2703
2750
 
2708
2755
  uint32_t found_types= 0;
2709
2756
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2710
2757
    return;
2711
 
  
 
2758
 
2712
2759
  /*
2713
2760
    Aggregate all THEN and ELSE expression types
2714
2761
    and collations when string result
2715
2762
  */
2716
 
  
 
2763
 
2717
2764
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2718
2765
    agg[nagg]= args[nagg*2+1];
2719
 
  
 
2766
 
2720
2767
  if (else_expr_num != -1)
2721
2768
    agg[nagg++]= args[else_expr_num];
2722
 
  
 
2769
 
2723
2770
  agg_result_type(&cached_result_type, agg, nagg);
2724
2771
  if ((cached_result_type == STRING_RESULT) &&
2725
2772
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2726
2773
    return;
2727
 
  
 
2774
 
2728
2775
  cached_field_type= agg_field_type(agg, nagg);
2729
2776
  /*
2730
2777
    Aggregate first expression and all THEN expression types
2760
2807
 
2761
2808
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2762
2809
    maybe_null=1;
2763
 
  
 
2810
 
2764
2811
  max_length=0;
2765
2812
  decimals=0;
2766
2813
  unsigned_flag= true;
2775
2822
  {
2776
2823
    for (uint32_t i= 0; i < ncases; i+= 2)
2777
2824
      agg_num_lengths(args[i + 1]);
2778
 
    if (else_expr_num != -1) 
 
2825
    if (else_expr_num != -1)
2779
2826
      agg_num_lengths(args[else_expr_num]);
2780
2827
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2781
2828
                                               unsigned_flag);
2789
2836
  for (uint32_t i=0 ; i < ncases ; i+=2)
2790
2837
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2791
2838
 
2792
 
  if (else_expr_num != -1) 
 
2839
  if (else_expr_num != -1)
2793
2840
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2794
2841
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2795
2842
}
2980
3027
 
2981
3028
 
2982
3029
/*
2983
 
  Compare two integers in IN value list format (packed_int64_t) 
 
3030
  Compare two integers in IN value list format (packed_int64_t)
2984
3031
 
2985
3032
  SYNOPSIS
2986
3033
    cmp_int64_t()
3002
3049
    0           left argument is equal to the right argument.
3003
3050
    1           left argument is greater than the right argument.
3004
3051
*/
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)
 
3052
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
 
3053
                in_int64_t::packed_int64_t *b)
3008
3054
{
3009
3055
  if (a->unsigned_flag != b->unsigned_flag)
3010
 
  { 
3011
 
    /* 
3012
 
      One of the args is unsigned and is too big to fit into the 
 
3056
  {
 
3057
    /*
 
3058
      One of the args is unsigned and is too big to fit into the
3013
3059
      positive signed range. Report no match.
3014
 
    */  
 
3060
    */
3015
3061
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3016
3062
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3017
3063
      return a->unsigned_flag ? 1 : -1;
3018
3064
    /*
3019
 
      Although the signedness differs both args can fit into the signed 
 
3065
      Although the signedness differs both args can fit into the signed
3020
3066
      positive range. Make them signed and compare as usual.
3021
 
    */  
 
3067
    */
3022
3068
    return cmp_longs (a->val, b->val);
3023
3069
  }
3024
3070
  if (a->unsigned_flag)
3027
3073
    return cmp_longs (a->val, b->val);
3028
3074
}
3029
3075
 
3030
 
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
 
3076
static int cmp_double(void *, double *a, double *b)
3031
3077
{
3032
3078
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3033
3079
}
3034
3080
 
3035
 
static int cmp_row(void *cmp_arg __attribute__((unused)), cmp_item_row *a, cmp_item_row *b)
 
3081
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
3036
3082
{
3037
3083
  return a->compare(b);
3038
3084
}
3039
3085
 
3040
3086
 
3041
 
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
 
3087
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
3042
3088
{
3043
3089
  /*
3044
3090
    We need call of fixing buffer pointer, because fast sort just copy
3115
3161
  return (unsigned char*) item->val_str(&tmp);
3116
3162
}
3117
3163
 
3118
 
in_row::in_row(uint32_t elements, Item * item __attribute__((unused)))
 
3164
in_row::in_row(uint32_t elements, Item *)
3119
3165
{
3120
3166
  base= (char*) new cmp_item_row[count= elements];
3121
3167
  size= sizeof(cmp_item_row);
3155
3201
void in_int64_t::set(uint32_t pos,Item *item)
3156
3202
{
3157
3203
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3158
 
  
 
3204
 
3159
3205
  buff->val= item->val_int();
3160
3206
  buff->unsigned_flag= item->unsigned_flag;
3161
3207
}
3175
3221
  bool is_null;
3176
3222
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3177
3223
 
3178
 
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3224
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3179
3225
  buff->unsigned_flag= 1L;
3180
3226
}
3181
3227
 
3183
3229
{
3184
3230
  bool is_null;
3185
3231
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3186
 
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3232
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3187
3233
  if (item->null_value)
3188
3234
    return 0;
3189
3235
  tmp.unsigned_flag= 1L;
3220
3266
  dec->len= DECIMAL_BUFF_LENGTH;
3221
3267
  dec->fix_buffer_pointer();
3222
3268
  my_decimal *res= item->val_decimal(dec);
3223
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
 
3269
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
3224
3270
  if (!item->null_value && res != dec)
3225
3271
    my_decimal2decimal(res, dec);
3226
3272
}
3295
3341
void cmp_item_row::alloc_comparators()
3296
3342
{
3297
3343
  if (!comparators)
3298
 
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
 
3344
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
3299
3345
}
3300
3346
 
3301
3347
 
3418
3464
{
3419
3465
  bool is_null;
3420
3466
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3421
 
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3467
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3422
3468
}
3423
3469
 
3424
3470
 
3427
3473
  bool is_null;
3428
3474
  Item **tmp_item= &arg;
3429
3475
  return value !=
3430
 
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3476
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3431
3477
}
3432
3478
 
3433
3479
 
3464
3510
    The function saves in ref the pointer to the item or to a newly created
3465
3511
    item that is considered as a replacement for the original one.
3466
3512
 
3467
 
  @param thd     reference to the global context of the query thread
 
3513
  @param session     reference to the global context of the query thread
3468
3514
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3469
3515
                 item is to be assigned
3470
3516
 
3485
3531
*/
3486
3532
 
3487
3533
bool
3488
 
Item_func_in::fix_fields(THD *thd, Item **ref)
 
3534
Item_func_in::fix_fields(Session *session, Item **ref)
3489
3535
{
3490
3536
  Item **arg, **arg_end;
3491
3537
 
3492
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
3538
  if (Item_func_opt_neg::fix_fields(session, ref))
3493
3539
    return 1;
3494
3540
 
3495
3541
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3517
3563
{
3518
3564
  Item **arg, **arg_end;
3519
3565
  bool const_itm= 1;
3520
 
  THD *thd= current_thd;
 
3566
  Session *session= current_session;
3521
3567
  bool datetime_found= false;
3522
3568
  /* true <=> arguments values will be compared as DATETIMEs. */
3523
3569
  bool compare_as_datetime= false;
3528
3574
  left_result_type= args[0]->result_type();
3529
3575
  if (!(found_types= collect_cmp_types(args, arg_count)))
3530
3576
    return;
3531
 
  
 
3577
 
3532
3578
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3533
3579
  {
3534
3580
    if (!arg[0]->const_item())
3548
3594
 
3549
3595
  if (type_cnt == 1)
3550
3596
  {
3551
 
    if (cmp_type == STRING_RESULT && 
 
3597
    if (cmp_type == STRING_RESULT &&
3552
3598
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3553
3599
      return;
3554
3600
    arg_types_compatible= true;
3650
3696
      /*
3651
3697
        IN must compare INT columns and constants as int values (the same
3652
3698
        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 
 
3699
        So we must check here if the column on the left and all the constant
 
3700
        values on the right can be compared as integers and adjust the
3655
3701
        comparison type accordingly.
3656
 
      */  
 
3702
      */
3657
3703
      if (args[0]->real_item()->type() == FIELD_ITEM &&
3658
 
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
 
3704
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3659
3705
          cmp_type != INT_RESULT)
3660
3706
      {
3661
3707
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3664
3710
          bool all_converted= true;
3665
3711
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3666
3712
          {
3667
 
            if (!convert_constant_item (thd, field_item, &arg[0]))
 
3713
            if (!convert_constant_item (session, field_item, &arg[0]))
3668
3714
              all_converted= false;
3669
3715
          }
3670
3716
          if (all_converted)
3673
3719
      }
3674
3720
      switch (cmp_type) {
3675
3721
      case STRING_RESULT:
3676
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
 
3722
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3677
3723
                            cmp_collation.collation);
3678
3724
        break;
3679
3725
      case INT_RESULT:
3698
3744
        return;
3699
3745
      }
3700
3746
    }
3701
 
    if (array && !(thd->is_fatal_error))                // If not EOM
 
3747
    if (array && !(session->is_fatal_error))            // If not EOM
3702
3748
    {
3703
3749
      uint32_t j=0;
3704
3750
      for (uint32_t i=1 ; i < arg_count ; i++)
3850
3896
  return (int64_t) (arg1 & arg2);
3851
3897
}
3852
3898
 
3853
 
Item_cond::Item_cond(THD *thd, Item_cond *item)
3854
 
  :Item_bool_func(thd, item),
 
3899
Item_cond::Item_cond(Session *session, Item_cond *item)
 
3900
  :Item_bool_func(session, item),
3855
3901
   abort_on_null(item->abort_on_null),
3856
3902
   and_tables_cache(item->and_tables_cache)
3857
3903
{
3861
3907
}
3862
3908
 
3863
3909
 
3864
 
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
 
3910
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3865
3911
{
3866
3912
  List_iterator_fast<Item> li(item->list);
3867
3913
  while (Item *it= li++)
3868
 
    list.push_back(it->copy_andor_structure(thd));
 
3914
    list.push_back(it->copy_andor_structure(session));
3869
3915
}
3870
3916
 
3871
3917
 
3872
3918
bool
3873
 
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
 
3919
Item_cond::fix_fields(Session *session, Item **)
3874
3920
{
3875
3921
  assert(fixed == 0);
3876
3922
  List_iterator<Item> li(list);
3877
3923
  Item *item;
3878
 
  void *orig_thd_marker= thd->thd_marker;
 
3924
  void *orig_session_marker= session->session_marker;
3879
3925
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3880
3926
  not_null_tables_cache= used_tables_cache= 0;
3881
3927
  const_item_cache= 1;
3882
3928
 
3883
3929
  if (functype() == COND_OR_FUNC)
3884
 
    thd->thd_marker= 0;
 
3930
    session->session_marker= 0;
3885
3931
  /*
3886
3932
    and_table_cache is the value that Item_cond_or() returns for
3887
3933
    not_null_tables()
3888
3934
  */
3889
3935
  and_tables_cache= ~(table_map) 0;
3890
3936
 
3891
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
3937
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3892
3938
    return true;                                // Fatal error flag is set!
3893
3939
  /*
3894
3940
    The following optimization reduces the depth of an AND-OR tree.
3921
3967
 
3922
3968
    // item can be substituted in fix_fields
3923
3969
    if ((!item->fixed &&
3924
 
         item->fix_fields(thd, li.ref())) ||
 
3970
         item->fix_fields(session, li.ref())) ||
3925
3971
        (item= *li.ref())->check_cols(1))
3926
3972
      return true; /* purecov: inspected */
3927
3973
    used_tables_cache|=     item->used_tables();
3933
3979
      not_null_tables_cache|= tmp_table_map;
3934
3980
      and_tables_cache&= tmp_table_map;
3935
3981
      const_item_cache= false;
3936
 
    }  
 
3982
    }
3937
3983
    with_sum_func=          with_sum_func || item->with_sum_func;
3938
3984
    with_subselect|=        item->with_subselect;
3939
3985
    if (item->maybe_null)
3940
3986
      maybe_null=1;
3941
3987
  }
3942
 
  thd->lex->current_select->cond_count+= list.elements;
3943
 
  thd->thd_marker= orig_thd_marker;
 
3988
  session->lex->current_select->cond_count+= list.elements;
 
3989
  session->session_marker= orig_session_marker;
3944
3990
  fix_length_and_dec();
3945
3991
  fixed= 1;
3946
3992
  return false;
3947
3993
}
3948
3994
 
3949
3995
 
3950
 
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
 
3996
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **)
3951
3997
{
3952
3998
  List_iterator<Item> li(list);
3953
3999
  Item *item;
3974
4020
      not_null_tables_cache|= tmp_table_map;
3975
4021
      and_tables_cache&= tmp_table_map;
3976
4022
      const_item_cache= false;
3977
 
    }  
 
4023
    }
3978
4024
  }
3979
4025
}
3980
4026
 
3992
4038
 
3993
4039
/**
3994
4040
  Transform an Item_cond object with a transformer callback function.
3995
 
  
 
4041
 
3996
4042
    The function recursively applies the transform method to each
3997
4043
     member item of the condition list.
3998
4044
    If the call of the method for a member item returns a new item
3999
4045
    the old item is substituted for a new one.
4000
4046
    After this the transformer is applied to the root node
4001
 
    of the Item_cond object. 
4002
 
     
 
4047
    of the Item_cond object.
 
4048
 
4003
4049
  @param transformer   the transformer callback function to be applied to
4004
4050
                       the nodes of the tree of the object
4005
4051
  @param arg           parameter to be passed to the transformer
4006
4052
 
4007
4053
  @return
4008
 
    Item returned as the result of transformation of the root node 
 
4054
    Item returned as the result of transformation of the root node
4009
4055
*/
4010
4056
 
4011
4057
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4019
4065
      return 0;
4020
4066
 
4021
4067
    /*
4022
 
      THD::change_item_tree() should be called only if the tree was
 
4068
      Session::change_item_tree() should be called only if the tree was
4023
4069
      really transformed, i.e. when a new item has been created.
4024
4070
      Otherwise we'll be allocating a lot of unnecessary memory for
4025
4071
      change records at each execution.
4026
4072
    */
4027
4073
    if (new_item != item)
4028
 
      current_thd->change_item_tree(li.ref(), new_item);
 
4074
      current_session->change_item_tree(li.ref(), new_item);
4029
4075
  }
4030
4076
  return Item_func::transform(transformer, arg);
4031
4077
}
4034
4080
/**
4035
4081
  Compile Item_cond object with a processor and a transformer
4036
4082
  callback functions.
4037
 
  
 
4083
 
4038
4084
    First the function applies the analyzer to the root node of
4039
4085
    the Item_func object. Then if the analyzer succeeeds (returns true)
4040
4086
    the function recursively applies the compile method to member
4042
4088
    If the call of the method for a member item returns a new item
4043
4089
    the old item is substituted for a new one.
4044
4090
    After this the transformer is applied to the root node
4045
 
    of the Item_cond object. 
4046
 
     
 
4091
    of the Item_cond object.
 
4092
 
4047
4093
  @param analyzer      the analyzer callback function to be applied to the
4048
4094
                       nodes of the tree of the object
4049
4095
  @param[in,out] arg_p parameter to be passed to the analyzer
4052
4098
  @param arg_t         parameter to be passed to the transformer
4053
4099
 
4054
4100
  @return
4055
 
    Item returned as the result of transformation of the root node 
 
4101
    Item returned as the result of transformation of the root node
4056
4102
*/
4057
4103
 
4058
4104
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4060
4106
{
4061
4107
  if (!(this->*analyzer)(arg_p))
4062
4108
    return 0;
4063
 
  
 
4109
 
4064
4110
  List_iterator<Item> li(list);
4065
4111
  Item *item;
4066
4112
  while ((item= li++))
4067
4113
  {
4068
 
    /* 
 
4114
    /*
4069
4115
      The same parameter value of arg_p must be passed
4070
4116
      to analyze any argument of the condition formula.
4071
 
    */   
 
4117
    */
4072
4118
    unsigned char *arg_v= *arg_p;
4073
4119
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4074
4120
    if (new_item && new_item != item)
4109
4155
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4110
4156
  sql_select.cc)
4111
4157
 
4112
 
  @param thd                    Thread handler
 
4158
  @param session                        Thread handler
4113
4159
  @param ref_pointer_array      Pointer to array of reference fields
4114
4160
  @param fields         All fields in select
4115
4161
 
4118
4164
    that have or refer (HAVING) to a SUM expression.
4119
4165
*/
4120
4166
 
4121
 
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
 
4167
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4122
4168
                               List<Item> &fields)
4123
4169
{
4124
4170
  List_iterator<Item> li(list);
4125
4171
  Item *item;
4126
4172
  while ((item= li++))
4127
 
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
 
4173
    item->split_sum_func(session, ref_pointer_array, fields, li.ref(), true);
4128
4174
}
4129
4175
 
4130
4176
 
4169
4215
}
4170
4216
 
4171
4217
 
4172
 
void Item_cond::neg_arguments(THD *thd)
 
4218
void Item_cond::neg_arguments(Session *session)
4173
4219
{
4174
4220
  List_iterator<Item> li(list);
4175
4221
  Item *item;
4176
4222
  while ((item= li++))          /* Apply not transformation to the arguments */
4177
4223
  {
4178
 
    Item *new_item= item->neg_transformer(thd);
 
4224
    Item *new_item= item->neg_transformer(session);
4179
4225
    if (!new_item)
4180
4226
    {
4181
4227
      if (!(new_item= new Item_func_not(item)))
4399
4445
}
4400
4446
 
4401
4447
 
4402
 
bool Item_func_like::fix_fields(THD *thd, Item **ref)
 
4448
bool Item_func_like::fix_fields(Session *session, Item **ref)
4403
4449
{
4404
4450
  assert(fixed == 0);
4405
 
  if (Item_bool_func2::fix_fields(thd, ref) ||
4406
 
      escape_item->fix_fields(thd, &escape_item))
 
4451
  if (Item_bool_func2::fix_fields(session, ref) ||
 
4452
      escape_item->fix_fields(session, &escape_item))
4407
4453
    return true;
4408
4454
 
4409
4455
  if (!escape_item->const_during_execution())
4411
4457
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4412
4458
    return true;
4413
4459
  }
4414
 
  
 
4460
 
4415
4461
  if (escape_item->const_item())
4416
4462
  {
4417
4463
    /* If we are on execution stage */
4464
4510
      We could also do boyer-more for non-const items, but as we would have to
4465
4511
      recompute the tables for each row it's not worth it.
4466
4512
    */
4467
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation)) 
 
4513
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4468
4514
    {
4469
4515
      String* res2 = args[1]->val_str(&tmp_value2);
4470
4516
      if (!res2)
4471
4517
        return false;                           // Null argument
4472
 
      
 
4518
 
4473
4519
      const size_t len   = res2->length();
4474
4520
      const char*  first = res2->ptr();
4475
4521
      const char*  last  = first + len - 1;
4477
4523
        len must be > 2 ('%pattern%')
4478
4524
        heuristic: only do TurboBM for pattern_len > 2
4479
4525
      */
4480
 
      
 
4526
 
4481
4527
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4482
4528
          *first == wild_many &&
4483
4529
          *last  == wild_many)
4490
4536
      {
4491
4537
        pattern     = first + 1;
4492
4538
        pattern_len = (int) len - 2;
4493
 
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
 
4539
        int *suff = (int*) session->alloc((int) (sizeof(int)*
4494
4540
                                      ((pattern_len + 1)*2+
4495
4541
                                      alphabet_size)));
4496
4542
        bmGs      = suff + pattern_len + 1;
4750
4796
  assert(fixed == 1);
4751
4797
  List_iterator<Item> li(list);
4752
4798
  Item *item;
4753
 
  int result=0; 
 
4799
  int result=0;
4754
4800
  null_value=0;
4755
4801
  while ((item=li++))
4756
4802
  {
4783
4829
       IS NOT NULL(a)     -> IS NULL(a)
4784
4830
    @endverbatim
4785
4831
 
4786
 
  @param thd            thread handler
 
4832
  @param session                thread handler
4787
4833
 
4788
4834
  @return
4789
4835
    New item or
4790
4836
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4791
4837
*/
4792
4838
 
4793
 
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
 
4839
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
4794
4840
{
4795
4841
  return args[0];
4796
4842
}
4797
4843
 
4798
4844
 
4799
 
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
 
4845
Item *Item_bool_rowready_func2::neg_transformer(Session *)
4800
4846
{
4801
4847
  Item *item= negated_item();
4802
4848
  return item;
4806
4852
/**
4807
4853
  a IS NULL  ->  a IS NOT NULL.
4808
4854
*/
4809
 
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
 
4855
Item *Item_func_isnull::neg_transformer(Session *)
4810
4856
{
4811
4857
  Item *item= new Item_func_isnotnull(args[0]);
4812
4858
  return item;
4816
4862
/**
4817
4863
  a IS NOT NULL  ->  a IS NULL.
4818
4864
*/
4819
 
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
 
4865
Item *Item_func_isnotnull::neg_transformer(Session *)
4820
4866
{
4821
4867
  Item *item= new Item_func_isnull(args[0]);
4822
4868
  return item;
4823
4869
}
4824
4870
 
4825
4871
 
4826
 
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
 
4872
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
4827
4873
                                        /* NOT a OR NOT b OR ... */
4828
4874
{
4829
 
  neg_arguments(thd);
 
4875
  neg_arguments(session);
4830
4876
  Item *item= new Item_cond_or(list);
4831
4877
  return item;
4832
4878
}
4833
4879
 
4834
4880
 
4835
 
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
 
4881
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
4836
4882
                                        /* NOT a AND NOT b AND ... */
4837
4883
{
4838
 
  neg_arguments(thd);
 
4884
  neg_arguments(session);
4839
4885
  Item *item= new Item_cond_and(list);
4840
4886
  return item;
4841
4887
}
4842
4888
 
4843
4889
 
4844
 
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
 
4890
Item *Item_func_nop_all::neg_transformer(Session *)
4845
4891
{
4846
4892
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4847
4893
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4852
4898
  return new_item;
4853
4899
}
4854
4900
 
4855
 
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
 
4901
Item *Item_func_not_all::neg_transformer(Session *)
4856
4902
{
4857
4903
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4858
4904
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4975
5021
  @retval
4976
5022
    1       if nultiple equality contains a reference to field
4977
5023
  @retval
4978
 
    0       otherwise    
 
5024
    0       otherwise
4979
5025
*/
4980
5026
 
4981
5027
bool Item_equal::contains(Field *field)
4993
5039
 
4994
5040
/**
4995
5041
  Join members of another Item_equal object.
4996
 
  
 
5042
 
4997
5043
    The function actually merges two multiple equalities.
4998
5044
    After this operation the Item_equal object additionally contains
4999
5045
    the field items of another item of the type Item_equal.
5000
5046
    If the optional constant items are not equal the cond_false flag is
5001
 
    set to 1.  
 
5047
    set to 1.
5002
5048
  @param item    multiple equality whose members are to be joined
5003
5049
*/
5004
5050
 
5008
5054
  Item *c= item->const_item;
5009
5055
  if (c)
5010
5056
  {
5011
 
    /* 
5012
 
      The flag cond_false will be set to 1 after this, if 
5013
 
      the multiple equality already contains a constant and its 
 
5057
    /*
 
5058
      The flag cond_false will be set to 1 after this, if
 
5059
      the multiple equality already contains a constant and its
5014
5060
      value is  not equal to the value of c.
5015
5061
    */
5016
5062
    add(c);
5017
5063
  }
5018
5064
  cond_false|= item->cond_false;
5019
 
 
5065
}
5020
5066
 
5021
5067
 
5022
5068
/**
5092
5138
  }
5093
5139
}
5094
5140
 
5095
 
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
 
5141
bool Item_equal::fix_fields(Session *, Item **)
5096
5142
{
5097
5143
  List_iterator_fast<Item_field> li(fields);
5098
5144
  Item *item;
5179
5225
      return 0;
5180
5226
 
5181
5227
    /*
5182
 
      THD::change_item_tree() should be called only if the tree was
 
5228
      Session::change_item_tree() should be called only if the tree was
5183
5229
      really transformed, i.e. when a new item has been created.
5184
5230
      Otherwise we'll be allocating a lot of unnecessary memory for
5185
5231
      change records at each execution.
5186
5232
    */
5187
5233
    if (new_item != item)
5188
 
      current_thd->change_item_tree((Item **) it.ref(), new_item);
 
5234
      current_session->change_item_tree((Item **) it.ref(), new_item);
5189
5235
  }
5190
5236
  return Item_func::transform(transformer, arg);
5191
5237
}