~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Brian Aker
  • Date: 2009-02-12 22:45:08 UTC
  • Revision ID: brian@tangent.org-20090212224508-mrd9jwgn1zjdpqdk
Minor refactoring (we will need to disconnect the code from the include
file).

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;
 
515
  Item_field *field_item= NULL;
468
516
 
469
517
  if (args[0]->real_item()->type() == FIELD_ITEM)
470
518
  {
471
 
    Item_field *field_item= (Item_field*) (args[0]->real_item());
 
519
    field_item= static_cast<Item_field*>(args[0]->real_item());
472
520
    if (field_item->field->can_be_compared_as_int64_t() &&
473
521
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
474
522
    {
475
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
523
      if (convert_constant_item(session, field_item, &args[1]))
476
524
      {
477
525
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
478
526
                         INT_RESULT);           // Works for all types.
483
531
 
484
532
    if (args[1]->real_item()->type() == FIELD_ITEM)
485
533
    {
486
 
      Item_field *field_item= (Item_field*) (args[1]->real_item());
 
534
      field_item= static_cast<Item_field*>(args[1]->real_item());
487
535
      if (field_item->field->can_be_compared_as_int64_t() &&
488
536
          !(field_item->is_datetime() &&
489
537
            args[0]->result_type() == STRING_RESULT))
490
538
      {
491
 
        if (convert_constant_item(thd, field_item, &args[0]))
 
539
        if (convert_constant_item(session, field_item, &args[0]))
492
540
        {
493
541
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
494
542
                           INT_RESULT); // Works for all types.
536
584
      We must set cmp_charset here as we may be called from for an automatic
537
585
      generated item, like in natural join
538
586
    */
539
 
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
587
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
540
588
        cmp_collation.derivation == DERIVATION_NONE)
541
589
    {
542
590
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
608
656
/**
609
657
  @brief Convert date provided in a string to the int representation.
610
658
 
611
 
  @param[in]   thd        thread handle
 
659
  @param[in]   session        thread handle
612
660
  @param[in]   str        a string to convert
613
661
  @param[in]   warn_type  type of the timestamp for issuing the warning
614
662
  @param[in]   warn_name  field name for issuing the warning
628
676
*/
629
677
 
630
678
static uint64_t
631
 
get_date_from_str(THD *thd, String *str, enum enum_drizzle_timestamp_type warn_type,
 
679
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
632
680
                  char *warn_name, bool *error_arg)
633
681
{
634
682
  uint64_t value= 0;
638
686
 
639
687
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
640
688
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
641
 
                        (thd->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
689
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
642
690
                       &error);
643
691
 
644
692
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
657
705
  }
658
706
 
659
707
  if (error > 0)
660
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
708
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
661
709
                                 str->ptr(), str->length(),
662
710
                                 warn_type, warn_name);
663
711
 
734
782
        (str_arg->type() != Item::FUNC_ITEM ||
735
783
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
736
784
    {
737
 
      THD *thd= current_thd;
 
785
      Session *session= current_session;
738
786
      uint64_t value;
739
787
      bool error;
740
788
      String tmp, *str_val= 0;
741
 
      enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
 
789
      enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_DATE ?
742
790
                              DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
743
791
 
744
792
      str_val= str_arg->val_str(&tmp);
745
793
      if (str_arg->null_value)
746
794
        return CMP_DATE_DFLT;
747
 
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
 
795
      value= get_date_from_str(session, str_val, t_type, date_arg->name, &error);
748
796
      if (error)
749
797
        return CMP_DATE_DFLT;
750
798
      if (const_value)
760
808
 
761
809
  SYNOPSIS
762
810
    get_time_value()
763
 
    thd                 thread handle
 
811
    session                 thread handle
764
812
    item_arg   [in/out] item to retrieve TIME value from
765
813
    cache_arg  [in/out] pointer to place to store the cache item to
766
814
    warn_item  [in]     unused
781
829
*/
782
830
 
783
831
uint64_t
784
 
get_time_value(THD *thd __attribute__((unused)),
 
832
get_time_value(Session *,
785
833
               Item ***item_arg, Item **cache_arg,
786
 
               Item *warn_item __attribute__((unused)),
787
 
               bool *is_null)
 
834
               Item *, bool *is_null)
788
835
{
789
836
  uint64_t value;
790
837
  Item *item= **item_arg;
829
876
 
830
877
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
831
878
  {
832
 
    thd= current_thd;
 
879
    session= current_session;
833
880
    owner= owner_arg;
834
881
    a_type= (*a)->field_type();
835
882
    b_type= (*b)->field_type();
863
910
           (*b)->field_type() == DRIZZLE_TYPE_TIME)
864
911
  {
865
912
    /* Compare TIME values as integers. */
866
 
    thd= current_thd;
 
913
    session= current_session;
867
914
    owner= owner_arg;
868
915
    a_cache= 0;
869
916
    b_cache= 0;
879
926
 
880
927
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
881
928
{
882
 
  thd= current_thd;
 
929
  session= current_session;
883
930
  /* A caller will handle null values by itself. */
884
931
  owner= NULL;
885
932
  a= a1;
899
946
 
900
947
  SYNOPSIS
901
948
    get_datetime_value()
902
 
    thd                 thread handle
 
949
    session                 thread handle
903
950
    item_arg   [in/out] item to retrieve DATETIME value from
904
951
    cache_arg  [in/out] pointer to place to store the caching item to
905
952
    warn_item  [in]     item for issuing the conversion warning
924
971
*/
925
972
 
926
973
uint64_t
927
 
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
 
974
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
928
975
                   Item *warn_item, bool *is_null)
929
976
{
930
977
  uint64_t value= 0;
942
989
      compare it with 100000000L - any DATE value should be less than it.
943
990
      Don't shift cached DATETIME values up for the second time.
944
991
    */
945
 
    if (f_type == DRIZZLE_TYPE_NEWDATE ||
 
992
    if (f_type == DRIZZLE_TYPE_DATE ||
946
993
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
947
994
      value*= 1000000L;
948
995
  }
964
1011
    bool error;
965
1012
    enum_field_types f_type= warn_item->field_type();
966
1013
    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);
 
1014
      DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
 
1015
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
969
1016
    /*
970
1017
      If str did not contain a valid date according to the current
971
1018
      SQL_MODE, get_date_from_str() has already thrown a warning,
1017
1064
  uint64_t a_value, b_value;
1018
1065
 
1019
1066
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1020
 
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
 
1067
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
1021
1068
  if (!is_nulls_eq && is_null)
1022
1069
  {
1023
1070
    if (owner)
1026
1073
  }
1027
1074
 
1028
1075
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1029
 
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
 
1076
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
1030
1077
  if (is_null)
1031
1078
  {
1032
1079
    if (owner)
1443
1490
}
1444
1491
 
1445
1492
 
1446
 
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
 
1493
bool Item_in_optimizer::fix_left(Session *session, Item **)
1447
1494
{
1448
 
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
 
1495
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
1449
1496
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1450
1497
    return 1;
1451
1498
 
1477
1524
}
1478
1525
 
1479
1526
 
1480
 
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
 
1527
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
1481
1528
{
1482
1529
  assert(fixed == 0);
1483
 
  if (fix_left(thd, ref))
 
1530
  if (fix_left(session, ref))
1484
1531
    return true;
1485
1532
  if (args[0]->maybe_null)
1486
1533
    maybe_null=1;
1487
1534
 
1488
 
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
 
1535
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
1489
1536
    return true;
1490
1537
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1491
1538
  if (args[0]->cols() != sub->engine->cols())
1509
1556
  bool tmp;
1510
1557
  assert(fixed == 1);
1511
1558
  cache->store(args[0]);
1512
 
  
 
1559
 
1513
1560
  if (cache->null_value)
1514
1561
  {
1515
1562
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1537
1584
          We disable the predicates we've pushed down into subselect, run the
1538
1585
          subselect and see if it has produced any rows.
1539
1586
        */
1540
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
 
1587
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
1541
1588
        if (cache->cols() == 1)
1542
1589
        {
1543
1590
          item_subs->set_cond_guard_var(0, false);
1558
1605
            if (cache->element_index(i)->null_value)
1559
1606
              item_subs->set_cond_guard_var(i, false);
1560
1607
          }
1561
 
          
 
1608
 
1562
1609
          (void) args[1]->val_bool_result();
1563
1610
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1564
 
          
 
1611
 
1565
1612
          /* Turn all predicates back on */
1566
1613
          for (i= 0; i < ncols; i++)
1567
1614
            item_subs->set_cond_guard_var(i, true);
1632
1679
  if (!new_item)
1633
1680
    return 0;
1634
1681
  /*
1635
 
    THD::change_item_tree() should be called only if the tree was
 
1682
    Session::change_item_tree() should be called only if the tree was
1636
1683
    really transformed, i.e. when a new item has been created.
1637
1684
    Otherwise we'll be allocating a lot of unnecessary memory for
1638
1685
    change records at each execution.
1639
1686
  */
1640
1687
  if ((*args) != new_item)
1641
 
    current_thd->change_item_tree(args, new_item);
 
1688
    current_session->change_item_tree(args, new_item);
1642
1689
 
1643
1690
  /*
1644
1691
    Transform the right IN operand which should be an Item_in_subselect or a
1763
1810
void Item_func_interval::fix_length_and_dec()
1764
1811
{
1765
1812
  uint32_t rows= row->cols();
1766
 
  
 
1813
 
1767
1814
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1768
1815
                            DECIMAL_RESULT) ||
1769
1816
                           (row->element_index(0)->result_type() ==
1904
1951
      if (my_decimal_cmp(e_dec, dec) > 0)
1905
1952
        return i - 1;
1906
1953
    }
1907
 
    else 
 
1954
    else
1908
1955
    {
1909
1956
      double val= el->val_real();
1910
1957
      /* Skip NULL ranges. */
1926
1973
    The function saves in ref the pointer to the item or to a newly created
1927
1974
    item that is considered as a replacement for the original one.
1928
1975
 
1929
 
  @param thd     reference to the global context of the query thread
 
1976
  @param session     reference to the global context of the query thread
1930
1977
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1931
1978
                 item is to be assigned
1932
1979
 
1946
1993
    1   got error
1947
1994
*/
1948
1995
 
1949
 
bool Item_func_between::fix_fields(THD *thd, Item **ref)
 
1996
bool Item_func_between::fix_fields(Session *session, Item **ref)
1950
1997
{
1951
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
1998
  if (Item_func_opt_neg::fix_fields(session, ref))
1952
1999
    return 1;
1953
2000
 
1954
 
  thd->lex->current_select->between_count++;
 
2001
  session->lex->current_select->between_count++;
1955
2002
 
1956
2003
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1957
2004
  if (pred_level && !negated)
1973
2020
  bool datetime_found= false;
1974
2021
  int time_items_found= 0;
1975
2022
  compare_as_dates= true;
1976
 
  THD *thd= current_thd;
 
2023
  Session *session= current_session;
1977
2024
 
1978
2025
  /*
1979
2026
    As some compare functions are generated after sql_yacc,
2020
2067
    cmp_type= INT_RESULT;
2021
2068
  }
2022
2069
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
2023
 
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
 
2070
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2024
2071
  {
2025
2072
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2026
2073
    if (field_item->field->can_be_compared_as_int64_t())
2029
2076
        The following can't be recoded with || as convert_constant_item
2030
2077
        changes the argument
2031
2078
      */
2032
 
      if (convert_constant_item(thd, field_item, &args[1]))
 
2079
      if (convert_constant_item(session, field_item, &args[1]))
2033
2080
        cmp_type=INT_RESULT;                    // Works for all types.
2034
 
      if (convert_constant_item(thd, field_item, &args[2]))
 
2081
      if (convert_constant_item(session, field_item, &args[2]))
2035
2082
        cmp_type=INT_RESULT;                    // Works for all types.
2036
2083
    }
2037
2084
  }
2169
2216
  decimals= cmax(args[0]->decimals, args[1]->decimals);
2170
2217
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2171
2218
 
2172
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
 
2219
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2173
2220
  {
2174
2221
    int len0= args[0]->max_length - args[0]->decimals
2175
2222
      - (args[0]->unsigned_flag ? 0 : 1);
2207
2254
}
2208
2255
 
2209
2256
 
2210
 
enum_field_types Item_func_ifnull::field_type() const 
 
2257
enum_field_types Item_func_ifnull::field_type() const
2211
2258
{
2212
2259
  return cached_field_type;
2213
2260
}
2293
2340
    The function saves in ref the pointer to the item or to a newly created
2294
2341
    item that is considered as a replacement for the original one.
2295
2342
 
2296
 
  @param thd     reference to the global context of the query thread
 
2343
  @param session     reference to the global context of the query thread
2297
2344
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2298
2345
                 item is to be assigned
2299
2346
 
2312
2359
*/
2313
2360
 
2314
2361
bool
2315
 
Item_func_if::fix_fields(THD *thd, Item **ref)
 
2362
Item_func_if::fix_fields(Session *session, Item **ref)
2316
2363
{
2317
2364
  assert(fixed == 0);
2318
2365
  args[0]->top_level_item();
2319
2366
 
2320
 
  if (Item_func::fix_fields(thd, ref))
 
2367
  if (Item_func::fix_fields(session, ref))
2321
2368
    return 1;
2322
2369
 
2323
2370
  not_null_tables_cache= (args[1]->not_null_tables() &
2527
2574
bool
2528
2575
Item_func_nullif::is_null()
2529
2576
{
2530
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
 
2577
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
2531
2578
}
2532
2579
 
2533
2580
 
2552
2599
           failed
2553
2600
*/
2554
2601
 
2555
 
Item *Item_func_case::find_item(String *str __attribute__((unused)))
 
2602
Item *Item_func_case::find_item(String *)
2556
2603
{
2557
2604
  uint32_t value_added_map= 0;
2558
2605
 
2665
2712
}
2666
2713
 
2667
2714
 
2668
 
bool Item_func_case::fix_fields(THD *thd, Item **ref)
 
2715
bool Item_func_case::fix_fields(Session *session, Item **ref)
2669
2716
{
2670
2717
  /*
2671
2718
    buff should match stack usage from
2672
2719
    Item_func_case::val_int() -> Item_func_case::find_item()
2673
2720
  */
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);
 
2721
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
 
2722
                     +sizeof(double)*2+sizeof(int64_t)*2];
 
2723
  bool res= Item_func::fix_fields(session, ref);
2676
2724
  /*
2677
2725
    Call check_stack_overrun after fix_fields to be sure that stack variable
2678
2726
    is not optimized away
2679
2727
  */
2680
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
2728
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2681
2729
    return true;                                // Fatal error flag is set!
2682
2730
  return res;
2683
2731
}
2695
2743
{
2696
2744
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2697
2745
                                           arg->unsigned_flag) - arg->decimals;
2698
 
  set_if_bigger(max_length, len); 
 
2746
  set_if_bigger(max_length, len);
2699
2747
  set_if_bigger(decimals, arg->decimals);
2700
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
 
2748
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
2701
2749
}
2702
2750
 
2703
2751
 
2708
2756
  uint32_t found_types= 0;
2709
2757
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2710
2758
    return;
2711
 
  
 
2759
 
2712
2760
  /*
2713
2761
    Aggregate all THEN and ELSE expression types
2714
2762
    and collations when string result
2715
2763
  */
2716
 
  
 
2764
 
2717
2765
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2718
2766
    agg[nagg]= args[nagg*2+1];
2719
 
  
 
2767
 
2720
2768
  if (else_expr_num != -1)
2721
2769
    agg[nagg++]= args[else_expr_num];
2722
 
  
 
2770
 
2723
2771
  agg_result_type(&cached_result_type, agg, nagg);
2724
2772
  if ((cached_result_type == STRING_RESULT) &&
2725
2773
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2726
2774
    return;
2727
 
  
 
2775
 
2728
2776
  cached_field_type= agg_field_type(agg, nagg);
2729
2777
  /*
2730
2778
    Aggregate first expression and all THEN expression types
2760
2808
 
2761
2809
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2762
2810
    maybe_null=1;
2763
 
  
 
2811
 
2764
2812
  max_length=0;
2765
2813
  decimals=0;
2766
2814
  unsigned_flag= true;
2775
2823
  {
2776
2824
    for (uint32_t i= 0; i < ncases; i+= 2)
2777
2825
      agg_num_lengths(args[i + 1]);
2778
 
    if (else_expr_num != -1) 
 
2826
    if (else_expr_num != -1)
2779
2827
      agg_num_lengths(args[else_expr_num]);
2780
2828
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2781
2829
                                               unsigned_flag);
2789
2837
  for (uint32_t i=0 ; i < ncases ; i+=2)
2790
2838
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2791
2839
 
2792
 
  if (else_expr_num != -1) 
 
2840
  if (else_expr_num != -1)
2793
2841
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2794
2842
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2795
2843
}
2980
3028
 
2981
3029
 
2982
3030
/*
2983
 
  Compare two integers in IN value list format (packed_int64_t) 
 
3031
  Compare two integers in IN value list format (packed_int64_t)
2984
3032
 
2985
3033
  SYNOPSIS
2986
3034
    cmp_int64_t()
3002
3050
    0           left argument is equal to the right argument.
3003
3051
    1           left argument is greater than the right argument.
3004
3052
*/
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)
 
3053
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
 
3054
                in_int64_t::packed_int64_t *b)
3008
3055
{
3009
3056
  if (a->unsigned_flag != b->unsigned_flag)
3010
 
  { 
3011
 
    /* 
3012
 
      One of the args is unsigned and is too big to fit into the 
 
3057
  {
 
3058
    /*
 
3059
      One of the args is unsigned and is too big to fit into the
3013
3060
      positive signed range. Report no match.
3014
 
    */  
 
3061
    */
3015
3062
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3016
3063
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3017
3064
      return a->unsigned_flag ? 1 : -1;
3018
3065
    /*
3019
 
      Although the signedness differs both args can fit into the signed 
 
3066
      Although the signedness differs both args can fit into the signed
3020
3067
      positive range. Make them signed and compare as usual.
3021
 
    */  
 
3068
    */
3022
3069
    return cmp_longs (a->val, b->val);
3023
3070
  }
3024
3071
  if (a->unsigned_flag)
3027
3074
    return cmp_longs (a->val, b->val);
3028
3075
}
3029
3076
 
3030
 
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
 
3077
static int cmp_double(void *, double *a, double *b)
3031
3078
{
3032
3079
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3033
3080
}
3034
3081
 
3035
 
static int cmp_row(void *cmp_arg __attribute__((unused)), cmp_item_row *a, cmp_item_row *b)
 
3082
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
3036
3083
{
3037
3084
  return a->compare(b);
3038
3085
}
3039
3086
 
3040
3087
 
3041
 
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
 
3088
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
3042
3089
{
3043
3090
  /*
3044
3091
    We need call of fixing buffer pointer, because fast sort just copy
3115
3162
  return (unsigned char*) item->val_str(&tmp);
3116
3163
}
3117
3164
 
3118
 
in_row::in_row(uint32_t elements, Item * item __attribute__((unused)))
 
3165
in_row::in_row(uint32_t elements, Item *)
3119
3166
{
3120
3167
  base= (char*) new cmp_item_row[count= elements];
3121
3168
  size= sizeof(cmp_item_row);
3155
3202
void in_int64_t::set(uint32_t pos,Item *item)
3156
3203
{
3157
3204
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3158
 
  
 
3205
 
3159
3206
  buff->val= item->val_int();
3160
3207
  buff->unsigned_flag= item->unsigned_flag;
3161
3208
}
3175
3222
  bool is_null;
3176
3223
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3177
3224
 
3178
 
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3225
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3179
3226
  buff->unsigned_flag= 1L;
3180
3227
}
3181
3228
 
3183
3230
{
3184
3231
  bool is_null;
3185
3232
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3186
 
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3233
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3187
3234
  if (item->null_value)
3188
3235
    return 0;
3189
3236
  tmp.unsigned_flag= 1L;
3220
3267
  dec->len= DECIMAL_BUFF_LENGTH;
3221
3268
  dec->fix_buffer_pointer();
3222
3269
  my_decimal *res= item->val_decimal(dec);
3223
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
 
3270
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
3224
3271
  if (!item->null_value && res != dec)
3225
3272
    my_decimal2decimal(res, dec);
3226
3273
}
3295
3342
void cmp_item_row::alloc_comparators()
3296
3343
{
3297
3344
  if (!comparators)
3298
 
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
 
3345
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
3299
3346
}
3300
3347
 
3301
3348
 
3418
3465
{
3419
3466
  bool is_null;
3420
3467
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3421
 
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
 
3468
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3422
3469
}
3423
3470
 
3424
3471
 
3427
3474
  bool is_null;
3428
3475
  Item **tmp_item= &arg;
3429
3476
  return value !=
3430
 
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
 
3477
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3431
3478
}
3432
3479
 
3433
3480
 
3464
3511
    The function saves in ref the pointer to the item or to a newly created
3465
3512
    item that is considered as a replacement for the original one.
3466
3513
 
3467
 
  @param thd     reference to the global context of the query thread
 
3514
  @param session     reference to the global context of the query thread
3468
3515
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3469
3516
                 item is to be assigned
3470
3517
 
3485
3532
*/
3486
3533
 
3487
3534
bool
3488
 
Item_func_in::fix_fields(THD *thd, Item **ref)
 
3535
Item_func_in::fix_fields(Session *session, Item **ref)
3489
3536
{
3490
3537
  Item **arg, **arg_end;
3491
3538
 
3492
 
  if (Item_func_opt_neg::fix_fields(thd, ref))
 
3539
  if (Item_func_opt_neg::fix_fields(session, ref))
3493
3540
    return 1;
3494
3541
 
3495
3542
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3517
3564
{
3518
3565
  Item **arg, **arg_end;
3519
3566
  bool const_itm= 1;
3520
 
  THD *thd= current_thd;
 
3567
  Session *session= current_session;
3521
3568
  bool datetime_found= false;
3522
3569
  /* true <=> arguments values will be compared as DATETIMEs. */
3523
3570
  bool compare_as_datetime= false;
3528
3575
  left_result_type= args[0]->result_type();
3529
3576
  if (!(found_types= collect_cmp_types(args, arg_count)))
3530
3577
    return;
3531
 
  
 
3578
 
3532
3579
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3533
3580
  {
3534
3581
    if (!arg[0]->const_item())
3548
3595
 
3549
3596
  if (type_cnt == 1)
3550
3597
  {
3551
 
    if (cmp_type == STRING_RESULT && 
 
3598
    if (cmp_type == STRING_RESULT &&
3552
3599
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3553
3600
      return;
3554
3601
    arg_types_compatible= true;
3579
3626
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3580
3627
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3581
3628
    {
3582
 
      uint32_t col, cols= args[0]->cols();
 
3629
      uint32_t col, num_cols= args[0]->cols();
3583
3630
 
3584
 
      for (col= 0; col < cols; col++)
 
3631
      for (col= 0; col < num_cols; col++)
3585
3632
      {
3586
3633
        bool skip_column= false;
3587
3634
        /*
3650
3697
      /*
3651
3698
        IN must compare INT columns and constants as int values (the same
3652
3699
        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 
 
3700
        So we must check here if the column on the left and all the constant
 
3701
        values on the right can be compared as integers and adjust the
3655
3702
        comparison type accordingly.
3656
 
      */  
 
3703
      */
3657
3704
      if (args[0]->real_item()->type() == FIELD_ITEM &&
3658
 
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
 
3705
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3659
3706
          cmp_type != INT_RESULT)
3660
3707
      {
3661
3708
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3664
3711
          bool all_converted= true;
3665
3712
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3666
3713
          {
3667
 
            if (!convert_constant_item (thd, field_item, &arg[0]))
 
3714
            if (!convert_constant_item (session, field_item, &arg[0]))
3668
3715
              all_converted= false;
3669
3716
          }
3670
3717
          if (all_converted)
3673
3720
      }
3674
3721
      switch (cmp_type) {
3675
3722
      case STRING_RESULT:
3676
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
 
3723
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3677
3724
                            cmp_collation.collation);
3678
3725
        break;
3679
3726
      case INT_RESULT:
3698
3745
        return;
3699
3746
      }
3700
3747
    }
3701
 
    if (array && !(thd->is_fatal_error))                // If not EOM
 
3748
    if (array && !(session->is_fatal_error))            // If not EOM
3702
3749
    {
3703
3750
      uint32_t j=0;
3704
 
      for (uint32_t i=1 ; i < arg_count ; i++)
 
3751
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3705
3752
      {
3706
 
        array->set(j,args[i]);
3707
 
        if (!args[i]->null_value)                       // Skip NULL values
 
3753
        array->set(j,args[arg_num]);
 
3754
        if (!args[arg_num]->null_value)                 // Skip NULL values
3708
3755
          j++;
3709
3756
        else
3710
3757
          have_null= 1;
3850
3897
  return (int64_t) (arg1 & arg2);
3851
3898
}
3852
3899
 
3853
 
Item_cond::Item_cond(THD *thd, Item_cond *item)
3854
 
  :Item_bool_func(thd, item),
 
3900
Item_cond::Item_cond(Session *session, Item_cond *item)
 
3901
  :Item_bool_func(session, item),
3855
3902
   abort_on_null(item->abort_on_null),
3856
3903
   and_tables_cache(item->and_tables_cache)
3857
3904
{
3861
3908
}
3862
3909
 
3863
3910
 
3864
 
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
 
3911
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3865
3912
{
3866
3913
  List_iterator_fast<Item> li(item->list);
3867
3914
  while (Item *it= li++)
3868
 
    list.push_back(it->copy_andor_structure(thd));
 
3915
    list.push_back(it->copy_andor_structure(session));
3869
3916
}
3870
3917
 
3871
3918
 
3872
3919
bool
3873
 
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
 
3920
Item_cond::fix_fields(Session *session, Item **)
3874
3921
{
3875
3922
  assert(fixed == 0);
3876
3923
  List_iterator<Item> li(list);
3877
3924
  Item *item;
3878
 
  void *orig_thd_marker= thd->thd_marker;
 
3925
  void *orig_session_marker= session->session_marker;
3879
3926
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3880
3927
  not_null_tables_cache= used_tables_cache= 0;
3881
3928
  const_item_cache= 1;
3882
3929
 
3883
3930
  if (functype() == COND_OR_FUNC)
3884
 
    thd->thd_marker= 0;
 
3931
    session->session_marker= 0;
3885
3932
  /*
3886
3933
    and_table_cache is the value that Item_cond_or() returns for
3887
3934
    not_null_tables()
3888
3935
  */
3889
3936
  and_tables_cache= ~(table_map) 0;
3890
3937
 
3891
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
 
3938
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3892
3939
    return true;                                // Fatal error flag is set!
3893
3940
  /*
3894
3941
    The following optimization reduces the depth of an AND-OR tree.
3921
3968
 
3922
3969
    // item can be substituted in fix_fields
3923
3970
    if ((!item->fixed &&
3924
 
         item->fix_fields(thd, li.ref())) ||
 
3971
         item->fix_fields(session, li.ref())) ||
3925
3972
        (item= *li.ref())->check_cols(1))
3926
3973
      return true; /* purecov: inspected */
3927
3974
    used_tables_cache|=     item->used_tables();
3933
3980
      not_null_tables_cache|= tmp_table_map;
3934
3981
      and_tables_cache&= tmp_table_map;
3935
3982
      const_item_cache= false;
3936
 
    }  
 
3983
    }
3937
3984
    with_sum_func=          with_sum_func || item->with_sum_func;
3938
3985
    with_subselect|=        item->with_subselect;
3939
3986
    if (item->maybe_null)
3940
3987
      maybe_null=1;
3941
3988
  }
3942
 
  thd->lex->current_select->cond_count+= list.elements;
3943
 
  thd->thd_marker= orig_thd_marker;
 
3989
  session->lex->current_select->cond_count+= list.elements;
 
3990
  session->session_marker= orig_session_marker;
3944
3991
  fix_length_and_dec();
3945
3992
  fixed= 1;
3946
3993
  return false;
3947
3994
}
3948
3995
 
3949
3996
 
3950
 
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
 
3997
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3951
3998
{
3952
3999
  List_iterator<Item> li(list);
3953
4000
  Item *item;
3974
4021
      not_null_tables_cache|= tmp_table_map;
3975
4022
      and_tables_cache&= tmp_table_map;
3976
4023
      const_item_cache= false;
3977
 
    }  
 
4024
    }
3978
4025
  }
3979
4026
}
3980
4027
 
3992
4039
 
3993
4040
/**
3994
4041
  Transform an Item_cond object with a transformer callback function.
3995
 
  
 
4042
 
3996
4043
    The function recursively applies the transform method to each
3997
4044
     member item of the condition list.
3998
4045
    If the call of the method for a member item returns a new item
3999
4046
    the old item is substituted for a new one.
4000
4047
    After this the transformer is applied to the root node
4001
 
    of the Item_cond object. 
4002
 
     
 
4048
    of the Item_cond object.
 
4049
 
4003
4050
  @param transformer   the transformer callback function to be applied to
4004
4051
                       the nodes of the tree of the object
4005
4052
  @param arg           parameter to be passed to the transformer
4006
4053
 
4007
4054
  @return
4008
 
    Item returned as the result of transformation of the root node 
 
4055
    Item returned as the result of transformation of the root node
4009
4056
*/
4010
4057
 
4011
4058
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4019
4066
      return 0;
4020
4067
 
4021
4068
    /*
4022
 
      THD::change_item_tree() should be called only if the tree was
 
4069
      Session::change_item_tree() should be called only if the tree was
4023
4070
      really transformed, i.e. when a new item has been created.
4024
4071
      Otherwise we'll be allocating a lot of unnecessary memory for
4025
4072
      change records at each execution.
4026
4073
    */
4027
4074
    if (new_item != item)
4028
 
      current_thd->change_item_tree(li.ref(), new_item);
 
4075
      current_session->change_item_tree(li.ref(), new_item);
4029
4076
  }
4030
4077
  return Item_func::transform(transformer, arg);
4031
4078
}
4034
4081
/**
4035
4082
  Compile Item_cond object with a processor and a transformer
4036
4083
  callback functions.
4037
 
  
 
4084
 
4038
4085
    First the function applies the analyzer to the root node of
4039
4086
    the Item_func object. Then if the analyzer succeeeds (returns true)
4040
4087
    the function recursively applies the compile method to member
4042
4089
    If the call of the method for a member item returns a new item
4043
4090
    the old item is substituted for a new one.
4044
4091
    After this the transformer is applied to the root node
4045
 
    of the Item_cond object. 
4046
 
     
 
4092
    of the Item_cond object.
 
4093
 
4047
4094
  @param analyzer      the analyzer callback function to be applied to the
4048
4095
                       nodes of the tree of the object
4049
4096
  @param[in,out] arg_p parameter to be passed to the analyzer
4052
4099
  @param arg_t         parameter to be passed to the transformer
4053
4100
 
4054
4101
  @return
4055
 
    Item returned as the result of transformation of the root node 
 
4102
    Item returned as the result of transformation of the root node
4056
4103
*/
4057
4104
 
4058
4105
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4060
4107
{
4061
4108
  if (!(this->*analyzer)(arg_p))
4062
4109
    return 0;
4063
 
  
 
4110
 
4064
4111
  List_iterator<Item> li(list);
4065
4112
  Item *item;
4066
4113
  while ((item= li++))
4067
4114
  {
4068
 
    /* 
 
4115
    /*
4069
4116
      The same parameter value of arg_p must be passed
4070
4117
      to analyze any argument of the condition formula.
4071
 
    */   
 
4118
    */
4072
4119
    unsigned char *arg_v= *arg_p;
4073
4120
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4074
4121
    if (new_item && new_item != item)
4083
4130
  List_iterator<Item> li(list);
4084
4131
  Item *item;
4085
4132
 
4086
 
  switch(order) {
4087
 
  case(PREFIX):
 
4133
  switch (order) {
 
4134
  case (T_PREFIX):
4088
4135
    (*traverser)(this, arg);
4089
4136
    while ((item= li++))
4090
4137
    {
4092
4139
    }
4093
4140
    (*traverser)(NULL, arg);
4094
4141
    break;
4095
 
  case(POSTFIX):
 
4142
  case (T_POSTFIX):
4096
4143
    while ((item= li++))
4097
4144
    {
4098
4145
      item->traverse_cond(traverser, arg, order);
4109
4156
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4110
4157
  sql_select.cc)
4111
4158
 
4112
 
  @param thd                    Thread handler
 
4159
  @param session                        Thread handler
4113
4160
  @param ref_pointer_array      Pointer to array of reference fields
4114
4161
  @param fields         All fields in select
4115
4162
 
4118
4165
    that have or refer (HAVING) to a SUM expression.
4119
4166
*/
4120
4167
 
4121
 
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
 
4168
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4122
4169
                               List<Item> &fields)
4123
4170
{
4124
4171
  List_iterator<Item> li(list);
4125
4172
  Item *item;
4126
4173
  while ((item= li++))
4127
 
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
 
4174
    item->split_sum_func(session, ref_pointer_array,
 
4175
                         fields, li.ref(), true);
4128
4176
}
4129
4177
 
4130
4178
 
4169
4217
}
4170
4218
 
4171
4219
 
4172
 
void Item_cond::neg_arguments(THD *thd)
 
4220
void Item_cond::neg_arguments(Session *session)
4173
4221
{
4174
4222
  List_iterator<Item> li(list);
4175
4223
  Item *item;
4176
4224
  while ((item= li++))          /* Apply not transformation to the arguments */
4177
4225
  {
4178
 
    Item *new_item= item->neg_transformer(thd);
 
4226
    Item *new_item= item->neg_transformer(session);
4179
4227
    if (!new_item)
4180
4228
    {
4181
4229
      if (!(new_item= new Item_func_not(item)))
4399
4447
}
4400
4448
 
4401
4449
 
4402
 
bool Item_func_like::fix_fields(THD *thd, Item **ref)
 
4450
bool Item_func_like::fix_fields(Session *session, Item **ref)
4403
4451
{
4404
4452
  assert(fixed == 0);
4405
 
  if (Item_bool_func2::fix_fields(thd, ref) ||
4406
 
      escape_item->fix_fields(thd, &escape_item))
 
4453
  if (Item_bool_func2::fix_fields(session, ref) ||
 
4454
      escape_item->fix_fields(session, &escape_item))
4407
4455
    return true;
4408
4456
 
4409
4457
  if (!escape_item->const_during_execution())
4411
4459
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4412
4460
    return true;
4413
4461
  }
4414
 
  
 
4462
 
4415
4463
  if (escape_item->const_item())
4416
4464
  {
4417
4465
    /* If we are on execution stage */
4464
4512
      We could also do boyer-more for non-const items, but as we would have to
4465
4513
      recompute the tables for each row it's not worth it.
4466
4514
    */
4467
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation)) 
 
4515
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4468
4516
    {
4469
4517
      String* res2 = args[1]->val_str(&tmp_value2);
4470
4518
      if (!res2)
4471
4519
        return false;                           // Null argument
4472
 
      
 
4520
 
4473
4521
      const size_t len   = res2->length();
4474
4522
      const char*  first = res2->ptr();
4475
4523
      const char*  last  = first + len - 1;
4477
4525
        len must be > 2 ('%pattern%')
4478
4526
        heuristic: only do TurboBM for pattern_len > 2
4479
4527
      */
4480
 
      
 
4528
 
4481
4529
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4482
4530
          *first == wild_many &&
4483
4531
          *last  == wild_many)
4490
4538
      {
4491
4539
        pattern     = first + 1;
4492
4540
        pattern_len = (int) len - 2;
4493
 
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
 
4541
        int *suff = (int*) session->alloc((int) (sizeof(int)*
4494
4542
                                      ((pattern_len + 1)*2+
4495
4543
                                      alphabet_size)));
4496
4544
        bmGs      = suff + pattern_len + 1;
4750
4798
  assert(fixed == 1);
4751
4799
  List_iterator<Item> li(list);
4752
4800
  Item *item;
4753
 
  int result=0; 
 
4801
  int result=0;
4754
4802
  null_value=0;
4755
4803
  while ((item=li++))
4756
4804
  {
4783
4831
       IS NOT NULL(a)     -> IS NULL(a)
4784
4832
    @endverbatim
4785
4833
 
4786
 
  @param thd            thread handler
 
4834
  @param session                thread handler
4787
4835
 
4788
4836
  @return
4789
4837
    New item or
4790
4838
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4791
4839
*/
4792
4840
 
4793
 
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
 
4841
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
4794
4842
{
4795
4843
  return args[0];
4796
4844
}
4797
4845
 
4798
4846
 
4799
 
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
 
4847
Item *Item_bool_rowready_func2::neg_transformer(Session *)
4800
4848
{
4801
4849
  Item *item= negated_item();
4802
4850
  return item;
4806
4854
/**
4807
4855
  a IS NULL  ->  a IS NOT NULL.
4808
4856
*/
4809
 
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
 
4857
Item *Item_func_isnull::neg_transformer(Session *)
4810
4858
{
4811
4859
  Item *item= new Item_func_isnotnull(args[0]);
4812
4860
  return item;
4816
4864
/**
4817
4865
  a IS NOT NULL  ->  a IS NULL.
4818
4866
*/
4819
 
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
 
4867
Item *Item_func_isnotnull::neg_transformer(Session *)
4820
4868
{
4821
4869
  Item *item= new Item_func_isnull(args[0]);
4822
4870
  return item;
4823
4871
}
4824
4872
 
4825
4873
 
4826
 
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
 
4874
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
4827
4875
                                        /* NOT a OR NOT b OR ... */
4828
4876
{
4829
 
  neg_arguments(thd);
 
4877
  neg_arguments(session);
4830
4878
  Item *item= new Item_cond_or(list);
4831
4879
  return item;
4832
4880
}
4833
4881
 
4834
4882
 
4835
 
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
 
4883
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
4836
4884
                                        /* NOT a AND NOT b AND ... */
4837
4885
{
4838
 
  neg_arguments(thd);
 
4886
  neg_arguments(session);
4839
4887
  Item *item= new Item_cond_and(list);
4840
4888
  return item;
4841
4889
}
4842
4890
 
4843
4891
 
4844
 
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
 
4892
Item *Item_func_nop_all::neg_transformer(Session *)
4845
4893
{
4846
4894
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4847
4895
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4852
4900
  return new_item;
4853
4901
}
4854
4902
 
4855
 
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
 
4903
Item *Item_func_not_all::neg_transformer(Session *)
4856
4904
{
4857
4905
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4858
4906
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4975
5023
  @retval
4976
5024
    1       if nultiple equality contains a reference to field
4977
5025
  @retval
4978
 
    0       otherwise    
 
5026
    0       otherwise
4979
5027
*/
4980
5028
 
4981
5029
bool Item_equal::contains(Field *field)
4993
5041
 
4994
5042
/**
4995
5043
  Join members of another Item_equal object.
4996
 
  
 
5044
 
4997
5045
    The function actually merges two multiple equalities.
4998
5046
    After this operation the Item_equal object additionally contains
4999
5047
    the field items of another item of the type Item_equal.
5000
5048
    If the optional constant items are not equal the cond_false flag is
5001
 
    set to 1.  
 
5049
    set to 1.
5002
5050
  @param item    multiple equality whose members are to be joined
5003
5051
*/
5004
5052
 
5008
5056
  Item *c= item->const_item;
5009
5057
  if (c)
5010
5058
  {
5011
 
    /* 
5012
 
      The flag cond_false will be set to 1 after this, if 
5013
 
      the multiple equality already contains a constant and its 
 
5059
    /*
 
5060
      The flag cond_false will be set to 1 after this, if
 
5061
      the multiple equality already contains a constant and its
5014
5062
      value is  not equal to the value of c.
5015
5063
    */
5016
5064
    add(c);
5017
5065
  }
5018
5066
  cond_false|= item->cond_false;
5019
 
 
5067
}
5020
5068
 
5021
5069
 
5022
5070
/**
5092
5140
  }
5093
5141
}
5094
5142
 
5095
 
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
 
5143
bool Item_equal::fix_fields(Session *, Item **)
5096
5144
{
5097
5145
  List_iterator_fast<Item_field> li(fields);
5098
5146
  Item *item;
5179
5227
      return 0;
5180
5228
 
5181
5229
    /*
5182
 
      THD::change_item_tree() should be called only if the tree was
 
5230
      Session::change_item_tree() should be called only if the tree was
5183
5231
      really transformed, i.e. when a new item has been created.
5184
5232
      Otherwise we'll be allocating a lot of unnecessary memory for
5185
5233
      change records at each execution.
5186
5234
    */
5187
5235
    if (new_item != item)
5188
 
      current_thd->change_item_tree((Item **) it.ref(), new_item);
 
5236
      current_session->change_item_tree((Item **) it.ref(), new_item);
5189
5237
  }
5190
5238
  return Item_func::transform(transformer, arg);
5191
5239
}