~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_cmpfunc.cc

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

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
 
#include <drizzled/error.h>
27
 
#include CMATH_H
28
 
 
29
 
#if defined(CMATH_NAMESPACE)
30
 
using namespace CMATH_NAMESPACE;
31
 
#endif
32
 
 
33
 
static bool convert_constant_item(Session *, Item_field *, Item **);
 
26
 
 
27
static bool convert_constant_item(THD *, Item_field *, Item **);
34
28
 
35
29
static Item_result item_store_type(Item_result a, Item *item,
36
30
                                   bool unsigned_flag)
48
42
    return INT_RESULT;
49
43
}
50
44
 
51
 
static void agg_result_type(Item_result *type, Item **items, uint32_t nitems)
 
45
static void agg_result_type(Item_result *type, Item **items, uint nitems)
52
46
{
53
47
  Item **item, **item_end;
54
48
  bool unsigned_flag= 0;
96
90
 
97
91
static int cmp_row_type(Item* item1, Item* item2)
98
92
{
99
 
  uint32_t n= item1->cols();
 
93
  uint n= item1->cols();
100
94
  if (item2->check_cols(n))
101
95
    return 1;
102
 
  for (uint32_t i=0; i<n; i++)
 
96
  for (uint i=0; i<n; i++)
103
97
  {
104
98
    if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
105
99
        (item1->element_index(i)->result_type() == ROW_RESULT &&
133
127
    0  otherwise
134
128
*/
135
129
 
136
 
static int agg_cmp_type(Item_result *type, Item **items, uint32_t nitems)
 
130
static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
137
131
{
138
 
  uint32_t i;
 
132
  uint i;
139
133
  type[0]= items[0]->result_type();
140
134
  for (i= 1 ; i < nitems ; i++)
141
135
  {
172
166
  @return aggregated field type.
173
167
*/
174
168
 
175
 
enum_field_types agg_field_type(Item **items, uint32_t nitems)
 
169
enum_field_types agg_field_type(Item **items, uint nitems)
176
170
{
177
 
  uint32_t i;
 
171
  uint i;
178
172
  if (!nitems || items[0]->result_type() == ROW_RESULT )
179
173
    return (enum_field_types)-1;
180
174
  enum_field_types res= items[0]->field_type();
200
194
    Bitmap of collected types - otherwise
201
195
*/
202
196
 
203
 
static uint32_t collect_cmp_types(Item **items, uint32_t nitems)
 
197
static uint collect_cmp_types(Item **items, uint nitems)
204
198
{
205
 
  uint32_t i;
206
 
  uint32_t found_types;
 
199
  uint i;
 
200
  uint found_types;
207
201
  Item_result left_result= items[0]->result_type();
208
202
  assert(nitems > 1);
209
203
  found_types= 0;
367
361
    also when comparing bigint to strings (in which case strings
368
362
    are converted to bigints).
369
363
 
370
 
  @param  session             thread handle
 
364
  @param  thd             thread handle
371
365
  @param  field_item      item will be converted using the type of this field
372
366
  @param[in,out] item     reference to the item to convert
373
367
 
384
378
    1  Item was replaced with an integer version of the item
385
379
*/
386
380
 
387
 
static bool convert_constant_item(Session *session, Item_field *field_item,
 
381
static bool convert_constant_item(THD *thd, Item_field *field_item,
388
382
                                  Item **item)
389
383
{
390
384
  Field *field= field_item->field;
392
386
 
393
387
  if (!(*item)->with_subselect && (*item)->const_item())
394
388
  {
395
 
    ulong orig_sql_mode= session->variables.sql_mode;
396
 
    enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
 
389
    ulong orig_sql_mode= thd->variables.sql_mode;
 
390
    enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
397
391
    uint64_t orig_field_val= 0; /* original field value if valid */
398
392
 
399
393
    /* For comparison purposes allow invalid dates like 2000-01-32 */
400
 
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
 
394
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
401
395
                             MODE_INVALID_DATES;
402
 
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
396
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
403
397
 
404
398
    /*
405
399
      Store the value of the field if it references an outer field because
412
406
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
413
407
                                       test(field->flags & UNSIGNED_FLAG));
414
408
      if (tmp)
415
 
        session->change_item_tree(item, tmp);
 
409
        thd->change_item_tree(item, tmp);
416
410
      result= 1;                                        // Item was replaced
417
411
    }
418
412
    /* Restore the original field value. */
422
416
      /* orig_field_val must be a valid value that can be restored back. */
423
417
      assert(!result);
424
418
    }
425
 
    session->variables.sql_mode= orig_sql_mode;
426
 
    session->count_cuted_fields= orig_count_cuted_fields;
 
419
    thd->variables.sql_mode= orig_sql_mode;
 
420
    thd->count_cuted_fields= orig_count_cuted_fields;
427
421
  }
428
422
  return result;
429
423
}
432
426
void Item_bool_func2::fix_length_and_dec()
433
427
{
434
428
  max_length= 1;                                     // Function returns 0 or 1
435
 
  Session *session;
 
429
  THD *thd;
436
430
 
437
431
  /*
438
432
    As some compare functions are generated after sql_yacc,
470
464
    return;
471
465
  }
472
466
 
473
 
  session= current_session;
 
467
  thd= current_thd;
474
468
 
475
469
  if (args[0]->real_item()->type() == FIELD_ITEM)
476
470
  {
478
472
    if (field_item->field->can_be_compared_as_int64_t() &&
479
473
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
480
474
    {
481
 
      if (convert_constant_item(session, field_item, &args[1]))
 
475
      if (convert_constant_item(thd, field_item, &args[1]))
482
476
      {
483
477
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
484
478
                         INT_RESULT);           // Works for all types.
494
488
          !(field_item->is_datetime() &&
495
489
            args[0]->result_type() == STRING_RESULT))
496
490
      {
497
 
        if (convert_constant_item(session, field_item, &args[0]))
 
491
        if (convert_constant_item(thd, field_item, &args[0]))
498
492
        {
499
493
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
500
494
                           INT_RESULT); // Works for all types.
516
510
  switch (type) {
517
511
  case ROW_RESULT:
518
512
  {
519
 
    uint32_t n= (*a)->cols();
 
513
    uint n= (*a)->cols();
520
514
    if (n != (*b)->cols())
521
515
    {
522
516
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
525
519
    }
526
520
    if (!(comparators= new Arg_comparator[n]))
527
521
      return 1;
528
 
    for (uint32_t i=0; i < n; i++)
 
522
    for (uint i=0; i < n; i++)
529
523
    {
530
524
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
531
525
      {
567
561
        which would be transformed to:
568
562
        WHERE col= 'j'
569
563
      */
570
 
      (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
571
 
      (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
 
564
      (*a)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
 
565
      (*b)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
572
566
    }
573
567
    break;
574
568
  }
596
590
  {
597
591
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
598
592
    {
599
 
      precision= 5 / log_10[cmax((*a)->decimals, (*b)->decimals) + 1];
 
593
      precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
600
594
      if (func == &Arg_comparator::compare_real)
601
595
        func= &Arg_comparator::compare_real_fixed;
602
596
      else if (func == &Arg_comparator::compare_e_real)
614
608
/**
615
609
  @brief Convert date provided in a string to the int representation.
616
610
 
617
 
  @param[in]   session        thread handle
 
611
  @param[in]   thd        thread handle
618
612
  @param[in]   str        a string to convert
619
613
  @param[in]   warn_type  type of the timestamp for issuing the warning
620
614
  @param[in]   warn_name  field name for issuing the warning
634
628
*/
635
629
 
636
630
static uint64_t
637
 
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
 
631
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
638
632
                  char *warn_name, bool *error_arg)
639
633
{
640
634
  uint64_t value= 0;
641
635
  int error;
642
636
  DRIZZLE_TIME l_time;
643
 
  enum enum_drizzle_timestamp_type ret;
 
637
  enum_drizzle_timestamp_type ret;
644
638
 
645
639
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
646
640
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
647
 
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
641
                        (thd->variables.sql_mode & MODE_NO_ZERO_DATE)),
648
642
                       &error);
649
643
 
650
644
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
663
657
  }
664
658
 
665
659
  if (error > 0)
666
 
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
660
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
667
661
                                 str->ptr(), str->length(),
668
662
                                 warn_type, warn_name);
669
663
 
740
734
        (str_arg->type() != Item::FUNC_ITEM ||
741
735
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
742
736
    {
743
 
      Session *session= current_session;
 
737
      THD *thd= current_thd;
744
738
      uint64_t value;
745
739
      bool error;
746
740
      String tmp, *str_val= 0;
747
 
      enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
 
741
      timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
748
742
                              DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
749
743
 
750
744
      str_val= str_arg->val_str(&tmp);
751
745
      if (str_arg->null_value)
752
746
        return CMP_DATE_DFLT;
753
 
      value= get_date_from_str(session, str_val, t_type, date_arg->name, &error);
 
747
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
754
748
      if (error)
755
749
        return CMP_DATE_DFLT;
756
750
      if (const_value)
766
760
 
767
761
  SYNOPSIS
768
762
    get_time_value()
769
 
    session                 thread handle
 
763
    thd                 thread handle
770
764
    item_arg   [in/out] item to retrieve TIME value from
771
765
    cache_arg  [in/out] pointer to place to store the cache item to
772
766
    warn_item  [in]     unused
787
781
*/
788
782
 
789
783
uint64_t
790
 
get_time_value(Session *session __attribute__((unused)),
 
784
get_time_value(THD *thd __attribute__((unused)),
791
785
               Item ***item_arg, Item **cache_arg,
792
786
               Item *warn_item __attribute__((unused)),
793
787
               bool *is_null)
835
829
 
836
830
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
837
831
  {
838
 
    session= current_session;
 
832
    thd= current_thd;
839
833
    owner= owner_arg;
840
834
    a_type= (*a)->field_type();
841
835
    b_type= (*b)->field_type();
869
863
           (*b)->field_type() == DRIZZLE_TYPE_TIME)
870
864
  {
871
865
    /* Compare TIME values as integers. */
872
 
    session= current_session;
 
866
    thd= current_thd;
873
867
    owner= owner_arg;
874
868
    a_cache= 0;
875
869
    b_cache= 0;
885
879
 
886
880
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
887
881
{
888
 
  session= current_session;
 
882
  thd= current_thd;
889
883
  /* A caller will handle null values by itself. */
890
884
  owner= NULL;
891
885
  a= a1;
905
899
 
906
900
  SYNOPSIS
907
901
    get_datetime_value()
908
 
    session                 thread handle
 
902
    thd                 thread handle
909
903
    item_arg   [in/out] item to retrieve DATETIME value from
910
904
    cache_arg  [in/out] pointer to place to store the caching item to
911
905
    warn_item  [in]     item for issuing the conversion warning
930
924
*/
931
925
 
932
926
uint64_t
933
 
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
 
927
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
934
928
                   Item *warn_item, bool *is_null)
935
929
{
936
930
  uint64_t value= 0;
969
963
  {
970
964
    bool error;
971
965
    enum_field_types f_type= warn_item->field_type();
972
 
    enum enum_drizzle_timestamp_type t_type= f_type ==
 
966
    timestamp_type t_type= f_type ==
973
967
      DRIZZLE_TYPE_NEWDATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
974
 
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
 
968
    value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
975
969
    /*
976
970
      If str did not contain a valid date according to the current
977
971
      SQL_MODE, get_date_from_str() has already thrown a warning,
1023
1017
  uint64_t a_value, b_value;
1024
1018
 
1025
1019
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1026
 
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
 
1020
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
1027
1021
  if (!is_nulls_eq && is_null)
1028
1022
  {
1029
1023
    if (owner)
1032
1026
  }
1033
1027
 
1034
1028
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1035
 
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
 
1029
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
1036
1030
  if (is_null)
1037
1031
  {
1038
1032
    if (owner)
1085
1079
    if ((res2= (*b)->val_str(&owner->tmp_value2)))
1086
1080
    {
1087
1081
      owner->null_value= 0;
1088
 
      uint32_t res1_length= res1->length();
1089
 
      uint32_t res2_length= res2->length();
1090
 
      int cmp= memcmp(res1->ptr(), res2->ptr(), cmin(res1_length,res2_length));
 
1082
      uint res1_length= res1->length();
 
1083
      uint res2_length= res2->length();
 
1084
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
1091
1085
      return cmp ? cmp : (int) (res1_length - res2_length);
1092
1086
    }
1093
1087
  }
1343
1337
  bool was_null= 0;
1344
1338
  (*a)->bring_value();
1345
1339
  (*b)->bring_value();
1346
 
  uint32_t n= (*a)->cols();
1347
 
  for (uint32_t i= 0; i<n; i++)
 
1340
  uint n= (*a)->cols();
 
1341
  for (uint i= 0; i<n; i++)
1348
1342
  {
1349
1343
    res= comparators[i].compare();
1350
1344
    if (owner->null_value)
1386
1380
{
1387
1381
  (*a)->bring_value();
1388
1382
  (*b)->bring_value();
1389
 
  uint32_t n= (*a)->cols();
1390
 
  for (uint32_t i= 0; i<n; i++)
 
1383
  uint n= (*a)->cols();
 
1384
  for (uint i= 0; i<n; i++)
1391
1385
  {
1392
1386
    if (!comparators[i].compare())
1393
1387
      return 0;
1449
1443
}
1450
1444
 
1451
1445
 
1452
 
bool Item_in_optimizer::fix_left(Session *session, Item **ref __attribute__((unused)))
 
1446
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
1453
1447
{
1454
 
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
 
1448
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
1455
1449
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1456
1450
    return 1;
1457
1451
 
1465
1459
  }
1466
1460
  else
1467
1461
  {
1468
 
    uint32_t n= cache->cols();
1469
 
    for (uint32_t i= 0; i < n; i++)
 
1462
    uint n= cache->cols();
 
1463
    for (uint i= 0; i < n; i++)
1470
1464
    {
1471
1465
      if (args[0]->element_index(i)->used_tables())
1472
1466
        ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
1483
1477
}
1484
1478
 
1485
1479
 
1486
 
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
 
1480
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1487
1481
{
1488
1482
  assert(fixed == 0);
1489
 
  if (fix_left(session, ref))
 
1483
  if (fix_left(thd, ref))
1490
1484
    return true;
1491
1485
  if (args[0]->maybe_null)
1492
1486
    maybe_null=1;
1493
1487
 
1494
 
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
 
1488
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
1495
1489
    return true;
1496
1490
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1497
1491
  if (args[0]->cols() != sub->engine->cols())
1553
1547
        }
1554
1548
        else
1555
1549
        {
1556
 
          uint32_t i;
1557
 
          uint32_t ncols= cache->cols();
 
1550
          uint i;
 
1551
          uint ncols= cache->cols();
1558
1552
          /*
1559
1553
            Turn off the predicates that are based on column compares for
1560
1554
            which the left part is currently NULL
1627
1621
    @retval NULL if an error occurred
1628
1622
*/
1629
1623
 
1630
 
Item *Item_in_optimizer::transform(Item_transformer transformer, unsigned char *argument)
 
1624
Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument)
1631
1625
{
1632
1626
  Item *new_item;
1633
1627
 
1638
1632
  if (!new_item)
1639
1633
    return 0;
1640
1634
  /*
1641
 
    Session::change_item_tree() should be called only if the tree was
 
1635
    THD::change_item_tree() should be called only if the tree was
1642
1636
    really transformed, i.e. when a new item has been created.
1643
1637
    Otherwise we'll be allocating a lot of unnecessary memory for
1644
1638
    change records at each execution.
1645
1639
  */
1646
1640
  if ((*args) != new_item)
1647
 
    current_session->change_item_tree(args, new_item);
 
1641
    current_thd->change_item_tree(args, new_item);
1648
1642
 
1649
1643
  /*
1650
1644
    Transform the right IN operand which should be an Item_in_subselect or a
1759
1753
    return 0;
1760
1754
  if (negated != ((Item_func_opt_neg *) item_func)->negated)
1761
1755
    return 0;
1762
 
  for (uint32_t i=0; i < arg_count ; i++)
 
1756
  for (uint i=0; i < arg_count ; i++)
1763
1757
    if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
1764
1758
      return 0;
1765
1759
  return 1;
1768
1762
 
1769
1763
void Item_func_interval::fix_length_and_dec()
1770
1764
{
1771
 
  uint32_t rows= row->cols();
 
1765
  uint rows= row->cols();
1772
1766
  
1773
1767
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1774
1768
                            DECIMAL_RESULT) ||
1778
1772
  {
1779
1773
    bool not_null_consts= true;
1780
1774
 
1781
 
    for (uint32_t i= 1; not_null_consts && i < rows; i++)
 
1775
    for (uint i= 1; not_null_consts && i < rows; i++)
1782
1776
    {
1783
1777
      Item *el= row->element_index(i);
1784
1778
      not_null_consts&= el->const_item() & !el->is_null();
1790
1784
    {
1791
1785
      if (use_decimal_comparison)
1792
1786
      {
1793
 
        for (uint32_t i= 1; i < rows; i++)
 
1787
        for (uint i= 1; i < rows; i++)
1794
1788
        {
1795
1789
          Item *el= row->element_index(i);
1796
1790
          interval_range *range= intervals + (i-1);
1815
1809
      }
1816
1810
      else
1817
1811
      {
1818
 
        for (uint32_t i= 1; i < rows; i++)
 
1812
        for (uint i= 1; i < rows; i++)
1819
1813
        {
1820
1814
          intervals[i-1].dbl= row->element_index(i)->val_real();
1821
1815
        }
1850
1844
  assert(fixed == 1);
1851
1845
  double value;
1852
1846
  my_decimal dec_buf, *dec= NULL;
1853
 
  uint32_t i;
 
1847
  uint i;
1854
1848
 
1855
1849
  if (use_decimal_comparison)
1856
1850
  {
1868
1862
 
1869
1863
  if (intervals)
1870
1864
  {                                     // Use binary search to find interval
1871
 
    uint32_t start,end;
 
1865
    uint start,end;
1872
1866
    start= 0;
1873
1867
    end=   row->cols()-2;
1874
1868
    while (start != end)
1875
1869
    {
1876
 
      uint32_t mid= (start + end + 1) / 2;
 
1870
      uint mid= (start + end + 1) / 2;
1877
1871
      interval_range *range= intervals + mid;
1878
1872
      bool cmp_result;
1879
1873
      /*
1932
1926
    The function saves in ref the pointer to the item or to a newly created
1933
1927
    item that is considered as a replacement for the original one.
1934
1928
 
1935
 
  @param session     reference to the global context of the query thread
 
1929
  @param thd     reference to the global context of the query thread
1936
1930
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1937
1931
                 item is to be assigned
1938
1932
 
1952
1946
    1   got error
1953
1947
*/
1954
1948
 
1955
 
bool Item_func_between::fix_fields(Session *session, Item **ref)
 
1949
bool Item_func_between::fix_fields(THD *thd, Item **ref)
1956
1950
{
1957
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
1951
  if (Item_func_opt_neg::fix_fields(thd, ref))
1958
1952
    return 1;
1959
1953
 
1960
 
  session->lex->current_select->between_count++;
 
1954
  thd->lex->current_select->between_count++;
1961
1955
 
1962
1956
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1963
1957
  if (pred_level && !negated)
1979
1973
  bool datetime_found= false;
1980
1974
  int time_items_found= 0;
1981
1975
  compare_as_dates= true;
1982
 
  Session *session= current_session;
 
1976
  THD *thd= current_thd;
1983
1977
 
1984
1978
  /*
1985
1979
    As some compare functions are generated after sql_yacc,
2026
2020
    cmp_type= INT_RESULT;
2027
2021
  }
2028
2022
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
2029
 
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
 
2023
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
2030
2024
  {
2031
2025
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2032
2026
    if (field_item->field->can_be_compared_as_int64_t())
2035
2029
        The following can't be recoded with || as convert_constant_item
2036
2030
        changes the argument
2037
2031
      */
2038
 
      if (convert_constant_item(session, field_item, &args[1]))
 
2032
      if (convert_constant_item(thd, field_item, &args[1]))
2039
2033
        cmp_type=INT_RESULT;                    // Works for all types.
2040
 
      if (convert_constant_item(session, field_item, &args[2]))
 
2034
      if (convert_constant_item(thd, field_item, &args[2]))
2041
2035
        cmp_type=INT_RESULT;                    // Works for all types.
2042
2036
    }
2043
2037
  }
2172
2166
{
2173
2167
  agg_result_type(&hybrid_type, args, 2);
2174
2168
  maybe_null=args[1]->maybe_null;
2175
 
  decimals= cmax(args[0]->decimals, args[1]->decimals);
 
2169
  decimals= max(args[0]->decimals, args[1]->decimals);
2176
2170
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2177
2171
 
2178
2172
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
2183
2177
    int len1= args[1]->max_length - args[1]->decimals
2184
2178
      - (args[1]->unsigned_flag ? 0 : 1);
2185
2179
 
2186
 
    max_length= cmax(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
 
2180
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2187
2181
  }
2188
2182
  else
2189
 
    max_length= cmax(args[0]->max_length, args[1]->max_length);
 
2183
    max_length= max(args[0]->max_length, args[1]->max_length);
2190
2184
 
2191
2185
  switch (hybrid_type) {
2192
2186
  case STRING_RESULT:
2206
2200
}
2207
2201
 
2208
2202
 
2209
 
uint32_t Item_func_ifnull::decimal_precision() const
 
2203
uint Item_func_ifnull::decimal_precision() const
2210
2204
{
2211
 
  int max_int_part=cmax(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2212
 
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
2205
  int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
 
2206
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2213
2207
}
2214
2208
 
2215
2209
 
2299
2293
    The function saves in ref the pointer to the item or to a newly created
2300
2294
    item that is considered as a replacement for the original one.
2301
2295
 
2302
 
  @param session     reference to the global context of the query thread
 
2296
  @param thd     reference to the global context of the query thread
2303
2297
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2304
2298
                 item is to be assigned
2305
2299
 
2318
2312
*/
2319
2313
 
2320
2314
bool
2321
 
Item_func_if::fix_fields(Session *session, Item **ref)
 
2315
Item_func_if::fix_fields(THD *thd, Item **ref)
2322
2316
{
2323
2317
  assert(fixed == 0);
2324
2318
  args[0]->top_level_item();
2325
2319
 
2326
 
  if (Item_func::fix_fields(session, ref))
 
2320
  if (Item_func::fix_fields(thd, ref))
2327
2321
    return 1;
2328
2322
 
2329
2323
  not_null_tables_cache= (args[1]->not_null_tables() &
2337
2331
Item_func_if::fix_length_and_dec()
2338
2332
{
2339
2333
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
2340
 
  decimals= cmax(args[1]->decimals, args[2]->decimals);
 
2334
  decimals= max(args[1]->decimals, args[2]->decimals);
2341
2335
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2342
2336
 
2343
2337
  enum Item_result arg1_type=args[1]->result_type();
2381
2375
    int len2= args[2]->max_length - args[2]->decimals
2382
2376
      - (args[2]->unsigned_flag ? 0 : 1);
2383
2377
 
2384
 
    max_length=cmax(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2378
    max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2385
2379
  }
2386
2380
  else
2387
 
    max_length= cmax(args[1]->max_length, args[2]->max_length);
 
2381
    max_length= max(args[1]->max_length, args[2]->max_length);
2388
2382
}
2389
2383
 
2390
2384
 
2391
 
uint32_t Item_func_if::decimal_precision() const
 
2385
uint Item_func_if::decimal_precision() const
2392
2386
{
2393
 
  int precision=(cmax(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
 
2387
  int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2394
2388
                 decimals);
2395
 
  return cmin(precision, DECIMAL_MAX_PRECISION);
 
2389
  return min(precision, DECIMAL_MAX_PRECISION);
2396
2390
}
2397
2391
 
2398
2392
 
2560
2554
 
2561
2555
Item *Item_func_case::find_item(String *str __attribute__((unused)))
2562
2556
{
2563
 
  uint32_t value_added_map= 0;
 
2557
  uint value_added_map= 0;
2564
2558
 
2565
2559
  if (first_expr_num == -1)
2566
2560
  {
2567
 
    for (uint32_t i=0 ; i < ncases ; i+=2)
 
2561
    for (uint i=0 ; i < ncases ; i+=2)
2568
2562
    {
2569
2563
      // No expression between CASE and the first WHEN
2570
2564
      if (args[i]->val_bool())
2575
2569
  else
2576
2570
  {
2577
2571
    /* Compare every WHEN argument with it and return the first match */
2578
 
    for (uint32_t i=0 ; i < ncases ; i+=2)
 
2572
    for (uint i=0 ; i < ncases ; i+=2)
2579
2573
    {
2580
2574
      cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2581
2575
      assert(cmp_type != ROW_RESULT);
2671
2665
}
2672
2666
 
2673
2667
 
2674
 
bool Item_func_case::fix_fields(Session *session, Item **ref)
 
2668
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2675
2669
{
2676
2670
  /*
2677
2671
    buff should match stack usage from
2678
2672
    Item_func_case::val_int() -> Item_func_case::find_item()
2679
2673
  */
2680
 
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(int64_t)*2];
2681
 
  bool res= Item_func::fix_fields(session, ref);
 
2674
  uchar 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);
2682
2676
  /*
2683
2677
    Call check_stack_overrun after fix_fields to be sure that stack variable
2684
2678
    is not optimized away
2685
2679
  */
2686
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
2680
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2687
2681
    return true;                                // Fatal error flag is set!
2688
2682
  return res;
2689
2683
}
2699
2693
 
2700
2694
void Item_func_case::agg_num_lengths(Item *arg)
2701
2695
{
2702
 
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
 
2696
  uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2703
2697
                                           arg->unsigned_flag) - arg->decimals;
2704
2698
  set_if_bigger(max_length, len); 
2705
2699
  set_if_bigger(decimals, arg->decimals);
2710
2704
void Item_func_case::fix_length_and_dec()
2711
2705
{
2712
2706
  Item **agg;
2713
 
  uint32_t nagg;
2714
 
  uint32_t found_types= 0;
 
2707
  uint nagg;
 
2708
  uint found_types= 0;
2715
2709
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2716
2710
    return;
2717
2711
  
2738
2732
  */
2739
2733
  if (first_expr_num != -1)
2740
2734
  {
2741
 
    uint32_t i;
 
2735
    uint i;
2742
2736
    agg[0]= args[first_expr_num];
2743
2737
    left_result_type= agg[0]->result_type();
2744
2738
 
2772
2766
  unsigned_flag= true;
2773
2767
  if (cached_result_type == STRING_RESULT)
2774
2768
  {
2775
 
    for (uint32_t i= 0; i < ncases; i+= 2)
 
2769
    for (uint i= 0; i < ncases; i+= 2)
2776
2770
      agg_str_lengths(args[i + 1]);
2777
2771
    if (else_expr_num != -1)
2778
2772
      agg_str_lengths(args[else_expr_num]);
2779
2773
  }
2780
2774
  else
2781
2775
  {
2782
 
    for (uint32_t i= 0; i < ncases; i+= 2)
 
2776
    for (uint i= 0; i < ncases; i+= 2)
2783
2777
      agg_num_lengths(args[i + 1]);
2784
2778
    if (else_expr_num != -1) 
2785
2779
      agg_num_lengths(args[else_expr_num]);
2789
2783
}
2790
2784
 
2791
2785
 
2792
 
uint32_t Item_func_case::decimal_precision() const
 
2786
uint Item_func_case::decimal_precision() const
2793
2787
{
2794
2788
  int max_int_part=0;
2795
 
  for (uint32_t i=0 ; i < ncases ; i+=2)
 
2789
  for (uint i=0 ; i < ncases ; i+=2)
2796
2790
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2797
2791
 
2798
2792
  if (else_expr_num != -1) 
2799
2793
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2800
 
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
2794
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2801
2795
}
2802
2796
 
2803
2797
 
2814
2808
    args[first_expr_num]->print(str, query_type);
2815
2809
    str->append(' ');
2816
2810
  }
2817
 
  for (uint32_t i=0 ; i < ncases ; i+=2)
 
2811
  for (uint i=0 ; i < ncases ; i+=2)
2818
2812
  {
2819
2813
    str->append(STRING_WITH_LEN("when "));
2820
2814
    args[i]->print(str, query_type);
2834
2828
 
2835
2829
void Item_func_case::cleanup()
2836
2830
{
2837
 
  uint32_t i;
 
2831
  uint i;
2838
2832
  Item_func::cleanup();
2839
2833
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2840
2834
  {
2853
2847
{
2854
2848
  assert(fixed == 1);
2855
2849
  null_value=0;
2856
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2850
  for (uint i=0 ; i < arg_count ; i++)
2857
2851
  {
2858
2852
    String *res;
2859
2853
    if ((res=args[i]->val_str(str)))
2867
2861
{
2868
2862
  assert(fixed == 1);
2869
2863
  null_value=0;
2870
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2864
  for (uint i=0 ; i < arg_count ; i++)
2871
2865
  {
2872
2866
    int64_t res=args[i]->val_int();
2873
2867
    if (!args[i]->null_value)
2881
2875
{
2882
2876
  assert(fixed == 1);
2883
2877
  null_value=0;
2884
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2878
  for (uint i=0 ; i < arg_count ; i++)
2885
2879
  {
2886
2880
    double res= args[i]->val_real();
2887
2881
    if (!args[i]->null_value)
2896
2890
{
2897
2891
  assert(fixed == 1);
2898
2892
  null_value= 0;
2899
 
  for (uint32_t i= 0; i < arg_count; i++)
 
2893
  for (uint i= 0; i < arg_count; i++)
2900
2894
  {
2901
2895
    my_decimal *res= args[i]->val_decimal(decimal_value);
2902
2896
    if (!args[i]->null_value)
3058
3052
 
3059
3053
int in_vector::find(Item *item)
3060
3054
{
3061
 
  unsigned char *result=get_value(item);
 
3055
  uchar *result=get_value(item);
3062
3056
  if (!result || !used_count)
3063
3057
    return 0;                           // Null value
3064
3058
 
3065
 
  uint32_t start,end;
 
3059
  uint start,end;
3066
3060
  start=0; end=used_count-1;
3067
3061
  while (start != end)
3068
3062
  {
3069
 
    uint32_t mid=(start+end+1)/2;
 
3063
    uint mid=(start+end+1)/2;
3070
3064
    int res;
3071
3065
    if ((res=(*compare)(collation, base+mid*size, result)) == 0)
3072
3066
      return 1;
3078
3072
  return (int) ((*compare)(collation, base+start*size, result) == 0);
3079
3073
}
3080
3074
 
3081
 
in_string::in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
 
3075
in_string::in_string(uint elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
3082
3076
  :in_vector(elements, sizeof(String), cmp_func, cs),
3083
3077
   tmp(buff, sizeof(buff), &my_charset_bin)
3084
3078
{}
3088
3082
  if (base)
3089
3083
  {
3090
3084
    // base was allocated with help of sql_alloc => following is OK
3091
 
    for (uint32_t i=0 ; i < count ; i++)
 
3085
    for (uint i=0 ; i < count ; i++)
3092
3086
      ((String*) base)[i].free();
3093
3087
  }
3094
3088
}
3095
3089
 
3096
 
void in_string::set(uint32_t pos,Item *item)
 
3090
void in_string::set(uint pos,Item *item)
3097
3091
{
3098
3092
  String *str=((String*) base)+pos;
3099
3093
  String *res=item->val_str(str);
3116
3110
}
3117
3111
 
3118
3112
 
3119
 
unsigned char *in_string::get_value(Item *item)
 
3113
uchar *in_string::get_value(Item *item)
3120
3114
{
3121
 
  return (unsigned char*) item->val_str(&tmp);
 
3115
  return (uchar*) item->val_str(&tmp);
3122
3116
}
3123
3117
 
3124
 
in_row::in_row(uint32_t elements, Item * item __attribute__((unused)))
 
3118
in_row::in_row(uint elements, Item * item __attribute__((unused)))
3125
3119
{
3126
3120
  base= (char*) new cmp_item_row[count= elements];
3127
3121
  size= sizeof(cmp_item_row);
3140
3134
    delete [] (cmp_item_row*) base;
3141
3135
}
3142
3136
 
3143
 
unsigned char *in_row::get_value(Item *item)
 
3137
uchar *in_row::get_value(Item *item)
3144
3138
{
3145
3139
  tmp.store_value(item);
3146
3140
  if (item->is_null())
3147
3141
    return 0;
3148
 
  return (unsigned char *)&tmp;
 
3142
  return (uchar *)&tmp;
3149
3143
}
3150
3144
 
3151
 
void in_row::set(uint32_t pos, Item *item)
 
3145
void in_row::set(uint pos, Item *item)
3152
3146
{
3153
3147
  ((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
3154
3148
  return;
3155
3149
}
3156
3150
 
3157
 
in_int64_t::in_int64_t(uint32_t elements)
 
3151
in_int64_t::in_int64_t(uint elements)
3158
3152
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3159
3153
{}
3160
3154
 
3161
 
void in_int64_t::set(uint32_t pos,Item *item)
 
3155
void in_int64_t::set(uint pos,Item *item)
3162
3156
{
3163
3157
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3164
3158
  
3166
3160
  buff->unsigned_flag= item->unsigned_flag;
3167
3161
}
3168
3162
 
3169
 
unsigned char *in_int64_t::get_value(Item *item)
 
3163
uchar *in_int64_t::get_value(Item *item)
3170
3164
{
3171
3165
  tmp.val= item->val_int();
3172
3166
  if (item->null_value)
3173
3167
    return 0;
3174
3168
  tmp.unsigned_flag= item->unsigned_flag;
3175
 
  return (unsigned char*) &tmp;
 
3169
  return (uchar*) &tmp;
3176
3170
}
3177
3171
 
3178
 
void in_datetime::set(uint32_t pos,Item *item)
 
3172
void in_datetime::set(uint pos,Item *item)
3179
3173
{
3180
3174
  Item **tmp_item= &item;
3181
3175
  bool is_null;
3182
3176
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3183
3177
 
3184
 
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3178
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3185
3179
  buff->unsigned_flag= 1L;
3186
3180
}
3187
3181
 
3188
 
unsigned char *in_datetime::get_value(Item *item)
 
3182
uchar *in_datetime::get_value(Item *item)
3189
3183
{
3190
3184
  bool is_null;
3191
3185
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3192
 
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
 
3186
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3193
3187
  if (item->null_value)
3194
3188
    return 0;
3195
3189
  tmp.unsigned_flag= 1L;
3196
 
  return (unsigned char*) &tmp;
 
3190
  return (uchar*) &tmp;
3197
3191
}
3198
3192
 
3199
 
in_double::in_double(uint32_t elements)
 
3193
in_double::in_double(uint elements)
3200
3194
  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
3201
3195
{}
3202
3196
 
3203
 
void in_double::set(uint32_t pos,Item *item)
 
3197
void in_double::set(uint pos,Item *item)
3204
3198
{
3205
3199
  ((double*) base)[pos]= item->val_real();
3206
3200
}
3207
3201
 
3208
 
unsigned char *in_double::get_value(Item *item)
 
3202
uchar *in_double::get_value(Item *item)
3209
3203
{
3210
3204
  tmp= item->val_real();
3211
3205
  if (item->null_value)
3212
3206
    return 0;                                   /* purecov: inspected */
3213
 
  return (unsigned char*) &tmp;
 
3207
  return (uchar*) &tmp;
3214
3208
}
3215
3209
 
3216
3210
 
3217
 
in_decimal::in_decimal(uint32_t elements)
 
3211
in_decimal::in_decimal(uint elements)
3218
3212
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3219
3213
{}
3220
3214
 
3221
3215
 
3222
 
void in_decimal::set(uint32_t pos, Item *item)
 
3216
void in_decimal::set(uint pos, Item *item)
3223
3217
{
3224
3218
  /* as far as 'item' is constant, we can store reference on my_decimal */
3225
3219
  my_decimal *dec= ((my_decimal *)base) + pos;
3232
3226
}
3233
3227
 
3234
3228
 
3235
 
unsigned char *in_decimal::get_value(Item *item)
 
3229
uchar *in_decimal::get_value(Item *item)
3236
3230
{
3237
3231
  my_decimal *result= item->val_decimal(&val);
3238
3232
  if (item->null_value)
3239
3233
    return 0;
3240
 
  return (unsigned char *)result;
 
3234
  return (uchar *)result;
3241
3235
}
3242
3236
 
3243
3237
 
3288
3282
{
3289
3283
  if (comparators)
3290
3284
  {
3291
 
    for (uint32_t i= 0; i < n; i++)
 
3285
    for (uint i= 0; i < n; i++)
3292
3286
    {
3293
3287
      if (comparators[i])
3294
3288
        delete comparators[i];
3301
3295
void cmp_item_row::alloc_comparators()
3302
3296
{
3303
3297
  if (!comparators)
3304
 
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
 
3298
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
3305
3299
}
3306
3300
 
3307
3301
 
3313
3307
  {
3314
3308
    item->bring_value();
3315
3309
    item->null_value= 0;
3316
 
    for (uint32_t i=0; i < n; i++)
 
3310
    for (uint i=0; i < n; i++)
3317
3311
    {
3318
3312
      if (!comparators[i])
3319
3313
        if (!(comparators[i]=
3341
3335
  {
3342
3336
    item->bring_value();
3343
3337
    item->null_value= 0;
3344
 
    for (uint32_t i=0; i < n; i++)
 
3338
    for (uint i=0; i < n; i++)
3345
3339
    {
3346
3340
      if (!(comparators[i]= tmpl->comparators[i]->make_same()))
3347
3341
        break;                                  // new failed
3363
3357
  }
3364
3358
  bool was_null= 0;
3365
3359
  arg->bring_value();
3366
 
  for (uint32_t i=0; i < n; i++)
 
3360
  for (uint i=0; i < n; i++)
3367
3361
  {
3368
3362
    if (comparators[i]->cmp(arg->element_index(i)))
3369
3363
    {
3379
3373
int cmp_item_row::compare(cmp_item *c)
3380
3374
{
3381
3375
  cmp_item_row *l_cmp= (cmp_item_row *) c;
3382
 
  for (uint32_t i=0; i < n; i++)
 
3376
  for (uint i=0; i < n; i++)
3383
3377
  {
3384
3378
    int res;
3385
3379
    if ((res= comparators[i]->compare(l_cmp->comparators[i])))
3424
3418
{
3425
3419
  bool is_null;
3426
3420
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3427
 
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
 
3421
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3428
3422
}
3429
3423
 
3430
3424
 
3433
3427
  bool is_null;
3434
3428
  Item **tmp_item= &arg;
3435
3429
  return value !=
3436
 
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3430
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3437
3431
}
3438
3432
 
3439
3433
 
3470
3464
    The function saves in ref the pointer to the item or to a newly created
3471
3465
    item that is considered as a replacement for the original one.
3472
3466
 
3473
 
  @param session     reference to the global context of the query thread
 
3467
  @param thd     reference to the global context of the query thread
3474
3468
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3475
3469
                 item is to be assigned
3476
3470
 
3491
3485
*/
3492
3486
 
3493
3487
bool
3494
 
Item_func_in::fix_fields(Session *session, Item **ref)
 
3488
Item_func_in::fix_fields(THD *thd, Item **ref)
3495
3489
{
3496
3490
  Item **arg, **arg_end;
3497
3491
 
3498
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
3492
  if (Item_func_opt_neg::fix_fields(thd, ref))
3499
3493
    return 1;
3500
3494
 
3501
3495
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3514
3508
static int srtcmp_in(const CHARSET_INFO * const cs, const String *x,const String *y)
3515
3509
{
3516
3510
  return cs->coll->strnncollsp(cs,
3517
 
                               (unsigned char *) x->ptr(),x->length(),
3518
 
                               (unsigned char *) y->ptr(),y->length(), 0);
 
3511
                               (uchar *) x->ptr(),x->length(),
 
3512
                               (uchar *) y->ptr(),y->length(), 0);
3519
3513
}
3520
3514
 
3521
3515
 
3523
3517
{
3524
3518
  Item **arg, **arg_end;
3525
3519
  bool const_itm= 1;
3526
 
  Session *session= current_session;
 
3520
  THD *thd= current_thd;
3527
3521
  bool datetime_found= false;
3528
3522
  /* true <=> arguments values will be compared as DATETIMEs. */
3529
3523
  bool compare_as_datetime= false;
3530
3524
  Item *date_arg= 0;
3531
 
  uint32_t found_types= 0;
3532
 
  uint32_t type_cnt= 0, i;
 
3525
  uint found_types= 0;
 
3526
  uint type_cnt= 0, i;
3533
3527
  Item_result cmp_type= STRING_RESULT;
3534
3528
  left_result_type= args[0]->result_type();
3535
3529
  if (!(found_types= collect_cmp_types(args, arg_count)))
3585
3579
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3586
3580
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3587
3581
    {
3588
 
      uint32_t col, cols= args[0]->cols();
 
3582
      uint col, cols= args[0]->cols();
3589
3583
 
3590
3584
      for (col= 0; col < cols; col++)
3591
3585
      {
3661
3655
        comparison type accordingly.
3662
3656
      */  
3663
3657
      if (args[0]->real_item()->type() == FIELD_ITEM &&
3664
 
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
 
3658
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
3665
3659
          cmp_type != INT_RESULT)
3666
3660
      {
3667
3661
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3670
3664
          bool all_converted= true;
3671
3665
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3672
3666
          {
3673
 
            if (!convert_constant_item (session, field_item, &arg[0]))
 
3667
            if (!convert_constant_item (thd, field_item, &arg[0]))
3674
3668
              all_converted= false;
3675
3669
          }
3676
3670
          if (all_converted)
3704
3698
        return;
3705
3699
      }
3706
3700
    }
3707
 
    if (array && !(session->is_fatal_error))            // If not EOM
 
3701
    if (array && !(thd->is_fatal_error))                // If not EOM
3708
3702
    {
3709
 
      uint32_t j=0;
3710
 
      for (uint32_t i=1 ; i < arg_count ; i++)
 
3703
      uint j=0;
 
3704
      for (uint i=1 ; i < arg_count ; i++)
3711
3705
      {
3712
3706
        array->set(j,args[i]);
3713
3707
        if (!args[i]->null_value)                       // Skip NULL values
3786
3780
{
3787
3781
  cmp_item *in_item;
3788
3782
  assert(fixed == 1);
3789
 
  uint32_t value_added_map= 0;
 
3783
  uint value_added_map= 0;
3790
3784
  if (array)
3791
3785
  {
3792
3786
    int tmp=array->find(args[0]);
3794
3788
    return (int64_t) (!null_value && tmp != negated);
3795
3789
  }
3796
3790
 
3797
 
  for (uint32_t i= 1 ; i < arg_count ; i++)
 
3791
  for (uint i= 1 ; i < arg_count ; i++)
3798
3792
  {
3799
3793
    Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3800
3794
    in_item= cmp_items[(uint)cmp_type];
3856
3850
  return (int64_t) (arg1 & arg2);
3857
3851
}
3858
3852
 
3859
 
Item_cond::Item_cond(Session *session, Item_cond *item)
3860
 
  :Item_bool_func(session, item),
 
3853
Item_cond::Item_cond(THD *thd, Item_cond *item)
 
3854
  :Item_bool_func(thd, item),
3861
3855
   abort_on_null(item->abort_on_null),
3862
3856
   and_tables_cache(item->and_tables_cache)
3863
3857
{
3867
3861
}
3868
3862
 
3869
3863
 
3870
 
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
 
3864
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3871
3865
{
3872
3866
  List_iterator_fast<Item> li(item->list);
3873
3867
  while (Item *it= li++)
3874
 
    list.push_back(it->copy_andor_structure(session));
 
3868
    list.push_back(it->copy_andor_structure(thd));
3875
3869
}
3876
3870
 
3877
3871
 
3878
3872
bool
3879
 
Item_cond::fix_fields(Session *session, Item **ref __attribute__((unused)))
 
3873
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
3880
3874
{
3881
3875
  assert(fixed == 0);
3882
3876
  List_iterator<Item> li(list);
3883
3877
  Item *item;
3884
 
  void *orig_session_marker= session->session_marker;
3885
 
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
 
3878
  void *orig_thd_marker= thd->thd_marker;
 
3879
  uchar buff[sizeof(char*)];                    // Max local vars in function
3886
3880
  not_null_tables_cache= used_tables_cache= 0;
3887
3881
  const_item_cache= 1;
3888
3882
 
3889
3883
  if (functype() == COND_OR_FUNC)
3890
 
    session->session_marker= 0;
 
3884
    thd->thd_marker= 0;
3891
3885
  /*
3892
3886
    and_table_cache is the value that Item_cond_or() returns for
3893
3887
    not_null_tables()
3894
3888
  */
3895
3889
  and_tables_cache= ~(table_map) 0;
3896
3890
 
3897
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
3891
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3898
3892
    return true;                                // Fatal error flag is set!
3899
3893
  /*
3900
3894
    The following optimization reduces the depth of an AND-OR tree.
3927
3921
 
3928
3922
    // item can be substituted in fix_fields
3929
3923
    if ((!item->fixed &&
3930
 
         item->fix_fields(session, li.ref())) ||
 
3924
         item->fix_fields(thd, li.ref())) ||
3931
3925
        (item= *li.ref())->check_cols(1))
3932
3926
      return true; /* purecov: inspected */
3933
3927
    used_tables_cache|=     item->used_tables();
3945
3939
    if (item->maybe_null)
3946
3940
      maybe_null=1;
3947
3941
  }
3948
 
  session->lex->current_select->cond_count+= list.elements;
3949
 
  session->session_marker= orig_session_marker;
 
3942
  thd->lex->current_select->cond_count+= list.elements;
 
3943
  thd->thd_marker= orig_thd_marker;
3950
3944
  fix_length_and_dec();
3951
3945
  fixed= 1;
3952
3946
  return false;
3985
3979
}
3986
3980
 
3987
3981
 
3988
 
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
 
3982
bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
3989
3983
{
3990
3984
  List_iterator_fast<Item> li(list);
3991
3985
  Item *item;
4014
4008
    Item returned as the result of transformation of the root node 
4015
4009
*/
4016
4010
 
4017
 
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
 
4011
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
4018
4012
{
4019
4013
  List_iterator<Item> li(list);
4020
4014
  Item *item;
4025
4019
      return 0;
4026
4020
 
4027
4021
    /*
4028
 
      Session::change_item_tree() should be called only if the tree was
 
4022
      THD::change_item_tree() should be called only if the tree was
4029
4023
      really transformed, i.e. when a new item has been created.
4030
4024
      Otherwise we'll be allocating a lot of unnecessary memory for
4031
4025
      change records at each execution.
4032
4026
    */
4033
4027
    if (new_item != item)
4034
 
      current_session->change_item_tree(li.ref(), new_item);
 
4028
      current_thd->change_item_tree(li.ref(), new_item);
4035
4029
  }
4036
4030
  return Item_func::transform(transformer, arg);
4037
4031
}
4061
4055
    Item returned as the result of transformation of the root node 
4062
4056
*/
4063
4057
 
4064
 
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4065
 
                         Item_transformer transformer, unsigned char *arg_t)
 
4058
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
 
4059
                         Item_transformer transformer, uchar *arg_t)
4066
4060
{
4067
4061
  if (!(this->*analyzer)(arg_p))
4068
4062
    return 0;
4075
4069
      The same parameter value of arg_p must be passed
4076
4070
      to analyze any argument of the condition formula.
4077
4071
    */   
4078
 
    unsigned char *arg_v= *arg_p;
 
4072
    uchar *arg_v= *arg_p;
4079
4073
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4080
4074
    if (new_item && new_item != item)
4081
4075
      li.replace(new_item);
4115
4109
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4116
4110
  sql_select.cc)
4117
4111
 
4118
 
  @param session                        Thread handler
 
4112
  @param thd                    Thread handler
4119
4113
  @param ref_pointer_array      Pointer to array of reference fields
4120
4114
  @param fields         All fields in select
4121
4115
 
4124
4118
    that have or refer (HAVING) to a SUM expression.
4125
4119
*/
4126
4120
 
4127
 
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
 
4121
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
4128
4122
                               List<Item> &fields)
4129
4123
{
4130
4124
  List_iterator<Item> li(list);
4131
4125
  Item *item;
4132
4126
  while ((item= li++))
4133
 
    item->split_sum_func2(session, ref_pointer_array, fields, li.ref(), true);
 
4127
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
4134
4128
}
4135
4129
 
4136
4130
 
4175
4169
}
4176
4170
 
4177
4171
 
4178
 
void Item_cond::neg_arguments(Session *session)
 
4172
void Item_cond::neg_arguments(THD *thd)
4179
4173
{
4180
4174
  List_iterator<Item> li(list);
4181
4175
  Item *item;
4182
4176
  while ((item= li++))          /* Apply not transformation to the arguments */
4183
4177
  {
4184
 
    Item *new_item= item->neg_transformer(session);
 
4178
    Item *new_item= item->neg_transformer(thd);
4185
4179
    if (!new_item)
4186
4180
    {
4187
4181
      if (!(new_item= new Item_func_not(item)))
4188
4182
        return;                                 // Fatal OEM error
4189
4183
    }
4190
 
    li.replace(new_item);
 
4184
    VOID(li.replace(new_item));
4191
4185
  }
4192
4186
}
4193
4187
 
4405
4399
}
4406
4400
 
4407
4401
 
4408
 
bool Item_func_like::fix_fields(Session *session, Item **ref)
 
4402
bool Item_func_like::fix_fields(THD *thd, Item **ref)
4409
4403
{
4410
4404
  assert(fixed == 0);
4411
 
  if (Item_bool_func2::fix_fields(session, ref) ||
4412
 
      escape_item->fix_fields(session, &escape_item))
 
4405
  if (Item_bool_func2::fix_fields(thd, ref) ||
 
4406
      escape_item->fix_fields(thd, &escape_item))
4413
4407
    return true;
4414
4408
 
4415
4409
  if (!escape_item->const_during_execution())
4435
4429
        const CHARSET_INFO * const cs= escape_str->charset();
4436
4430
        my_wc_t wc;
4437
4431
        int rc= cs->cset->mb_wc(cs, &wc,
4438
 
                                (const unsigned char*) escape_str->ptr(),
4439
 
                                (const unsigned char*) escape_str->ptr() +
 
4432
                                (const uchar*) escape_str->ptr(),
 
4433
                                (const uchar*) escape_str->ptr() +
4440
4434
                                               escape_str->length());
4441
4435
        escape= (int) (rc > 0 ? wc : '\\');
4442
4436
      }
4453
4447
                                         escape_str->charset(), cs, &unused))
4454
4448
        {
4455
4449
          char ch;
4456
 
          uint32_t errors;
 
4450
          uint errors;
4457
4451
          uint32_t cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
4458
4452
                                          escape_str->length(),
4459
4453
                                          escape_str->charset(), &errors);
4496
4490
      {
4497
4491
        pattern     = first + 1;
4498
4492
        pattern_len = (int) len - 2;
4499
 
        int *suff = (int*) session->alloc((int) (sizeof(int)*
 
4493
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
4500
4494
                                      ((pattern_len + 1)*2+
4501
4495
                                      alphabet_size)));
4502
4496
        bmGs      = suff + pattern_len + 1;
4516
4510
}
4517
4511
 
4518
4512
#ifdef LIKE_CMP_TOUPPER
4519
 
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
 
4513
#define likeconv(cs,A) (uchar) (cs)->toupper(A)
4520
4514
#else
4521
 
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
 
4515
#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
4522
4516
#endif
4523
4517
 
4524
4518
 
4547
4541
      else
4548
4542
      {
4549
4543
        if (i < g)
4550
 
          g = i; // g = cmin(i, g)
 
4544
          g = i; // g = min(i, g)
4551
4545
        f = i;
4552
4546
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4553
4547
          g--;
4566
4560
      else
4567
4561
      {
4568
4562
        if (i < g)
4569
 
          g = i; // g = cmin(i, g)
 
4563
          g = i; // g = min(i, g)
4570
4564
        f = i;
4571
4565
        while (g >= 0 &&
4572
4566
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4640
4634
  if (!cs->sort_order)
4641
4635
  {
4642
4636
    for (j = 0; j < plm1; j++)
4643
 
      bmBc[(uint) (unsigned char) pattern[j]] = plm1 - j;
 
4637
      bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
4644
4638
  }
4645
4639
  else
4646
4640
  {
4686
4680
 
4687
4681
      register const int v = plm1 - i;
4688
4682
      turboShift = u - v;
4689
 
      bcShift    = bmBc[(uint) (unsigned char) text[i + j]] - plm1 + i;
 
4683
      bcShift    = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
4690
4684
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4691
4685
      shift      = (shift > bmGs[i]) ? shift : bmGs[i];
4692
4686
      if (shift == bmGs[i])
4694
4688
      else
4695
4689
      {
4696
4690
        if (turboShift < bcShift)
4697
 
          shift = cmax(shift, u + 1);
 
4691
          shift = max(shift, u + 1);
4698
4692
        u = 0;
4699
4693
      }
4700
4694
      j+= shift;
4719
4713
      turboShift = u - v;
4720
4714
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
4721
4715
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4722
 
      shift      = cmax(shift, bmGs[i]);
 
4716
      shift      = max(shift, bmGs[i]);
4723
4717
      if (shift == bmGs[i])
4724
4718
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4725
4719
      else
4726
4720
      {
4727
4721
        if (turboShift < bcShift)
4728
 
          shift = cmax(shift, u + 1);
 
4722
          shift = max(shift, u + 1);
4729
4723
        u = 0;
4730
4724
      }
4731
4725
      j+= shift;
4789
4783
       IS NOT NULL(a)     -> IS NULL(a)
4790
4784
    @endverbatim
4791
4785
 
4792
 
  @param session                thread handler
 
4786
  @param thd            thread handler
4793
4787
 
4794
4788
  @return
4795
4789
    New item or
4796
4790
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4797
4791
*/
4798
4792
 
4799
 
Item *Item_func_not::neg_transformer(Session *session __attribute__((unused)))  /* NOT(x)  ->  x */
 
4793
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
4800
4794
{
4801
4795
  return args[0];
4802
4796
}
4803
4797
 
4804
4798
 
4805
 
Item *Item_bool_rowready_func2::neg_transformer(Session *session __attribute__((unused)))
 
4799
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
4806
4800
{
4807
4801
  Item *item= negated_item();
4808
4802
  return item;
4812
4806
/**
4813
4807
  a IS NULL  ->  a IS NOT NULL.
4814
4808
*/
4815
 
Item *Item_func_isnull::neg_transformer(Session *session __attribute__((unused)))
 
4809
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
4816
4810
{
4817
4811
  Item *item= new Item_func_isnotnull(args[0]);
4818
4812
  return item;
4822
4816
/**
4823
4817
  a IS NOT NULL  ->  a IS NULL.
4824
4818
*/
4825
 
Item *Item_func_isnotnull::neg_transformer(Session *session __attribute__((unused)))
 
4819
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
4826
4820
{
4827
4821
  Item *item= new Item_func_isnull(args[0]);
4828
4822
  return item;
4829
4823
}
4830
4824
 
4831
4825
 
4832
 
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
 
4826
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
4833
4827
                                        /* NOT a OR NOT b OR ... */
4834
4828
{
4835
 
  neg_arguments(session);
 
4829
  neg_arguments(thd);
4836
4830
  Item *item= new Item_cond_or(list);
4837
4831
  return item;
4838
4832
}
4839
4833
 
4840
4834
 
4841
 
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
 
4835
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
4842
4836
                                        /* NOT a AND NOT b AND ... */
4843
4837
{
4844
 
  neg_arguments(session);
 
4838
  neg_arguments(thd);
4845
4839
  Item *item= new Item_cond_and(list);
4846
4840
  return item;
4847
4841
}
4848
4842
 
4849
4843
 
4850
 
Item *Item_func_nop_all::neg_transformer(Session *session __attribute__((unused)))
 
4844
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
4851
4845
{
4852
4846
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4853
4847
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4858
4852
  return new_item;
4859
4853
}
4860
4854
 
4861
 
Item *Item_func_not_all::neg_transformer(Session *session __attribute__((unused)))
 
4855
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
4862
4856
{
4863
4857
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4864
4858
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4965
4959
  fields.push_back(f);
4966
4960
}
4967
4961
 
4968
 
uint32_t Item_equal::members()
 
4962
uint Item_equal::members()
4969
4963
{
4970
4964
  return fields.elements;
4971
4965
}
5098
5092
  }
5099
5093
}
5100
5094
 
5101
 
bool Item_equal::fix_fields(Session *session __attribute__((unused)), Item **ref __attribute__((unused)))
 
5095
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
5102
5096
{
5103
5097
  List_iterator_fast<Item_field> li(fields);
5104
5098
  Item *item;
5162
5156
                                      item->collation.collation);
5163
5157
}
5164
5158
 
5165
 
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
 
5159
bool Item_equal::walk(Item_processor processor, bool walk_subquery, uchar *arg)
5166
5160
{
5167
5161
  List_iterator_fast<Item_field> it(fields);
5168
5162
  Item *item;
5174
5168
  return Item_func::walk(processor, walk_subquery, arg);
5175
5169
}
5176
5170
 
5177
 
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
 
5171
Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
5178
5172
{
5179
5173
  List_iterator<Item_field> it(fields);
5180
5174
  Item *item;
5185
5179
      return 0;
5186
5180
 
5187
5181
    /*
5188
 
      Session::change_item_tree() should be called only if the tree was
 
5182
      THD::change_item_tree() should be called only if the tree was
5189
5183
      really transformed, i.e. when a new item has been created.
5190
5184
      Otherwise we'll be allocating a lot of unnecessary memory for
5191
5185
      change records at each execution.
5192
5186
    */
5193
5187
    if (new_item != item)
5194
 
      current_session->change_item_tree((Item **) it.ref(), new_item);
 
5188
      current_thd->change_item_tree((Item **) it.ref(), new_item);
5195
5189
  }
5196
5190
  return Item_func::transform(transformer, arg);
5197
5191
}