~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_cmpfunc.cc

Merged vcol stuff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/**
21
21
  This file defines all compare functions
22
22
*/
23
23
 
24
 
#include "config.h"
25
 
#include "drizzled/sql_select.h"
26
 
#include "drizzled/error.h"
27
 
#include "drizzled/temporal.h"
28
 
#include "drizzled/item/cmpfunc.h"
29
 
#include "drizzled/cached_item.h"
30
 
#include "drizzled/item/cache_int.h"
31
 
#include "drizzled/item/int_with_ref.h"
32
 
#include "drizzled/check_stack_overrun.h"
33
 
#include "drizzled/time_functions.h"
34
 
#include "drizzled/internal/my_sys.h"
35
 
#include <math.h>
36
 
#include <algorithm>
37
 
 
38
 
using namespace std;
39
 
 
40
 
namespace drizzled
41
 
{
42
 
 
43
 
extern const double log_10[309];
44
 
 
45
 
static Eq_creator eq_creator;
46
 
static Ne_creator ne_creator;
47
 
static Gt_creator gt_creator;
48
 
static Lt_creator lt_creator;
49
 
static Ge_creator ge_creator;
50
 
static Le_creator le_creator;
51
 
 
52
 
static bool convert_constant_item(Session *, Item_field *, Item **);
 
24
#include <drizzled/server_includes.h>
 
25
#include <drizzled/sql_select.h>
 
26
 
 
27
static bool convert_constant_item(THD *, Item_field *, Item **);
53
28
 
54
29
static Item_result item_store_type(Item_result a, Item *item,
55
30
                                   bool unsigned_flag)
104
79
  DESCRIPTION
105
80
    The function checks that two expressions have compatible row signatures
106
81
    i.e. that the number of columns they return are the same and that if they
107
 
    are both row expressions then each component from the first expression has
 
82
    are both row expressions then each component from the first expression has 
108
83
    a row signature compatible with the signature of the corresponding component
109
84
    of the second expression.
110
85
 
165
140
      of the first row expression has a compatible row signature with
166
141
      the signature of the corresponding component of the second row
167
142
      expression.
168
 
    */
 
143
    */ 
169
144
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
170
145
      return 1;     // error found: invalid usage of rows
171
146
  }
209
184
    collect_cmp_types()
210
185
      items             Array of items to collect types from
211
186
      nitems            Number of items in the array
212
 
      skip_nulls        Don't collect types of NULL items if TRUE
213
187
 
214
188
  DESCRIPTION
215
189
    This function collects different result types for comparison of the first
220
194
    Bitmap of collected types - otherwise
221
195
*/
222
196
 
223
 
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
 
197
static uint32_t collect_cmp_types(Item **items, uint32_t nitems)
224
198
{
225
199
  uint32_t i;
226
200
  uint32_t found_types;
229
203
  found_types= 0;
230
204
  for (i= 1; i < nitems ; i++)
231
205
  {
232
 
    if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
233
 
      continue; // Skip NULL constant items
234
 
    if ((left_result == ROW_RESULT ||
 
206
    if ((left_result == ROW_RESULT || 
235
207
         items[i]->result_type() == ROW_RESULT) &&
236
208
        cmp_row_type(items[0], items[i]))
237
209
      return 0;
238
 
    found_types|= 1<< (uint32_t)item_cmp_type(left_result,
 
210
    found_types|= 1<< (uint)item_cmp_type(left_result,
239
211
                                           items[i]->result_type());
240
212
  }
241
 
  /*
242
 
   Even if all right-hand items are NULLs and we are skipping them all, we need
243
 
   at least one type bit in the found_type bitmask.
244
 
  */
245
 
  if (skip_nulls && !found_types)
246
 
    found_types= 1 << (uint)left_result;
247
213
  return found_types;
248
214
}
249
215
 
 
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
 
250
225
 
251
226
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
252
227
{
254
229
}
255
230
 
256
231
 
257
 
const Eq_creator* Eq_creator::instance()
258
 
{
259
 
  return &eq_creator;
260
 
}
261
 
 
262
 
 
263
232
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
264
233
{
265
234
  return new Item_func_ne(a, b);
266
235
}
267
236
 
268
237
 
269
 
const Ne_creator* Ne_creator::instance()
270
 
{
271
 
  return &ne_creator;
272
 
}
273
 
 
274
 
 
275
238
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
276
239
{
277
240
  return new Item_func_gt(a, b);
278
241
}
279
242
 
280
243
 
281
 
const Gt_creator* Gt_creator::instance()
282
 
{
283
 
  return &gt_creator;
284
 
}
285
 
 
286
 
 
287
244
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
288
245
{
289
246
  return new Item_func_lt(a, b);
290
247
}
291
248
 
292
249
 
293
 
const Lt_creator* Lt_creator::instance()
294
 
{
295
 
  return &lt_creator;
296
 
}
297
 
 
298
 
 
299
250
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
300
251
{
301
252
  return new Item_func_ge(a, b);
302
253
}
303
254
 
304
255
 
305
 
const Ge_creator* Ge_creator::instance()
306
 
{
307
 
  return &ge_creator;
308
 
}
309
 
 
310
 
 
311
256
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
312
257
{
313
258
  return new Item_func_le(a, b);
314
259
}
315
260
 
316
 
const Le_creator* Le_creator::instance()
317
 
{
318
 
  return &le_creator;
319
 
}
320
 
 
321
 
 
322
261
/*
323
262
  Test functions
324
263
  Most of these  returns 0LL if false and 1LL if true and
422
361
    also when comparing bigint to strings (in which case strings
423
362
    are converted to bigints).
424
363
 
425
 
  @param  session             thread handle
 
364
  @param  thd             thread handle
426
365
  @param  field_item      item will be converted using the type of this field
427
366
  @param[in,out] item     reference to the item to convert
428
367
 
439
378
    1  Item was replaced with an integer version of the item
440
379
*/
441
380
 
442
 
static bool convert_constant_item(Session *session, Item_field *field_item,
 
381
static bool convert_constant_item(THD *thd, Item_field *field_item,
443
382
                                  Item **item)
444
383
{
445
384
  Field *field= field_item->field;
446
385
  int result= 0;
447
386
 
448
 
  field->setWriteSet();
449
 
 
450
387
  if (!(*item)->with_subselect && (*item)->const_item())
451
388
  {
452
 
    ulong orig_sql_mode= session->variables.sql_mode;
453
 
    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;
454
391
    uint64_t orig_field_val= 0; /* original field value if valid */
455
392
 
456
393
    /* For comparison purposes allow invalid dates like 2000-01-32 */
457
 
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
 
394
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
458
395
                             MODE_INVALID_DATES;
459
 
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
396
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
460
397
 
461
398
    /*
462
399
      Store the value of the field if it references an outer field because
463
400
      the call to save_in_field below overrides that value.
464
401
    */
465
402
    if (field_item->depended_from)
466
 
    {
467
403
      orig_field_val= field->val_int();
468
 
    }
469
 
 
470
404
    if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
471
405
    {
472
406
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
473
407
                                       test(field->flags & UNSIGNED_FLAG));
474
408
      if (tmp)
475
 
        session->change_item_tree(item, tmp);
 
409
        thd->change_item_tree(item, tmp);
476
410
      result= 1;                                        // Item was replaced
477
411
    }
478
 
 
479
412
    /* Restore the original field value. */
480
413
    if (field_item->depended_from)
481
414
    {
482
 
      result= field->store(orig_field_val, field->isUnsigned());
 
415
      result= field->store(orig_field_val, true);
483
416
      /* orig_field_val must be a valid value that can be restored back. */
484
417
      assert(!result);
485
418
    }
486
 
    session->variables.sql_mode= orig_sql_mode;
487
 
    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;
488
421
  }
489
422
  return result;
490
423
}
493
426
void Item_bool_func2::fix_length_and_dec()
494
427
{
495
428
  max_length= 1;                                     // Function returns 0 or 1
 
429
  THD *thd;
496
430
 
497
431
  /*
498
432
    As some compare functions are generated after sql_yacc,
501
435
  if (!args[0] || !args[1])
502
436
    return;
503
437
 
504
 
  /*
 
438
  /* 
505
439
    We allow to convert to Unicode character sets in some cases.
506
440
    The conditions when conversion is possible are:
507
441
    - arguments A and B have different charsets
508
442
    - A wins according to coercibility rules
509
443
    - character set of A is superset for character set of B
510
 
 
 
444
   
511
445
    If all of the above is true, then it's possible to convert
512
446
    B into the character set of A, and then compare according
513
447
    to the collation of A.
514
448
  */
515
449
 
516
 
 
 
450
  
517
451
  DTCollation coll;
518
452
  if (args[0]->result_type() == STRING_RESULT &&
519
453
      args[1]->result_type() == STRING_RESULT &&
520
454
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
521
455
    return;
522
 
 
 
456
    
523
457
  args[0]->cmp_context= args[1]->cmp_context=
524
458
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
525
459
  // Make a special case of compare with fields to get nicer DATE comparisons
530
464
    return;
531
465
  }
532
466
 
533
 
  Item_field *field_item= NULL;
 
467
  thd= current_thd;
534
468
 
535
469
  if (args[0]->real_item()->type() == FIELD_ITEM)
536
470
  {
537
 
    field_item= static_cast<Item_field*>(args[0]->real_item());
 
471
    Item_field *field_item= (Item_field*) (args[0]->real_item());
538
472
    if (field_item->field->can_be_compared_as_int64_t() &&
539
473
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
540
474
    {
541
 
      if (convert_constant_item(&getSession(), field_item, &args[1]))
 
475
      if (convert_constant_item(thd, field_item, &args[1]))
542
476
      {
543
477
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
544
478
                         INT_RESULT);           // Works for all types.
549
483
 
550
484
    if (args[1]->real_item()->type() == FIELD_ITEM)
551
485
    {
552
 
      field_item= static_cast<Item_field*>(args[1]->real_item());
 
486
      Item_field *field_item= (Item_field*) (args[1]->real_item());
553
487
      if (field_item->field->can_be_compared_as_int64_t() &&
554
488
          !(field_item->is_datetime() &&
555
489
            args[0]->result_type() == STRING_RESULT))
556
490
      {
557
 
        if (convert_constant_item(&getSession(), field_item, &args[0]))
 
491
        if (convert_constant_item(thd, field_item, &args[0]))
558
492
        {
559
493
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
560
494
                           INT_RESULT); // Works for all types.
572
506
{
573
507
  owner= item;
574
508
  func= comparator_matrix[type]
575
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
576
 
 
 
509
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
577
510
  switch (type) {
578
511
  case ROW_RESULT:
579
 
    {
580
 
      uint32_t n= (*a)->cols();
581
 
      if (n != (*b)->cols())
582
 
      {
583
 
        my_error(ER_OPERAND_COLUMNS, MYF(0), n);
584
 
        comparators= 0;
585
 
        return 1;
586
 
      }
587
 
      if (!(comparators= new Arg_comparator[n]))
588
 
        return 1;
589
 
      for (uint32_t i=0; i < n; i++)
590
 
      {
591
 
        if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
592
 
        {
593
 
          my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
594
 
          return 1;
595
 
        }
596
 
        comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
597
 
      }
598
 
      break;
599
 
    }
600
 
 
 
512
  {
 
513
    uint32_t n= (*a)->cols();
 
514
    if (n != (*b)->cols())
 
515
    {
 
516
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
 
517
      comparators= 0;
 
518
      return 1;
 
519
    }
 
520
    if (!(comparators= new Arg_comparator[n]))
 
521
      return 1;
 
522
    for (uint32_t i=0; i < n; i++)
 
523
    {
 
524
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
 
525
      {
 
526
        my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
 
527
        return 1;
 
528
      }
 
529
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
 
530
    }
 
531
    break;
 
532
  }
601
533
  case STRING_RESULT:
 
534
  {
 
535
    /*
 
536
      We must set cmp_charset here as we may be called from for an automatic
 
537
      generated item, like in natural join
 
538
    */
 
539
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
540
        cmp_collation.derivation == DERIVATION_NONE)
 
541
    {
 
542
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
 
543
      return 1;
 
544
    }
 
545
    if (cmp_collation.collation == &my_charset_bin)
602
546
    {
603
547
      /*
604
 
        We must set cmp_charset here as we may be called from for an automatic
605
 
        generated item, like in natural join
 
548
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
549
        without removing end space
606
550
      */
607
 
      if (cmp_collation.set((*a)->collation, (*b)->collation) ||
608
 
          cmp_collation.derivation == DERIVATION_NONE)
609
 
      {
610
 
        my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
611
 
        return 1;
612
 
      }
613
 
      if (cmp_collation.collation == &my_charset_bin)
614
 
      {
615
 
        /*
616
 
          We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
617
 
          without removing end space
618
 
        */
619
 
        if (func == &Arg_comparator::compare_string)
620
 
          func= &Arg_comparator::compare_binary_string;
621
 
        else if (func == &Arg_comparator::compare_e_string)
622
 
          func= &Arg_comparator::compare_e_binary_string;
 
551
      if (func == &Arg_comparator::compare_string)
 
552
        func= &Arg_comparator::compare_binary_string;
 
553
      else if (func == &Arg_comparator::compare_e_string)
 
554
        func= &Arg_comparator::compare_e_binary_string;
623
555
 
624
 
        /*
625
 
          As this is binary compassion, mark all fields that they can't be
626
 
          transformed. Otherwise we would get into trouble with comparisons
627
 
like:
628
 
WHERE col= 'j' AND col LIKE BINARY 'j'
629
 
which would be transformed to:
630
 
WHERE col= 'j'
 
556
      /*
 
557
        As this is binary compassion, mark all fields that they can't be
 
558
        transformed. Otherwise we would get into trouble with comparisons
 
559
        like:
 
560
        WHERE col= 'j' AND col LIKE BINARY 'j'
 
561
        which would be transformed to:
 
562
        WHERE col= 'j'
631
563
      */
632
 
        (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
633
 
        (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
634
 
      }
635
 
      break;
 
564
      (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
 
565
      (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
636
566
    }
 
567
    break;
 
568
  }
637
569
  case INT_RESULT:
638
 
    {
639
 
      if (func == &Arg_comparator::compare_int_signed)
640
 
      {
641
 
        if ((*a)->unsigned_flag)
642
 
          func= (((*b)->unsigned_flag)?
643
 
                 &Arg_comparator::compare_int_unsigned :
644
 
                 &Arg_comparator::compare_int_unsigned_signed);
645
 
        else if ((*b)->unsigned_flag)
646
 
          func= &Arg_comparator::compare_int_signed_unsigned;
647
 
      }
648
 
      else if (func== &Arg_comparator::compare_e_int)
649
 
      {
650
 
        if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
651
 
          func= &Arg_comparator::compare_e_int_diff_signedness;
652
 
      }
653
 
      break;
654
 
    }
 
570
  {
 
571
    if (func == &Arg_comparator::compare_int_signed)
 
572
    {
 
573
      if ((*a)->unsigned_flag)
 
574
        func= (((*b)->unsigned_flag)?
 
575
               &Arg_comparator::compare_int_unsigned :
 
576
               &Arg_comparator::compare_int_unsigned_signed);
 
577
      else if ((*b)->unsigned_flag)
 
578
        func= &Arg_comparator::compare_int_signed_unsigned;
 
579
    }
 
580
    else if (func== &Arg_comparator::compare_e_int)
 
581
    {
 
582
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
 
583
        func= &Arg_comparator::compare_e_int_diff_signedness;
 
584
    }
 
585
    break;
 
586
  }
655
587
  case DECIMAL_RESULT:
656
588
    break;
657
589
  case REAL_RESULT:
 
590
  {
 
591
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
658
592
    {
659
 
      if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
660
 
      {
661
 
        precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
662
 
        if (func == &Arg_comparator::compare_real)
663
 
          func= &Arg_comparator::compare_real_fixed;
664
 
        else if (func == &Arg_comparator::compare_e_real)
665
 
          func= &Arg_comparator::compare_e_real_fixed;
666
 
      }
667
 
      break;
 
593
      precision= 5 / log_10[cmax((*a)->decimals, (*b)->decimals) + 1];
 
594
      if (func == &Arg_comparator::compare_real)
 
595
        func= &Arg_comparator::compare_real_fixed;
 
596
      else if (func == &Arg_comparator::compare_e_real)
 
597
        func= &Arg_comparator::compare_e_real_fixed;
668
598
    }
669
 
  }
670
 
 
 
599
    break;
 
600
  }
 
601
  default:
 
602
    assert(0);
 
603
  }
671
604
  return 0;
672
605
}
673
606
 
675
608
/**
676
609
  @brief Convert date provided in a string to the int representation.
677
610
 
678
 
  @param[in]   session        thread handle
 
611
  @param[in]   thd        thread handle
679
612
  @param[in]   str        a string to convert
680
613
  @param[in]   warn_type  type of the timestamp for issuing the warning
681
614
  @param[in]   warn_name  field name for issuing the warning
694
627
    converted value. 0 on error and on zero-dates -- check 'failure'
695
628
*/
696
629
 
697
 
static int64_t
698
 
get_date_from_str(Session *session, String *str, type::timestamp_t warn_type,
 
630
static uint64_t
 
631
get_date_from_str(THD *thd, String *str, enum enum_drizzle_timestamp_type warn_type,
699
632
                  char *warn_name, bool *error_arg)
700
633
{
701
 
  int64_t value= 0;
702
 
  type::cut_t error= type::VALID;
703
 
  type::Time l_time;
704
 
  type::timestamp_t ret;
705
 
 
706
 
  ret= l_time.store(str->ptr(), str->length(),
707
 
                    (TIME_FUZZY_DATE | MODE_INVALID_DATES | (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
708
 
                    error);
709
 
 
710
 
  if (ret == type::DRIZZLE_TIMESTAMP_DATETIME || ret == type::DRIZZLE_TIMESTAMP_DATE)
 
634
  uint64_t value= 0;
 
635
  int error;
 
636
  DRIZZLE_TIME l_time;
 
637
  enum enum_drizzle_timestamp_type ret;
 
638
 
 
639
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
 
640
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
 
641
                        (thd->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
642
                       &error);
 
643
 
 
644
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
711
645
  {
712
646
    /*
713
647
      Do not return yet, we may still want to throw a "trailing garbage"
714
648
      warning.
715
649
    */
716
650
    *error_arg= false;
717
 
    l_time.convert(value);
 
651
    value= TIME_to_uint64_t_datetime(&l_time);
718
652
  }
719
653
  else
720
654
  {
721
655
    *error_arg= true;
722
 
    error= type::CUT;                                   /* force warning */
 
656
    error= 1;                                   /* force warning */
723
657
  }
724
658
 
725
 
  if (error != type::VALID)
726
 
  {
727
 
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
659
  if (error > 0)
 
660
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
728
661
                                 str->ptr(), str->length(),
729
662
                                 warn_type, warn_name);
730
 
  }
731
663
 
732
664
  return value;
733
665
}
750
682
         int result and the other item (b or a) is an item with string result.
751
683
         If the second item is a constant one then it's checked to be
752
684
         convertible to the DATE/DATETIME type. If the constant can't be
753
 
         converted to a DATE/DATETIME then an error is issued back to the Session.
 
685
         converted to a DATE/DATETIME then the compare_datetime() comparator
 
686
         isn't used and the warning about wrong DATE/DATETIME value is issued.
754
687
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
755
688
      the comparison is handled by other comparators.
756
 
 
757
689
    If the datetime comparator can be used and one the operands of the
758
690
    comparison is a string constant that was successfully converted to a
759
691
    DATE/DATETIME type then the result of the conversion is returned in the
766
698
*/
767
699
 
768
700
enum Arg_comparator::enum_date_cmp_type
769
 
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
770
 
                                     int64_t *const_value)
 
701
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
771
702
{
772
703
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
773
704
  Item *str_arg= 0, *date_arg= 0;
774
705
 
775
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
706
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
776
707
    return CMP_DATE_DFLT;
777
708
 
778
 
  if (in_a->is_datetime())
 
709
  if (a->is_datetime())
779
710
  {
780
 
    if (in_b->is_datetime())
781
 
    {
 
711
    if (b->is_datetime())
782
712
      cmp_type= CMP_DATE_WITH_DATE;
783
 
    }
784
 
    else if (in_b->result_type() == STRING_RESULT)
 
713
    else if (b->result_type() == STRING_RESULT)
785
714
    {
786
715
      cmp_type= CMP_DATE_WITH_STR;
787
 
      date_arg= in_a;
788
 
      str_arg= in_b;
 
716
      date_arg= a;
 
717
      str_arg= b;
789
718
    }
790
719
  }
791
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
720
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
792
721
  {
793
722
    cmp_type= CMP_STR_WITH_DATE;
794
 
    date_arg= in_b;
795
 
    str_arg= in_a;
 
723
    date_arg= b;
 
724
    str_arg= a;
796
725
  }
797
726
 
798
727
  if (cmp_type != CMP_DATE_DFLT)
805
734
        (str_arg->type() != Item::FUNC_ITEM ||
806
735
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
807
736
    {
808
 
      /*
809
 
       * OK, we are here if we've got a date field (or something which can be 
810
 
       * compared as a date field) on one side of the equation, and a constant
811
 
       * string on the other side.  In this case, we must verify that the constant
812
 
       * string expression can indeed be evaluated as a datetime.  If it cannot, 
813
 
       * we throw an error here and stop processsing.  Bad data should ALWAYS 
814
 
       * produce an error, and no implicit conversion or truncation should take place.
815
 
       *
816
 
       * If the conversion to a DateTime temporal is successful, then we convert
817
 
       * the Temporal instance to a uint64_t for the comparison operator, which
818
 
       * compares date(times) using int64_t semantics.
819
 
       *
820
 
       * @TODO
821
 
       *
822
 
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
823
 
       * from val_int(), not uint64_t...
824
 
       */
825
 
      int64_t value;
826
 
      String *str_val;
827
 
      String tmp;
828
 
      /* DateTime used to pick up as many string conversion possibilities as possible. */
829
 
      DateTime temporal;
 
737
      THD *thd= current_thd;
 
738
      uint64_t value;
 
739
      bool error;
 
740
      String tmp, *str_val= 0;
 
741
      enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
 
742
                              DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
830
743
 
831
744
      str_val= str_arg->val_str(&tmp);
832
 
      if (! str_val)
833
 
      {
834
 
        /* 
835
 
         * If we are here, it is most likely due to the comparison item
836
 
         * being a NULL.  Although this is incorrect (SQL demands that the term IS NULL
837
 
         * be used, not = NULL since no item can be equal to NULL).
838
 
         *
839
 
         * So, return gracefully.
840
 
         */
841
 
        return CMP_DATE_DFLT;
842
 
      }
843
 
      if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
844
 
      {
845
 
        /* Chuck an error. Bad datetime input. */
846
 
        my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
847
 
        return CMP_DATE_DFLT; /* :( What else can I return... */
848
 
      }
849
 
 
850
 
      /* String conversion was good.  Convert to an integer for comparison purposes. */
851
 
      temporal.to_int64_t(&value);
852
 
 
 
745
      if (str_arg->null_value)
 
746
        return CMP_DATE_DFLT;
 
747
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
 
748
      if (error)
 
749
        return CMP_DATE_DFLT;
853
750
      if (const_value)
854
751
        *const_value= value;
855
752
    }
858
755
}
859
756
 
860
757
 
 
758
/*
 
759
  Retrieves correct TIME value from the given item.
 
760
 
 
761
  SYNOPSIS
 
762
    get_time_value()
 
763
    thd                 thread handle
 
764
    item_arg   [in/out] item to retrieve TIME value from
 
765
    cache_arg  [in/out] pointer to place to store the cache item to
 
766
    warn_item  [in]     unused
 
767
    is_null    [out]    true <=> the item_arg is null
 
768
 
 
769
  DESCRIPTION
 
770
    Retrieves the correct TIME value from given item for comparison by the
 
771
    compare_datetime() function.
 
772
    If item's result can be compared as int64_t then its int value is used
 
773
    and a value returned by get_time function is used otherwise.
 
774
    If an item is a constant one then its value is cached and it isn't
 
775
    get parsed again. An Item_cache_int object is used for for cached values.
 
776
    It seamlessly substitutes the original item.  The cache item is marked as
 
777
    non-constant to prevent re-caching it again.
 
778
 
 
779
  RETURN
 
780
    obtained value
 
781
*/
 
782
 
 
783
uint64_t
 
784
get_time_value(THD *thd __attribute__((unused)),
 
785
               Item ***item_arg, Item **cache_arg,
 
786
               Item *warn_item __attribute__((unused)),
 
787
               bool *is_null)
 
788
{
 
789
  uint64_t value;
 
790
  Item *item= **item_arg;
 
791
  DRIZZLE_TIME ltime;
 
792
 
 
793
  if (item->result_as_int64_t())
 
794
  {
 
795
    value= item->val_int();
 
796
    *is_null= item->null_value;
 
797
  }
 
798
  else
 
799
  {
 
800
    *is_null= item->get_time(&ltime);
 
801
    value= !*is_null ? TIME_to_uint64_t_datetime(&ltime) : 0;
 
802
  }
 
803
  /*
 
804
    Do not cache GET_USER_VAR() function as its const_item() may return true
 
805
    for the current thread but it still may change during the execution.
 
806
  */
 
807
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
 
808
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
 
809
  {
 
810
    Item_cache_int *cache= new Item_cache_int();
 
811
    /* Mark the cache as non-const to prevent re-caching. */
 
812
    cache->set_used_tables(1);
 
813
    cache->store(item, value);
 
814
    *cache_arg= cache;
 
815
    *item_arg= cache_arg;
 
816
  }
 
817
  return value;
 
818
}
 
819
 
 
820
 
861
821
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
862
822
                                        Item **a1, Item **a2,
863
823
                                        Item_result type)
864
824
{
865
 
  enum_date_cmp_type cmp_type;
866
 
  int64_t const_value= -1;
 
825
  enum enum_date_cmp_type cmp_type;
 
826
  uint64_t const_value= (uint64_t)-1;
867
827
  a= a1;
868
828
  b= a2;
869
829
 
870
830
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
871
831
  {
 
832
    thd= current_thd;
872
833
    owner= owner_arg;
873
834
    a_type= (*a)->field_type();
874
835
    b_type= (*b)->field_type();
875
836
    a_cache= 0;
876
837
    b_cache= 0;
877
838
 
878
 
    if (const_value != -1)
 
839
    if (const_value != (uint64_t)-1)
879
840
    {
880
841
      Item_cache_int *cache= new Item_cache_int();
881
842
      /* Mark the cache as non-const to prevent re-caching. */
896
857
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
897
858
    func= &Arg_comparator::compare_datetime;
898
859
    get_value_func= &get_datetime_value;
899
 
 
 
860
    return 0;
 
861
  }
 
862
  else if (type == STRING_RESULT && (*a)->field_type() == DRIZZLE_TYPE_TIME &&
 
863
           (*b)->field_type() == DRIZZLE_TYPE_TIME)
 
864
  {
 
865
    /* Compare TIME values as integers. */
 
866
    thd= current_thd;
 
867
    owner= owner_arg;
 
868
    a_cache= 0;
 
869
    b_cache= 0;
 
870
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
 
871
    func= &Arg_comparator::compare_datetime;
 
872
    get_value_func= &get_time_value;
900
873
    return 0;
901
874
  }
902
875
 
906
879
 
907
880
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
908
881
{
 
882
  thd= current_thd;
909
883
  /* A caller will handle null values by itself. */
910
884
  owner= NULL;
911
885
  a= a1;
925
899
 
926
900
  SYNOPSIS
927
901
    get_datetime_value()
928
 
    session                 thread handle
 
902
    thd                 thread handle
929
903
    item_arg   [in/out] item to retrieve DATETIME value from
930
904
    cache_arg  [in/out] pointer to place to store the caching item to
931
905
    warn_item  [in]     item for issuing the conversion warning
949
923
    obtained value
950
924
*/
951
925
 
952
 
int64_t
953
 
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
 
926
uint64_t
 
927
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
954
928
                   Item *warn_item, bool *is_null)
955
929
{
956
 
  int64_t value= 0;
 
930
  uint64_t value= 0;
957
931
  String buf, *str= 0;
958
932
  Item *item= **item_arg;
959
933
 
968
942
      compare it with 100000000L - any DATE value should be less than it.
969
943
      Don't shift cached DATETIME values up for the second time.
970
944
    */
971
 
    if (f_type == DRIZZLE_TYPE_DATE ||
 
945
    if (f_type == DRIZZLE_TYPE_NEWDATE ||
972
946
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
973
947
      value*= 1000000L;
974
948
  }
977
951
    str= item->val_str(&buf);
978
952
    *is_null= item->null_value;
979
953
  }
980
 
 
981
954
  if (*is_null)
982
955
    return ~(uint64_t) 0;
983
 
 
984
956
  /*
985
957
    Convert strings to the integer DATE/DATETIME representation.
986
958
    Even if both dates provided in strings we can't compare them directly as
991
963
  {
992
964
    bool error;
993
965
    enum_field_types f_type= warn_item->field_type();
994
 
    type::timestamp_t t_type= f_type == DRIZZLE_TYPE_DATE ? type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME;
995
 
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
 
966
    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);
996
969
    /*
997
970
      If str did not contain a valid date according to the current
998
971
      SQL_MODE, get_date_from_str() has already thrown a warning,
1014
987
    *cache_arg= cache;
1015
988
    *item_arg= cache_arg;
1016
989
  }
1017
 
 
1018
990
  return value;
1019
991
}
1020
992
 
1045
1017
  uint64_t a_value, b_value;
1046
1018
 
1047
1019
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1048
 
  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);
1049
1021
  if (!is_nulls_eq && is_null)
1050
1022
  {
1051
1023
    if (owner)
1054
1026
  }
1055
1027
 
1056
1028
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1057
 
  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);
1058
1030
  if (is_null)
1059
1031
  {
1060
1032
    if (owner)
1068
1040
  /* Compare values. */
1069
1041
  if (is_nulls_eq)
1070
1042
    return (a_value == b_value);
1071
 
  return (a_value < b_value) ? -1 : ((a_value > b_value) ? 1 : 0);
 
1043
  return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
1072
1044
}
1073
1045
 
1074
1046
 
1109
1081
      owner->null_value= 0;
1110
1082
      uint32_t res1_length= res1->length();
1111
1083
      uint32_t res2_length= res2->length();
1112
 
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
 
1084
      int cmp= memcmp(res1->ptr(), res2->ptr(), cmin(res1_length,res2_length));
1113
1085
      return cmp ? cmp : (int) (res1_length - res2_length);
1114
1086
    }
1115
1087
  }
1171
1143
 
1172
1144
int Arg_comparator::compare_decimal()
1173
1145
{
1174
 
  type::Decimal value1;
1175
 
  type::Decimal *val1= (*a)->val_decimal(&value1);
 
1146
  my_decimal value1;
 
1147
  my_decimal *val1= (*a)->val_decimal(&value1);
1176
1148
  if (!(*a)->null_value)
1177
1149
  {
1178
 
    type::Decimal value2;
1179
 
    type::Decimal *val2= (*b)->val_decimal(&value2);
 
1150
    my_decimal value2;
 
1151
    my_decimal *val2= (*b)->val_decimal(&value2);
1180
1152
    if (!(*b)->null_value)
1181
1153
    {
1182
1154
      owner->null_value= 0;
1183
 
      return class_decimal_cmp(val1, val2);
 
1155
      return my_decimal_cmp(val1, val2);
1184
1156
    }
1185
1157
  }
1186
1158
  owner->null_value= 1;
1198
1170
 
1199
1171
int Arg_comparator::compare_e_decimal()
1200
1172
{
1201
 
  type::Decimal value1, value2;
1202
 
  type::Decimal *val1= (*a)->val_decimal(&value1);
1203
 
  type::Decimal *val2= (*b)->val_decimal(&value2);
 
1173
  my_decimal value1, value2;
 
1174
  my_decimal *val1= (*a)->val_decimal(&value1);
 
1175
  my_decimal *val2= (*b)->val_decimal(&value2);
1204
1176
  if ((*a)->null_value || (*b)->null_value)
1205
1177
    return test((*a)->null_value && (*b)->null_value);
1206
 
  return test(class_decimal_cmp(val1, val2) == 0);
 
1178
  return test(my_decimal_cmp(val1, val2) == 0);
1207
1179
}
1208
1180
 
1209
1181
 
1471
1443
}
1472
1444
 
1473
1445
 
1474
 
bool Item_in_optimizer::fix_left(Session *session, Item **)
 
1446
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
1475
1447
{
1476
 
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
 
1448
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
1477
1449
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1478
1450
    return 1;
1479
1451
 
1505
1477
}
1506
1478
 
1507
1479
 
1508
 
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
 
1480
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1509
1481
{
1510
1482
  assert(fixed == 0);
1511
 
  if (fix_left(session, ref))
 
1483
  if (fix_left(thd, ref))
1512
1484
    return true;
1513
1485
  if (args[0]->maybe_null)
1514
1486
    maybe_null=1;
1515
1487
 
1516
 
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
 
1488
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
1517
1489
    return true;
1518
1490
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1519
1491
  if (args[0]->cols() != sub->engine->cols())
1537
1509
  bool tmp;
1538
1510
  assert(fixed == 1);
1539
1511
  cache->store(args[0]);
1540
 
 
 
1512
  
1541
1513
  if (cache->null_value)
1542
1514
  {
1543
1515
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1565
1537
          We disable the predicates we've pushed down into subselect, run the
1566
1538
          subselect and see if it has produced any rows.
1567
1539
        */
1568
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
 
1540
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
1569
1541
        if (cache->cols() == 1)
1570
1542
        {
1571
1543
          item_subs->set_cond_guard_var(0, false);
1586
1558
            if (cache->element_index(i)->null_value)
1587
1559
              item_subs->set_cond_guard_var(i, false);
1588
1560
          }
1589
 
 
 
1561
          
1590
1562
          (void) args[1]->val_bool_result();
1591
1563
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1592
 
 
 
1564
          
1593
1565
          /* Turn all predicates back on */
1594
1566
          for (i= 0; i < ncols; i++)
1595
1567
            item_subs->set_cond_guard_var(i, true);
1613
1585
 
1614
1586
void Item_in_optimizer::cleanup()
1615
1587
{
1616
 
  item::function::Boolean::cleanup();
 
1588
  Item_bool_func::cleanup();
1617
1589
  if (!save_cache)
1618
1590
    cache= 0;
1619
1591
  return;
1660
1632
  if (!new_item)
1661
1633
    return 0;
1662
1634
  /*
1663
 
    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
1664
1636
    really transformed, i.e. when a new item has been created.
1665
1637
    Otherwise we'll be allocating a lot of unnecessary memory for
1666
1638
    change records at each execution.
1667
1639
  */
1668
1640
  if ((*args) != new_item)
1669
 
    getSession().change_item_tree(args, new_item);
 
1641
    current_thd->change_item_tree(args, new_item);
1670
1642
 
1671
1643
  /*
1672
1644
    Transform the right IN operand which should be an Item_in_subselect or a
1791
1763
void Item_func_interval::fix_length_and_dec()
1792
1764
{
1793
1765
  uint32_t rows= row->cols();
1794
 
 
 
1766
  
1795
1767
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1796
1768
                            DECIMAL_RESULT) ||
1797
1769
                           (row->element_index(0)->result_type() ==
1808
1780
 
1809
1781
    if (not_null_consts &&
1810
1782
        (intervals=
1811
 
          (interval_range*) memory::sql_alloc(sizeof(interval_range) * (rows - 1))))
 
1783
          (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
1812
1784
    {
1813
1785
      if (use_decimal_comparison)
1814
1786
      {
1821
1793
          {
1822
1794
            range->type= DECIMAL_RESULT;
1823
1795
            range->dec.init();
1824
 
            type::Decimal *dec= el->val_decimal(&range->dec);
 
1796
            my_decimal *dec= el->val_decimal(&range->dec);
1825
1797
            if (dec != &range->dec)
1826
1798
            {
1827
1799
              range->dec= *dec;
1871
1843
{
1872
1844
  assert(fixed == 1);
1873
1845
  double value;
1874
 
  type::Decimal dec_buf, *dec= NULL;
 
1846
  my_decimal dec_buf, *dec= NULL;
1875
1847
  uint32_t i;
1876
1848
 
1877
1849
  if (use_decimal_comparison)
1879
1851
    dec= row->element_index(0)->val_decimal(&dec_buf);
1880
1852
    if (row->element_index(0)->null_value)
1881
1853
      return -1;
1882
 
    class_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
 
1854
    my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
1883
1855
  }
1884
1856
  else
1885
1857
  {
1904
1876
        and we are comparing against a decimal
1905
1877
      */
1906
1878
      if (dec && range->type == DECIMAL_RESULT)
1907
 
        cmp_result= class_decimal_cmp(&range->dec, dec) <= 0;
 
1879
        cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
1908
1880
      else
1909
1881
        cmp_result= (range->dbl <= value);
1910
1882
      if (cmp_result)
1914
1886
    }
1915
1887
    interval_range *range= intervals+start;
1916
1888
    return ((dec && range->type == DECIMAL_RESULT) ?
1917
 
            class_decimal_cmp(dec, &range->dec) < 0 :
 
1889
            my_decimal_cmp(dec, &range->dec) < 0 :
1918
1890
            value < range->dbl) ? 0 : start + 1;
1919
1891
  }
1920
1892
 
1925
1897
        ((el->result_type() == DECIMAL_RESULT) ||
1926
1898
         (el->result_type() == INT_RESULT)))
1927
1899
    {
1928
 
      type::Decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
 
1900
      my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
1929
1901
      /* Skip NULL ranges. */
1930
1902
      if (el->null_value)
1931
1903
        continue;
1932
 
      if (class_decimal_cmp(e_dec, dec) > 0)
 
1904
      if (my_decimal_cmp(e_dec, dec) > 0)
1933
1905
        return i - 1;
1934
1906
    }
1935
 
    else
 
1907
    else 
1936
1908
    {
1937
1909
      double val= el->val_real();
1938
1910
      /* Skip NULL ranges. */
1954
1926
    The function saves in ref the pointer to the item or to a newly created
1955
1927
    item that is considered as a replacement for the original one.
1956
1928
 
1957
 
  @param session     reference to the global context of the query thread
 
1929
  @param thd     reference to the global context of the query thread
1958
1930
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1959
1931
                 item is to be assigned
1960
1932
 
1974
1946
    1   got error
1975
1947
*/
1976
1948
 
1977
 
bool Item_func_between::fix_fields(Session *session, Item **ref)
 
1949
bool Item_func_between::fix_fields(THD *thd, Item **ref)
1978
1950
{
1979
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
1951
  if (Item_func_opt_neg::fix_fields(thd, ref))
1980
1952
    return 1;
1981
1953
 
1982
 
  session->lex->current_select->between_count++;
 
1954
  thd->lex->current_select->between_count++;
1983
1955
 
1984
1956
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1985
1957
  if (pred_level && !negated)
1999
1971
  max_length= 1;
2000
1972
  int i;
2001
1973
  bool datetime_found= false;
 
1974
  int time_items_found= 0;
2002
1975
  compare_as_dates= true;
 
1976
  THD *thd= current_thd;
2003
1977
 
2004
1978
  /*
2005
1979
    As some compare functions are generated after sql_yacc,
2027
2001
        datetime_found= true;
2028
2002
        continue;
2029
2003
      }
 
2004
      if (args[i]->field_type() == DRIZZLE_TYPE_TIME &&
 
2005
          args[i]->result_as_int64_t())
 
2006
        time_items_found++;
2030
2007
    }
2031
2008
  }
2032
2009
  if (!datetime_found)
2037
2014
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2038
2015
    le_cmp.set_datetime_cmp_func(args, args + 2);
2039
2016
  }
2040
 
  else if (args[0]->real_item()->type() == FIELD_ITEM)
 
2017
  else if (time_items_found == 3)
 
2018
  {
 
2019
    /* Compare TIME items as integers. */
 
2020
    cmp_type= INT_RESULT;
 
2021
  }
 
2022
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
 
2023
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
2041
2024
  {
2042
2025
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2043
2026
    if (field_item->field->can_be_compared_as_int64_t())
2046
2029
        The following can't be recoded with || as convert_constant_item
2047
2030
        changes the argument
2048
2031
      */
2049
 
      if (convert_constant_item(&getSession(), field_item, &args[1]))
 
2032
      if (convert_constant_item(thd, field_item, &args[1]))
2050
2033
        cmp_type=INT_RESULT;                    // Works for all types.
2051
 
      if (convert_constant_item(&getSession(), field_item, &args[2]))
 
2034
      if (convert_constant_item(thd, field_item, &args[2]))
2052
2035
        cmp_type=INT_RESULT;                    // Works for all types.
2053
2036
    }
2054
2037
  }
2107
2090
  {
2108
2091
    int64_t value=args[0]->val_int(), a, b;
2109
2092
    if ((null_value=args[0]->null_value))
2110
 
      return 0;
 
2093
      return 0;                                 /* purecov: inspected */
2111
2094
    a=args[1]->val_int();
2112
2095
    b=args[2]->val_int();
2113
2096
    if (!args[1]->null_value && !args[2]->null_value)
2125
2108
  }
2126
2109
  else if (cmp_type == DECIMAL_RESULT)
2127
2110
  {
2128
 
    type::Decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
 
2111
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2129
2112
               a_buf, *a_dec, b_buf, *b_dec;
2130
2113
    if ((null_value=args[0]->null_value))
2131
 
      return 0;
 
2114
      return 0;                                 /* purecov: inspected */
2132
2115
    a_dec= args[1]->val_decimal(&a_buf);
2133
2116
    b_dec= args[2]->val_decimal(&b_buf);
2134
2117
    if (!args[1]->null_value && !args[2]->null_value)
2135
 
      return (int64_t) ((class_decimal_cmp(dec, a_dec) >= 0 &&
2136
 
                          class_decimal_cmp(dec, b_dec) <= 0) != negated);
 
2118
      return (int64_t) ((my_decimal_cmp(dec, a_dec) >= 0 &&
 
2119
                          my_decimal_cmp(dec, b_dec) <= 0) != negated);
2137
2120
    if (args[1]->null_value && args[2]->null_value)
2138
2121
      null_value=1;
2139
2122
    else if (args[1]->null_value)
2140
 
      null_value= (class_decimal_cmp(dec, b_dec) <= 0);
 
2123
      null_value= (my_decimal_cmp(dec, b_dec) <= 0);
2141
2124
    else
2142
 
      null_value= (class_decimal_cmp(dec, a_dec) >= 0);
 
2125
      null_value= (my_decimal_cmp(dec, a_dec) >= 0);
2143
2126
  }
2144
2127
  else
2145
2128
  {
2146
2129
    double value= args[0]->val_real(),a,b;
2147
2130
    if ((null_value=args[0]->null_value))
2148
 
      return 0;
 
2131
      return 0;                                 /* purecov: inspected */
2149
2132
    a= args[1]->val_real();
2150
2133
    b= args[2]->val_real();
2151
2134
    if (!args[1]->null_value && !args[2]->null_value)
2182
2165
Item_func_ifnull::fix_length_and_dec()
2183
2166
{
2184
2167
  agg_result_type(&hybrid_type, args, 2);
2185
 
  maybe_null= args[1]->maybe_null;
2186
 
  decimals= max(args[0]->decimals, args[1]->decimals);
 
2168
  maybe_null=args[1]->maybe_null;
 
2169
  decimals= cmax(args[0]->decimals, args[1]->decimals);
2187
2170
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2188
2171
 
2189
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
 
2172
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
2190
2173
  {
2191
2174
    int len0= args[0]->max_length - args[0]->decimals
2192
2175
      - (args[0]->unsigned_flag ? 0 : 1);
2194
2177
    int len1= args[1]->max_length - args[1]->decimals
2195
2178
      - (args[1]->unsigned_flag ? 0 : 1);
2196
2179
 
2197
 
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
 
2180
    max_length= cmax(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2198
2181
  }
2199
2182
  else
2200
 
  {
2201
 
    max_length= max(args[0]->max_length, args[1]->max_length);
2202
 
  }
 
2183
    max_length= cmax(args[0]->max_length, args[1]->max_length);
2203
2184
 
2204
 
  switch (hybrid_type)
2205
 
  {
 
2185
  switch (hybrid_type) {
2206
2186
  case STRING_RESULT:
2207
2187
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2208
2188
    break;
2209
 
 
2210
2189
  case DECIMAL_RESULT:
2211
2190
  case REAL_RESULT:
2212
2191
    break;
2213
 
 
2214
2192
  case INT_RESULT:
2215
2193
    decimals= 0;
2216
2194
    break;
2217
 
 
2218
2195
  case ROW_RESULT:
 
2196
  default:
2219
2197
    assert(0);
2220
2198
  }
2221
 
 
2222
2199
  cached_field_type= agg_field_type(args, 2);
2223
2200
}
2224
2201
 
2225
2202
 
2226
2203
uint32_t Item_func_ifnull::decimal_precision() const
2227
2204
{
2228
 
  int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2229
 
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
2205
  int max_int_part=cmax(args[0]->decimal_int_part(),args[1]->decimal_int_part());
 
2206
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2230
2207
}
2231
2208
 
2232
2209
 
2233
 
enum_field_types Item_func_ifnull::field_type() const
 
2210
enum_field_types Item_func_ifnull::field_type() const 
2234
2211
{
2235
2212
  return cached_field_type;
2236
2213
}
2273
2250
}
2274
2251
 
2275
2252
 
2276
 
type::Decimal *Item_func_ifnull::decimal_op(type::Decimal *decimal_value)
 
2253
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
2277
2254
{
2278
2255
  assert(fixed == 1);
2279
 
  type::Decimal *value= args[0]->val_decimal(decimal_value);
 
2256
  my_decimal *value= args[0]->val_decimal(decimal_value);
2280
2257
  if (!args[0]->null_value)
2281
2258
  {
2282
2259
    null_value= 0;
2316
2293
    The function saves in ref the pointer to the item or to a newly created
2317
2294
    item that is considered as a replacement for the original one.
2318
2295
 
2319
 
  @param session     reference to the global context of the query thread
 
2296
  @param thd     reference to the global context of the query thread
2320
2297
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2321
2298
                 item is to be assigned
2322
2299
 
2335
2312
*/
2336
2313
 
2337
2314
bool
2338
 
Item_func_if::fix_fields(Session *session, Item **ref)
 
2315
Item_func_if::fix_fields(THD *thd, Item **ref)
2339
2316
{
2340
2317
  assert(fixed == 0);
2341
2318
  args[0]->top_level_item();
2342
2319
 
2343
 
  if (Item_func::fix_fields(session, ref))
 
2320
  if (Item_func::fix_fields(thd, ref))
2344
2321
    return 1;
2345
2322
 
2346
2323
  not_null_tables_cache= (args[1]->not_null_tables() &
2353
2330
void
2354
2331
Item_func_if::fix_length_and_dec()
2355
2332
{
2356
 
  maybe_null= args[1]->maybe_null || args[2]->maybe_null;
2357
 
  decimals= max(args[1]->decimals, args[2]->decimals);
2358
 
  unsigned_flag= args[1]->unsigned_flag && args[2]->unsigned_flag;
 
2333
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
 
2334
  decimals= cmax(args[1]->decimals, args[2]->decimals);
 
2335
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2359
2336
 
2360
 
  enum Item_result arg1_type= args[1]->result_type();
2361
 
  enum Item_result arg2_type= args[2]->result_type();
2362
 
  bool null1= args[1]->const_item() && args[1]->null_value;
2363
 
  bool null2= args[2]->const_item() && args[2]->null_value;
 
2337
  enum Item_result arg1_type=args[1]->result_type();
 
2338
  enum Item_result arg2_type=args[2]->result_type();
 
2339
  bool null1=args[1]->const_item() && args[1]->null_value;
 
2340
  bool null2=args[2]->const_item() && args[2]->null_value;
2364
2341
 
2365
2342
  if (null1)
2366
2343
  {
2398
2375
    int len2= args[2]->max_length - args[2]->decimals
2399
2376
      - (args[2]->unsigned_flag ? 0 : 1);
2400
2377
 
2401
 
    max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2378
    max_length=cmax(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2402
2379
  }
2403
2380
  else
2404
 
    max_length= max(args[1]->max_length, args[2]->max_length);
 
2381
    max_length= cmax(args[1]->max_length, args[2]->max_length);
2405
2382
}
2406
2383
 
2407
2384
 
2408
2385
uint32_t Item_func_if::decimal_precision() const
2409
2386
{
2410
 
  int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2411
 
                  decimals);
2412
 
  return min(precision, DECIMAL_MAX_PRECISION);
 
2387
  int precision=(cmax(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
 
2388
                 decimals);
 
2389
  return cmin(precision, DECIMAL_MAX_PRECISION);
2413
2390
}
2414
2391
 
2415
2392
 
2446
2423
}
2447
2424
 
2448
2425
 
2449
 
type::Decimal *
2450
 
Item_func_if::val_decimal(type::Decimal *decimal_value)
 
2426
my_decimal *
 
2427
Item_func_if::val_decimal(my_decimal *decimal_value)
2451
2428
{
2452
2429
  assert(fixed == 1);
2453
2430
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
2454
 
  type::Decimal *value= arg->val_decimal(decimal_value);
 
2431
  my_decimal *value= arg->val_decimal(decimal_value);
2455
2432
  null_value= arg->null_value;
2456
2433
  return value;
2457
2434
}
2531
2508
}
2532
2509
 
2533
2510
 
2534
 
type::Decimal *
2535
 
Item_func_nullif::val_decimal(type::Decimal * decimal_value)
 
2511
my_decimal *
 
2512
Item_func_nullif::val_decimal(my_decimal * decimal_value)
2536
2513
{
2537
2514
  assert(fixed == 1);
2538
 
  type::Decimal *res;
 
2515
  my_decimal *res;
2539
2516
  if (!cmp.compare())
2540
2517
  {
2541
2518
    null_value=1;
2550
2527
bool
2551
2528
Item_func_nullif::is_null()
2552
2529
{
2553
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
 
2530
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
2554
2531
}
2555
2532
 
2556
2533
 
2575
2552
           failed
2576
2553
*/
2577
2554
 
2578
 
Item *Item_func_case::find_item(String *)
 
2555
Item *Item_func_case::find_item(String *str __attribute__((unused)))
2579
2556
{
2580
2557
  uint32_t value_added_map= 0;
2581
2558
 
2596
2573
    {
2597
2574
      cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2598
2575
      assert(cmp_type != ROW_RESULT);
2599
 
      assert(cmp_items[(uint32_t)cmp_type]);
2600
 
      if (!(value_added_map & (1<<(uint32_t)cmp_type)))
 
2576
      assert(cmp_items[(uint)cmp_type]);
 
2577
      if (!(value_added_map & (1<<(uint)cmp_type)))
2601
2578
      {
2602
 
        cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
 
2579
        cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2603
2580
        if ((null_value=args[first_expr_num]->null_value))
2604
2581
          return else_expr_num != -1 ? args[else_expr_num] : 0;
2605
 
        value_added_map|= 1<<(uint32_t)cmp_type;
 
2582
        value_added_map|= 1<<(uint)cmp_type;
2606
2583
      }
2607
 
      if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
 
2584
      if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2608
2585
        return args[i + 1];
2609
2586
    }
2610
2587
  }
2668
2645
}
2669
2646
 
2670
2647
 
2671
 
type::Decimal *Item_func_case::val_decimal(type::Decimal *decimal_value)
 
2648
my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
2672
2649
{
2673
2650
  assert(fixed == 1);
2674
2651
  char buff[MAX_FIELD_WIDTH];
2675
2652
  String dummy_str(buff, sizeof(buff), default_charset());
2676
2653
  Item *item= find_item(&dummy_str);
2677
 
  type::Decimal *res;
 
2654
  my_decimal *res;
2678
2655
 
2679
2656
  if (!item)
2680
2657
  {
2688
2665
}
2689
2666
 
2690
2667
 
2691
 
bool Item_func_case::fix_fields(Session *session, Item **ref)
 
2668
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2692
2669
{
2693
2670
  /*
2694
2671
    buff should match stack usage from
2695
2672
    Item_func_case::val_int() -> Item_func_case::find_item()
2696
2673
  */
2697
 
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
2698
 
                     +sizeof(double)*2+sizeof(int64_t)*2];
2699
 
  bool res= Item_func::fix_fields(session, ref);
 
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);
2700
2676
  /*
2701
2677
    Call check_stack_overrun after fix_fields to be sure that stack variable
2702
2678
    is not optimized away
2703
2679
  */
2704
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
2680
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2705
2681
    return true;                                // Fatal error flag is set!
2706
2682
  return res;
2707
2683
}
2717
2693
 
2718
2694
void Item_func_case::agg_num_lengths(Item *arg)
2719
2695
{
2720
 
  uint32_t len= class_decimal_length_to_precision(arg->max_length, arg->decimals,
 
2696
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2721
2697
                                           arg->unsigned_flag) - arg->decimals;
2722
 
  set_if_bigger(max_length, len);
 
2698
  set_if_bigger(max_length, len); 
2723
2699
  set_if_bigger(decimals, arg->decimals);
2724
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
 
2700
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
2725
2701
}
2726
2702
 
2727
2703
 
2730
2706
  Item **agg;
2731
2707
  uint32_t nagg;
2732
2708
  uint32_t found_types= 0;
2733
 
  if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
 
2709
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2734
2710
    return;
2735
 
 
 
2711
  
2736
2712
  /*
2737
2713
    Aggregate all THEN and ELSE expression types
2738
2714
    and collations when string result
2739
2715
  */
2740
 
 
 
2716
  
2741
2717
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2742
2718
    agg[nagg]= args[nagg*2+1];
2743
 
 
 
2719
  
2744
2720
  if (else_expr_num != -1)
2745
2721
    agg[nagg++]= args[else_expr_num];
2746
 
 
 
2722
  
2747
2723
  agg_result_type(&cached_result_type, agg, nagg);
2748
2724
  if ((cached_result_type == STRING_RESULT) &&
2749
2725
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2750
2726
    return;
2751
 
 
 
2727
  
2752
2728
  cached_field_type= agg_field_type(agg, nagg);
2753
2729
  /*
2754
2730
    Aggregate first expression and all THEN expression types
2756
2732
  */
2757
2733
  if (first_expr_num != -1)
2758
2734
  {
 
2735
    uint32_t i;
2759
2736
    agg[0]= args[first_expr_num];
2760
2737
    left_result_type= agg[0]->result_type();
2761
2738
 
2765
2742
    if (!(found_types= collect_cmp_types(agg, nagg)))
2766
2743
      return;
2767
2744
 
2768
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2745
    for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2769
2746
    {
2770
2747
      if (found_types & (1 << i) && !cmp_items[i])
2771
2748
      {
2783
2760
 
2784
2761
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2785
2762
    maybe_null=1;
2786
 
 
 
2763
  
2787
2764
  max_length=0;
2788
2765
  decimals=0;
2789
2766
  unsigned_flag= true;
2798
2775
  {
2799
2776
    for (uint32_t i= 0; i < ncases; i+= 2)
2800
2777
      agg_num_lengths(args[i + 1]);
2801
 
    if (else_expr_num != -1)
 
2778
    if (else_expr_num != -1) 
2802
2779
      agg_num_lengths(args[else_expr_num]);
2803
 
    max_length= class_decimal_precision_to_length(max_length + decimals, decimals,
 
2780
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2804
2781
                                               unsigned_flag);
2805
2782
  }
2806
2783
}
2812
2789
  for (uint32_t i=0 ; i < ncases ; i+=2)
2813
2790
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2814
2791
 
2815
 
  if (else_expr_num != -1)
 
2792
  if (else_expr_num != -1) 
2816
2793
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2817
 
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
2794
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2818
2795
}
2819
2796
 
2820
2797
 
2851
2828
 
2852
2829
void Item_func_case::cleanup()
2853
2830
{
 
2831
  uint32_t i;
2854
2832
  Item_func::cleanup();
2855
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2833
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2856
2834
  {
2857
2835
    delete cmp_items[i];
2858
2836
    cmp_items[i]= 0;
2859
2837
  }
 
2838
  return;
2860
2839
}
2861
2840
 
2862
2841
 
2907
2886
}
2908
2887
 
2909
2888
 
2910
 
type::Decimal *Item_func_coalesce::decimal_op(type::Decimal *decimal_value)
 
2889
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
2911
2890
{
2912
2891
  assert(fixed == 1);
2913
2892
  null_value= 0;
2914
2893
  for (uint32_t i= 0; i < arg_count; i++)
2915
2894
  {
2916
 
    type::Decimal *res= args[i]->val_decimal(decimal_value);
 
2895
    my_decimal *res= args[i]->val_decimal(decimal_value);
2917
2896
    if (!args[i]->null_value)
2918
2897
      return res;
2919
2898
  }
2926
2905
{
2927
2906
  cached_field_type= agg_field_type(args, arg_count);
2928
2907
  agg_result_type(&hybrid_type, args, arg_count);
2929
 
 
2930
2908
  switch (hybrid_type) {
2931
2909
  case STRING_RESULT:
2932
2910
    count_only_length();
2933
2911
    decimals= NOT_FIXED_DEC;
2934
2912
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2935
2913
    break;
2936
 
 
2937
2914
  case DECIMAL_RESULT:
2938
2915
    count_decimal_length();
2939
2916
    break;
2940
 
 
2941
2917
  case REAL_RESULT:
2942
2918
    count_real_length();
2943
2919
    break;
2944
 
 
2945
2920
  case INT_RESULT:
2946
2921
    count_only_length();
2947
2922
    decimals= 0;
2948
2923
    break;
2949
 
 
2950
2924
  case ROW_RESULT:
 
2925
  default:
2951
2926
    assert(0);
2952
2927
  }
2953
2928
}
3005
2980
 
3006
2981
 
3007
2982
/*
3008
 
  Compare two integers in IN value list format (packed_int64_t)
 
2983
  Compare two integers in IN value list format (packed_int64_t) 
3009
2984
 
3010
2985
  SYNOPSIS
3011
2986
    cmp_int64_t()
3027
3002
    0           left argument is equal to the right argument.
3028
3003
    1           left argument is greater than the right argument.
3029
3004
*/
3030
 
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3031
 
                in_int64_t::packed_int64_t *b)
 
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)
3032
3008
{
3033
3009
  if (a->unsigned_flag != b->unsigned_flag)
3034
 
  {
3035
 
    /*
3036
 
      One of the args is unsigned and is too big to fit into the
 
3010
  { 
 
3011
    /* 
 
3012
      One of the args is unsigned and is too big to fit into the 
3037
3013
      positive signed range. Report no match.
3038
 
    */
 
3014
    */  
3039
3015
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3040
3016
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3041
3017
      return a->unsigned_flag ? 1 : -1;
3042
3018
    /*
3043
 
      Although the signedness differs both args can fit into the signed
 
3019
      Although the signedness differs both args can fit into the signed 
3044
3020
      positive range. Make them signed and compare as usual.
3045
 
    */
 
3021
    */  
3046
3022
    return cmp_longs (a->val, b->val);
3047
3023
  }
3048
3024
  if (a->unsigned_flag)
3051
3027
    return cmp_longs (a->val, b->val);
3052
3028
}
3053
3029
 
3054
 
static int cmp_double(void *, double *a, double *b)
 
3030
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
3055
3031
{
3056
3032
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3057
3033
}
3058
3034
 
3059
 
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
 
3035
static int cmp_row(void *cmp_arg __attribute__((unused)), cmp_item_row *a, cmp_item_row *b)
3060
3036
{
3061
3037
  return a->compare(b);
3062
3038
}
3063
3039
 
3064
3040
 
3065
 
static int cmp_decimal(void *, type::Decimal *a, type::Decimal *b)
 
3041
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
3066
3042
{
3067
3043
  /*
3068
3044
    We need call of fixing buffer pointer, because fast sort just copy
3070
3046
  */
3071
3047
  a->fix_buffer_pointer();
3072
3048
  b->fix_buffer_pointer();
3073
 
  return class_decimal_cmp(a, b);
3074
 
}
3075
 
 
3076
 
 
3077
 
void in_vector::sort()
3078
 
{
3079
 
  internal::my_qsort2(base,used_count,size,compare, (void *) collation);
 
3049
  return my_decimal_cmp(a, b);
3080
3050
}
3081
3051
 
3082
3052
 
3111
3081
{
3112
3082
  if (base)
3113
3083
  {
3114
 
    // base was allocated with help of memory::sql_alloc => following is OK
 
3084
    // base was allocated with help of sql_alloc => following is OK
3115
3085
    for (uint32_t i=0 ; i < count ; i++)
3116
3086
      ((String*) base)[i].free();
3117
3087
  }
3145
3115
  return (unsigned char*) item->val_str(&tmp);
3146
3116
}
3147
3117
 
3148
 
in_row::in_row(uint32_t elements, Item *)
 
3118
in_row::in_row(uint32_t elements, Item * item __attribute__((unused)))
3149
3119
{
3150
3120
  base= (char*) new cmp_item_row[count= elements];
3151
3121
  size= sizeof(cmp_item_row);
3178
3148
  return;
3179
3149
}
3180
3150
 
3181
 
in_int64_t::in_int64_t(uint32_t elements) :
3182
 
  in_vector(elements, sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
 
3151
in_int64_t::in_int64_t(uint32_t elements)
 
3152
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3183
3153
{}
3184
3154
 
3185
3155
void in_int64_t::set(uint32_t pos,Item *item)
3186
3156
{
3187
3157
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3188
 
 
 
3158
  
3189
3159
  buff->val= item->val_int();
3190
3160
  buff->unsigned_flag= item->unsigned_flag;
3191
3161
}
3199
3169
  return (unsigned char*) &tmp;
3200
3170
}
3201
3171
 
3202
 
void in_datetime::set(uint32_t pos, Item *item)
 
3172
void in_datetime::set(uint32_t pos,Item *item)
3203
3173
{
3204
3174
  Item **tmp_item= &item;
3205
3175
  bool is_null;
3206
3176
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3207
3177
 
3208
 
  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);
3209
3179
  buff->unsigned_flag= 1L;
3210
3180
}
3211
3181
 
3213
3183
{
3214
3184
  bool is_null;
3215
3185
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3216
 
  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);
3217
3187
  if (item->null_value)
3218
3188
    return 0;
3219
3189
  tmp.unsigned_flag= 1L;
3233
3203
{
3234
3204
  tmp= item->val_real();
3235
3205
  if (item->null_value)
3236
 
    return 0;
 
3206
    return 0;                                   /* purecov: inspected */
3237
3207
  return (unsigned char*) &tmp;
3238
3208
}
3239
3209
 
3240
3210
 
3241
3211
in_decimal::in_decimal(uint32_t elements)
3242
 
  :in_vector(elements, sizeof(type::Decimal),(qsort2_cmp) cmp_decimal, 0)
 
3212
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3243
3213
{}
3244
3214
 
3245
3215
 
3246
3216
void in_decimal::set(uint32_t pos, Item *item)
3247
3217
{
3248
 
  /* as far as 'item' is constant, we can store reference on type::Decimal */
3249
 
  type::Decimal *dec= ((type::Decimal *)base) + pos;
 
3218
  /* as far as 'item' is constant, we can store reference on my_decimal */
 
3219
  my_decimal *dec= ((my_decimal *)base) + pos;
3250
3220
  dec->len= DECIMAL_BUFF_LENGTH;
3251
3221
  dec->fix_buffer_pointer();
3252
 
  type::Decimal *res= item->val_decimal(dec);
3253
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
 
3222
  my_decimal *res= item->val_decimal(dec);
 
3223
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
3254
3224
  if (!item->null_value && res != dec)
3255
 
    class_decimal2decimal(res, dec);
 
3225
    my_decimal2decimal(res, dec);
3256
3226
}
3257
3227
 
3258
3228
 
3259
3229
unsigned char *in_decimal::get_value(Item *item)
3260
3230
{
3261
 
  type::Decimal *result= item->val_decimal(&val);
 
3231
  my_decimal *result= item->val_decimal(&val);
3262
3232
  if (item->null_value)
3263
3233
    return 0;
3264
3234
  return (unsigned char *)result;
3271
3241
  switch (type) {
3272
3242
  case STRING_RESULT:
3273
3243
    return new cmp_item_sort_string(cs);
3274
 
 
3275
3244
  case INT_RESULT:
3276
3245
    return new cmp_item_int;
3277
 
 
3278
3246
  case REAL_RESULT:
3279
3247
    return new cmp_item_real;
3280
 
 
3281
3248
  case ROW_RESULT:
3282
3249
    return new cmp_item_row;
3283
 
 
3284
3250
  case DECIMAL_RESULT:
3285
3251
    return new cmp_item_decimal;
 
3252
  default:
 
3253
    assert(0);
 
3254
    break;
3286
3255
  }
3287
 
 
3288
3256
  return 0; // to satisfy compiler :)
3289
3257
}
3290
3258
 
3327
3295
void cmp_item_row::alloc_comparators()
3328
3296
{
3329
3297
  if (!comparators)
3330
 
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
 
3298
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
3331
3299
}
3332
3300
 
3333
3301
 
3363
3331
    return;
3364
3332
  }
3365
3333
  n= tmpl->n;
3366
 
  if ((comparators= (cmp_item **) memory::sql_alloc(sizeof(cmp_item *)*n)))
 
3334
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
3367
3335
  {
3368
3336
    item->bring_value();
3369
3337
    item->null_value= 0;
3417
3385
 
3418
3386
void cmp_item_decimal::store_value(Item *item)
3419
3387
{
3420
 
  type::Decimal *val= item->val_decimal(&value);
 
3388
  my_decimal *val= item->val_decimal(&value);
3421
3389
  /* val may be zero if item is nnull */
3422
3390
  if (val && val != &value)
3423
 
    class_decimal2decimal(val, &value);
 
3391
    my_decimal2decimal(val, &value);
3424
3392
}
3425
3393
 
3426
3394
 
3427
3395
int cmp_item_decimal::cmp(Item *arg)
3428
3396
{
3429
 
  type::Decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
 
3397
  my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
3430
3398
  if (arg->null_value)
3431
3399
    return 1;
3432
 
  return class_decimal_cmp(&value, tmp);
 
3400
  return my_decimal_cmp(&value, tmp);
3433
3401
}
3434
3402
 
3435
3403
 
3436
3404
int cmp_item_decimal::compare(cmp_item *arg)
3437
3405
{
3438
3406
  cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
3439
 
  return class_decimal_cmp(&value, &l_cmp->value);
 
3407
  return my_decimal_cmp(&value, &l_cmp->value);
3440
3408
}
3441
3409
 
3442
3410
 
3450
3418
{
3451
3419
  bool is_null;
3452
3420
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3453
 
  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);
3454
3422
}
3455
3423
 
3456
3424
 
3459
3427
  bool is_null;
3460
3428
  Item **tmp_item= &arg;
3461
3429
  return value !=
3462
 
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3430
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3463
3431
}
3464
3432
 
3465
3433
 
3496
3464
    The function saves in ref the pointer to the item or to a newly created
3497
3465
    item that is considered as a replacement for the original one.
3498
3466
 
3499
 
  @param session     reference to the global context of the query thread
 
3467
  @param thd     reference to the global context of the query thread
3500
3468
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3501
3469
                 item is to be assigned
3502
3470
 
3517
3485
*/
3518
3486
 
3519
3487
bool
3520
 
Item_func_in::fix_fields(Session *session, Item **ref)
 
3488
Item_func_in::fix_fields(THD *thd, Item **ref)
3521
3489
{
3522
3490
  Item **arg, **arg_end;
3523
3491
 
3524
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
3492
  if (Item_func_opt_neg::fix_fields(thd, ref))
3525
3493
    return 1;
3526
3494
 
3527
3495
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3549
3517
{
3550
3518
  Item **arg, **arg_end;
3551
3519
  bool const_itm= 1;
 
3520
  THD *thd= current_thd;
3552
3521
  bool datetime_found= false;
3553
3522
  /* true <=> arguments values will be compared as DATETIMEs. */
3554
3523
  bool compare_as_datetime= false;
3555
3524
  Item *date_arg= 0;
3556
3525
  uint32_t found_types= 0;
3557
 
  uint32_t type_cnt= 0;
 
3526
  uint32_t type_cnt= 0, i;
3558
3527
  Item_result cmp_type= STRING_RESULT;
3559
3528
  left_result_type= args[0]->result_type();
3560
 
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
 
3529
  if (!(found_types= collect_cmp_types(args, arg_count)))
3561
3530
    return;
3562
 
 
 
3531
  
3563
3532
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3564
3533
  {
3565
3534
    if (!arg[0]->const_item())
3568
3537
      break;
3569
3538
    }
3570
3539
  }
3571
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3540
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
3572
3541
  {
3573
3542
    if (found_types & 1 << i)
3574
3543
    {
3579
3548
 
3580
3549
  if (type_cnt == 1)
3581
3550
  {
3582
 
    if (cmp_type == STRING_RESULT &&
 
3551
    if (cmp_type == STRING_RESULT && 
3583
3552
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3584
3553
      return;
3585
3554
    arg_types_compatible= true;
3610
3579
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3611
3580
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3612
3581
    {
3613
 
      uint32_t col, num_cols= args[0]->cols();
 
3582
      uint32_t col, cols= args[0]->cols();
3614
3583
 
3615
 
      for (col= 0; col < num_cols; col++)
 
3584
      for (col= 0; col < cols; col++)
3616
3585
      {
3617
3586
        bool skip_column= false;
3618
3587
        /*
3675
3644
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3676
3645
  {
3677
3646
    if (compare_as_datetime)
3678
 
    {
3679
3647
      array= new in_datetime(date_arg, arg_count - 1);
3680
 
    }
3681
3648
    else
3682
3649
    {
3683
3650
      /*
3684
3651
        IN must compare INT columns and constants as int values (the same
3685
3652
        way as equality does).
3686
 
        So we must check here if the column on the left and all the constant
3687
 
        values on the right can be compared as integers and adjust the
 
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 
3688
3655
        comparison type accordingly.
3689
 
      */
 
3656
      */  
3690
3657
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3658
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
3691
3659
          cmp_type != INT_RESULT)
3692
3660
      {
3693
3661
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3696
3664
          bool all_converted= true;
3697
3665
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3698
3666
          {
3699
 
            if (!convert_constant_item (&getSession(), field_item, &arg[0]))
 
3667
            if (!convert_constant_item (thd, field_item, &arg[0]))
3700
3668
              all_converted= false;
3701
3669
          }
3702
3670
          if (all_converted)
3703
3671
            cmp_type= INT_RESULT;
3704
3672
        }
3705
3673
      }
3706
 
 
3707
3674
      switch (cmp_type) {
3708
3675
      case STRING_RESULT:
3709
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
 
3676
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
3710
3677
                            cmp_collation.collation);
3711
3678
        break;
3712
 
 
3713
3679
      case INT_RESULT:
3714
3680
        array= new in_int64_t(arg_count-1);
3715
3681
        break;
3716
 
 
3717
3682
      case REAL_RESULT:
3718
3683
        array= new in_double(arg_count-1);
3719
3684
        break;
3720
 
 
3721
3685
      case ROW_RESULT:
3722
3686
        /*
3723
3687
          The row comparator was created at the beginning but only DATETIME
3726
3690
        */
3727
3691
        ((in_row*)array)->tmp.store_value(args[0]);
3728
3692
        break;
3729
 
 
3730
3693
      case DECIMAL_RESULT:
3731
3694
        array= new in_decimal(arg_count - 1);
3732
3695
        break;
 
3696
      default:
 
3697
        assert(0);
 
3698
        return;
3733
3699
      }
3734
3700
    }
3735
 
 
3736
 
    if (array && !(getSession().is_fatal_error))                // If not EOM
 
3701
    if (array && !(thd->is_fatal_error))                // If not EOM
3737
3702
    {
3738
3703
      uint32_t j=0;
3739
 
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
 
3704
      for (uint32_t i=1 ; i < arg_count ; i++)
3740
3705
      {
3741
 
        if (!args[arg_num]->null_value)                 // Skip NULL values
3742
 
        {
3743
 
          array->set(j,args[arg_num]);
3744
 
          j++;
3745
 
        }
3746
 
        else
3747
 
          have_null= 1;
 
3706
        array->set(j,args[i]);
 
3707
        if (!args[i]->null_value)                       // Skip NULL values
 
3708
          j++;
 
3709
        else
 
3710
          have_null= 1;
3748
3711
      }
3749
3712
      if ((array->used_count= j))
3750
 
        array->sort();
 
3713
        array->sort();
3751
3714
    }
3752
3715
  }
3753
3716
  else
3756
3719
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3757
3720
    else
3758
3721
    {
3759
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3722
      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
3760
3723
      {
3761
3724
        if (found_types & (1 << i) && !cmp_items[i])
3762
3725
        {
3828
3791
  for (uint32_t i= 1 ; i < arg_count ; i++)
3829
3792
  {
3830
3793
    Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3831
 
    in_item= cmp_items[(uint32_t)cmp_type];
 
3794
    in_item= cmp_items[(uint)cmp_type];
3832
3795
    assert(in_item);
3833
 
    if (!(value_added_map & (1 << (uint32_t)cmp_type)))
 
3796
    if (!(value_added_map & (1 << (uint)cmp_type)))
3834
3797
    {
3835
3798
      in_item->store_value(args[0]);
3836
3799
      if ((null_value=args[0]->null_value))
3837
3800
        return 0;
3838
3801
      have_null= 0;
3839
 
      value_added_map|= 1 << (uint32_t)cmp_type;
 
3802
      value_added_map|= 1 << (uint)cmp_type;
3840
3803
    }
3841
3804
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
3842
3805
      return (int64_t) (!negated);
3848
3811
}
3849
3812
 
3850
3813
 
3851
 
Item_cond::Item_cond(Session *session, Item_cond *item)
3852
 
  :item::function::Boolean(session, item),
 
3814
int64_t Item_func_bit_or::val_int()
 
3815
{
 
3816
  assert(fixed == 1);
 
3817
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
3818
  if (args[0]->null_value)
 
3819
  {
 
3820
    null_value=1; /* purecov: inspected */
 
3821
    return 0; /* purecov: inspected */
 
3822
  }
 
3823
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
3824
  if (args[1]->null_value)
 
3825
  {
 
3826
    null_value=1;
 
3827
    return 0;
 
3828
  }
 
3829
  null_value=0;
 
3830
  return (int64_t) (arg1 | arg2);
 
3831
}
 
3832
 
 
3833
 
 
3834
int64_t Item_func_bit_and::val_int()
 
3835
{
 
3836
  assert(fixed == 1);
 
3837
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
3838
  if (args[0]->null_value)
 
3839
  {
 
3840
    null_value=1; /* purecov: inspected */
 
3841
    return 0; /* purecov: inspected */
 
3842
  }
 
3843
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
3844
  if (args[1]->null_value)
 
3845
  {
 
3846
    null_value=1; /* purecov: inspected */
 
3847
    return 0; /* purecov: inspected */
 
3848
  }
 
3849
  null_value=0;
 
3850
  return (int64_t) (arg1 & arg2);
 
3851
}
 
3852
 
 
3853
Item_cond::Item_cond(THD *thd, Item_cond *item)
 
3854
  :Item_bool_func(thd, item),
3853
3855
   abort_on_null(item->abort_on_null),
3854
3856
   and_tables_cache(item->and_tables_cache)
3855
3857
{
3859
3861
}
3860
3862
 
3861
3863
 
3862
 
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
 
3864
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3863
3865
{
3864
3866
  List_iterator_fast<Item> li(item->list);
3865
3867
  while (Item *it= li++)
3866
 
    list.push_back(it->copy_andor_structure(session));
 
3868
    list.push_back(it->copy_andor_structure(thd));
3867
3869
}
3868
3870
 
3869
3871
 
3870
3872
bool
3871
 
Item_cond::fix_fields(Session *session, Item **)
 
3873
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
3872
3874
{
3873
3875
  assert(fixed == 0);
3874
3876
  List_iterator<Item> li(list);
3875
3877
  Item *item;
3876
 
  void *orig_session_marker= session->session_marker;
 
3878
  void *orig_thd_marker= thd->thd_marker;
3877
3879
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3878
3880
  not_null_tables_cache= used_tables_cache= 0;
3879
 
  const_item_cache= true;
 
3881
  const_item_cache= 1;
3880
3882
 
3881
3883
  if (functype() == COND_OR_FUNC)
3882
 
    session->session_marker= 0;
 
3884
    thd->thd_marker= 0;
3883
3885
  /*
3884
3886
    and_table_cache is the value that Item_cond_or() returns for
3885
3887
    not_null_tables()
3886
3888
  */
3887
3889
  and_tables_cache= ~(table_map) 0;
3888
3890
 
3889
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
3891
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3890
3892
    return true;                                // Fatal error flag is set!
3891
3893
  /*
3892
3894
    The following optimization reduces the depth of an AND-OR tree.
3919
3921
 
3920
3922
    // item can be substituted in fix_fields
3921
3923
    if ((!item->fixed &&
3922
 
         item->fix_fields(session, li.ref())) ||
 
3924
         item->fix_fields(thd, li.ref())) ||
3923
3925
        (item= *li.ref())->check_cols(1))
3924
 
      return true;
 
3926
      return true; /* purecov: inspected */
3925
3927
    used_tables_cache|=     item->used_tables();
3926
3928
    if (item->const_item())
3927
3929
      and_tables_cache= (table_map) 0;
3931
3933
      not_null_tables_cache|= tmp_table_map;
3932
3934
      and_tables_cache&= tmp_table_map;
3933
3935
      const_item_cache= false;
3934
 
    }
 
3936
    }  
3935
3937
    with_sum_func=          with_sum_func || item->with_sum_func;
3936
3938
    with_subselect|=        item->with_subselect;
3937
3939
    if (item->maybe_null)
3938
3940
      maybe_null=1;
3939
3941
  }
3940
 
  session->lex->current_select->cond_count+= list.elements;
3941
 
  session->session_marker= orig_session_marker;
 
3942
  thd->lex->current_select->cond_count+= list.elements;
 
3943
  thd->thd_marker= orig_thd_marker;
3942
3944
  fix_length_and_dec();
3943
3945
  fixed= 1;
3944
3946
  return false;
3945
3947
}
3946
3948
 
3947
3949
 
3948
 
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
 
3950
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
3949
3951
{
3950
3952
  List_iterator<Item> li(list);
3951
3953
  Item *item;
3952
3954
 
3953
3955
  used_tables_cache=0;
3954
 
  const_item_cache= true;
 
3956
  const_item_cache=1;
3955
3957
 
3956
3958
  and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
3957
3959
  not_null_tables_cache= 0;
3972
3974
      not_null_tables_cache|= tmp_table_map;
3973
3975
      and_tables_cache&= tmp_table_map;
3974
3976
      const_item_cache= false;
3975
 
    }
 
3977
    }  
3976
3978
  }
3977
3979
}
3978
3980
 
3990
3992
 
3991
3993
/**
3992
3994
  Transform an Item_cond object with a transformer callback function.
3993
 
 
 
3995
  
3994
3996
    The function recursively applies the transform method to each
3995
3997
     member item of the condition list.
3996
3998
    If the call of the method for a member item returns a new item
3997
3999
    the old item is substituted for a new one.
3998
4000
    After this the transformer is applied to the root node
3999
 
    of the Item_cond object.
4000
 
 
 
4001
    of the Item_cond object. 
 
4002
     
4001
4003
  @param transformer   the transformer callback function to be applied to
4002
4004
                       the nodes of the tree of the object
4003
4005
  @param arg           parameter to be passed to the transformer
4004
4006
 
4005
4007
  @return
4006
 
    Item returned as the result of transformation of the root node
 
4008
    Item returned as the result of transformation of the root node 
4007
4009
*/
4008
4010
 
4009
4011
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4017
4019
      return 0;
4018
4020
 
4019
4021
    /*
4020
 
      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
4021
4023
      really transformed, i.e. when a new item has been created.
4022
4024
      Otherwise we'll be allocating a lot of unnecessary memory for
4023
4025
      change records at each execution.
4024
4026
    */
4025
4027
    if (new_item != item)
4026
 
      getSession().change_item_tree(li.ref(), new_item);
 
4028
      current_thd->change_item_tree(li.ref(), new_item);
4027
4029
  }
4028
4030
  return Item_func::transform(transformer, arg);
4029
4031
}
4032
4034
/**
4033
4035
  Compile Item_cond object with a processor and a transformer
4034
4036
  callback functions.
4035
 
 
 
4037
  
4036
4038
    First the function applies the analyzer to the root node of
4037
4039
    the Item_func object. Then if the analyzer succeeeds (returns true)
4038
4040
    the function recursively applies the compile method to member
4040
4042
    If the call of the method for a member item returns a new item
4041
4043
    the old item is substituted for a new one.
4042
4044
    After this the transformer is applied to the root node
4043
 
    of the Item_cond object.
4044
 
 
 
4045
    of the Item_cond object. 
 
4046
     
4045
4047
  @param analyzer      the analyzer callback function to be applied to the
4046
4048
                       nodes of the tree of the object
4047
4049
  @param[in,out] arg_p parameter to be passed to the analyzer
4050
4052
  @param arg_t         parameter to be passed to the transformer
4051
4053
 
4052
4054
  @return
4053
 
    Item returned as the result of transformation of the root node
 
4055
    Item returned as the result of transformation of the root node 
4054
4056
*/
4055
4057
 
4056
4058
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4058
4060
{
4059
4061
  if (!(this->*analyzer)(arg_p))
4060
4062
    return 0;
4061
 
 
 
4063
  
4062
4064
  List_iterator<Item> li(list);
4063
4065
  Item *item;
4064
4066
  while ((item= li++))
4065
4067
  {
4066
 
    /*
 
4068
    /* 
4067
4069
      The same parameter value of arg_p must be passed
4068
4070
      to analyze any argument of the condition formula.
4069
 
    */
 
4071
    */   
4070
4072
    unsigned char *arg_v= *arg_p;
4071
4073
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4072
4074
    if (new_item && new_item != item)
4081
4083
  List_iterator<Item> li(list);
4082
4084
  Item *item;
4083
4085
 
4084
 
  switch (order) {
4085
 
  case (T_PREFIX):
 
4086
  switch(order) {
 
4087
  case(PREFIX):
4086
4088
    (*traverser)(this, arg);
4087
4089
    while ((item= li++))
4088
4090
    {
4090
4092
    }
4091
4093
    (*traverser)(NULL, arg);
4092
4094
    break;
4093
 
  case (T_POSTFIX):
 
4095
  case(POSTFIX):
4094
4096
    while ((item= li++))
4095
4097
    {
4096
4098
      item->traverse_cond(traverser, arg, order);
4107
4109
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4108
4110
  sql_select.cc)
4109
4111
 
4110
 
  @param session                        Thread handler
 
4112
  @param thd                    Thread handler
4111
4113
  @param ref_pointer_array      Pointer to array of reference fields
4112
4114
  @param fields         All fields in select
4113
4115
 
4116
4118
    that have or refer (HAVING) to a SUM expression.
4117
4119
*/
4118
4120
 
4119
 
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,
4120
4122
                               List<Item> &fields)
4121
4123
{
4122
4124
  List_iterator<Item> li(list);
4123
4125
  Item *item;
4124
4126
  while ((item= li++))
4125
 
    item->split_sum_func(session, ref_pointer_array,
4126
 
                         fields, li.ref(), true);
 
4127
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
4127
4128
}
4128
4129
 
4129
4130
 
4140
4141
  Item *item;
4141
4142
 
4142
4143
  used_tables_cache=0;
4143
 
  const_item_cache= true;
 
4144
  const_item_cache=1;
4144
4145
  while ((item=li++))
4145
4146
  {
4146
4147
    item->update_used_tables();
4168
4169
}
4169
4170
 
4170
4171
 
4171
 
void Item_cond::neg_arguments(Session *session)
 
4172
void Item_cond::neg_arguments(THD *thd)
4172
4173
{
4173
4174
  List_iterator<Item> li(list);
4174
4175
  Item *item;
4175
4176
  while ((item= li++))          /* Apply not transformation to the arguments */
4176
4177
  {
4177
 
    Item *new_item= item->neg_transformer(session);
 
4178
    Item *new_item= item->neg_transformer(thd);
4178
4179
    if (!new_item)
4179
4180
    {
4180
4181
      if (!(new_item= new Item_func_not(item)))
4369
4370
  if (canDoTurboBM)
4370
4371
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4371
4372
  return my_wildcmp(cmp.cmp_collation.collation,
4372
 
                    res->ptr(),res->ptr()+res->length(),
 
4373
                    res->ptr(),res->ptr()+res->length(),
4373
4374
                    res2->ptr(),res2->ptr()+res2->length(),
4374
 
                    make_escape_code(cmp.cmp_collation.collation, escape),
4375
 
                    internal::wild_one,internal::wild_many) ? 0 : 1;
 
4375
                    escape,wild_one,wild_many) ? 0 : 1;
4376
4376
}
4377
4377
 
4378
4378
 
4389
4389
    if (!res2)
4390
4390
      return OPTIMIZE_NONE;
4391
4391
 
4392
 
    if (*res2->ptr() != internal::wild_many)
 
4392
    if (*res2->ptr() != wild_many)
4393
4393
    {
4394
 
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != internal::wild_one)
 
4394
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
4395
4395
        return OPTIMIZE_OP;
4396
4396
    }
4397
4397
  }
4399
4399
}
4400
4400
 
4401
4401
 
4402
 
bool Item_func_like::fix_fields(Session *session, Item **ref)
 
4402
bool Item_func_like::fix_fields(THD *thd, Item **ref)
4403
4403
{
4404
4404
  assert(fixed == 0);
4405
 
  if (Item_bool_func2::fix_fields(session, ref) ||
4406
 
      escape_item->fix_fields(session, &escape_item))
 
4405
  if (Item_bool_func2::fix_fields(thd, ref) ||
 
4406
      escape_item->fix_fields(thd, &escape_item))
4407
4407
    return true;
4408
4408
 
4409
4409
  if (!escape_item->const_during_execution())
4411
4411
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4412
4412
    return true;
4413
4413
  }
4414
 
 
 
4414
  
4415
4415
  if (escape_item->const_item())
4416
4416
  {
4417
 
    
4418
4417
    /* If we are on execution stage */
4419
4418
    String *escape_str= escape_item->val_str(&tmp_value1);
4420
4419
    if (escape_str)
4421
4420
    {
4422
 
      escape= (char *)memory::sql_alloc(escape_str->length());
4423
 
      strcpy(escape, escape_str->ptr()); 
 
4421
      if (escape_used_in_parsing && escape_str->numchars() > 1)
 
4422
      {
 
4423
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
 
4424
        return true;
 
4425
      }
 
4426
 
 
4427
      if (use_mb(cmp.cmp_collation.collation))
 
4428
      {
 
4429
        const CHARSET_INFO * const cs= escape_str->charset();
 
4430
        my_wc_t wc;
 
4431
        int rc= cs->cset->mb_wc(cs, &wc,
 
4432
                                (const unsigned char*) escape_str->ptr(),
 
4433
                                (const unsigned char*) escape_str->ptr() +
 
4434
                                               escape_str->length());
 
4435
        escape= (int) (rc > 0 ? wc : '\\');
 
4436
      }
 
4437
      else
 
4438
      {
 
4439
        /*
 
4440
          In the case of 8bit character set, we pass native
 
4441
          code instead of Unicode code as "escape" argument.
 
4442
          Convert to "cs" if charset of escape differs.
 
4443
        */
 
4444
        const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4445
        uint32_t unused;
 
4446
        if (escape_str->needs_conversion(escape_str->length(),
 
4447
                                         escape_str->charset(), cs, &unused))
 
4448
        {
 
4449
          char ch;
 
4450
          uint32_t errors;
 
4451
          uint32_t cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
 
4452
                                          escape_str->length(),
 
4453
                                          escape_str->charset(), &errors);
 
4454
          escape= cnvlen ? ch : '\\';
 
4455
        }
 
4456
        else
 
4457
          escape= *(escape_str->ptr());
 
4458
      }
4424
4459
    }
4425
4460
    else
4426
 
    {
4427
 
      escape= (char *)memory::sql_alloc(1);
4428
 
      strcpy(escape, "\\");
4429
 
    } 
4430
 
   
 
4461
      escape= '\\';
 
4462
 
4431
4463
    /*
4432
4464
      We could also do boyer-more for non-const items, but as we would have to
4433
4465
      recompute the tables for each row it's not worth it.
4434
4466
    */
4435
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
 
4467
    if (args[1]->const_item() && !use_strnxfrm(collation.collation)) 
4436
4468
    {
4437
4469
      String* res2 = args[1]->val_str(&tmp_value2);
4438
4470
      if (!res2)
4439
4471
        return false;                           // Null argument
4440
 
 
 
4472
      
4441
4473
      const size_t len   = res2->length();
4442
4474
      const char*  first = res2->ptr();
4443
4475
      const char*  last  = first + len - 1;
4445
4477
        len must be > 2 ('%pattern%')
4446
4478
        heuristic: only do TurboBM for pattern_len > 2
4447
4479
      */
4448
 
 
 
4480
      
4449
4481
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4450
 
          *first == internal::wild_many &&
4451
 
          *last  == internal::wild_many)
 
4482
          *first == wild_many &&
 
4483
          *last  == wild_many)
4452
4484
      {
4453
4485
        const char* tmp = first + 1;
4454
 
        for (; *tmp != internal::wild_many && *tmp != internal::wild_one; tmp++)
4455
 
        {
4456
 
          if (escape == tmp)
4457
 
            break;
4458
 
        }
4459
 
  
 
4486
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
4460
4487
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
4461
4488
      }
4462
4489
      if (canDoTurboBM)
4463
4490
      {
4464
4491
        pattern     = first + 1;
4465
4492
        pattern_len = (int) len - 2;
4466
 
        int *suff = (int*) session->getMemRoot()->allocate((int) (sizeof(int)*
4467
 
                                                                  ((pattern_len + 1)*2+
4468
 
                                                                   alphabet_size)));
 
4493
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
 
4494
                                      ((pattern_len + 1)*2+
 
4495
                                      alphabet_size)));
4469
4496
        bmGs      = suff + pattern_len + 1;
4470
4497
        bmBc      = bmGs + pattern_len + 1;
4471
4498
        turboBM_compute_good_suffix_shifts(suff);
4482
4509
  Item_bool_func2::cleanup();
4483
4510
}
4484
4511
 
4485
 
static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
4486
 
{
4487
4512
#ifdef LIKE_CMP_TOUPPER
4488
 
  return cs->toupper(a);
 
4513
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
4489
4514
#else
4490
 
  return cs->sort_order[a];
 
4515
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
4491
4516
#endif
4492
 
}
 
4517
 
4493
4518
 
4494
4519
/**
4495
4520
  Precomputation dependent only on pattern_len.
4507
4532
 
4508
4533
  if (!cs->sort_order)
4509
4534
  {
4510
 
    for (int i = pattern_len - 2; i >= 0; i--)
 
4535
    int i;
 
4536
    for (i = pattern_len - 2; i >= 0; i--)
4511
4537
    {
4512
4538
      int tmp = *(splm1 + i - f);
4513
4539
      if (g < i && tmp < i - g)
4514
 
        suff[i] = tmp;
 
4540
        suff[i] = tmp;
4515
4541
      else
4516
4542
      {
4517
 
        if (i < g)
4518
 
          g = i;
4519
 
        f = i;
4520
 
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4521
 
          g--;
4522
 
        suff[i] = f - g;
 
4543
        if (i < g)
 
4544
          g = i; // g = cmin(i, g)
 
4545
        f = i;
 
4546
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
 
4547
          g--;
 
4548
        suff[i] = f - g;
4523
4549
      }
4524
4550
    }
4525
4551
  }
4526
4552
  else
4527
4553
  {
4528
 
    for (int i = pattern_len - 2; 0 <= i; --i)
 
4554
    int i;
 
4555
    for (i = pattern_len - 2; 0 <= i; --i)
4529
4556
    {
4530
4557
      int tmp = *(splm1 + i - f);
4531
4558
      if (g < i && tmp < i - g)
4532
 
        suff[i] = tmp;
 
4559
        suff[i] = tmp;
4533
4560
      else
4534
4561
      {
4535
 
        if (i < g)
4536
 
          g = i;
4537
 
        f = i;
4538
 
        while (g >= 0 &&
4539
 
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4540
 
          g--;
4541
 
        suff[i] = f - g;
 
4562
        if (i < g)
 
4563
          g = i; // g = cmin(i, g)
 
4564
        f = i;
 
4565
        while (g >= 0 &&
 
4566
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
 
4567
          g--;
 
4568
        suff[i] = f - g;
4542
4569
      }
4543
4570
    }
4544
4571
  }
4607
4634
  if (!cs->sort_order)
4608
4635
  {
4609
4636
    for (j = 0; j < plm1; j++)
4610
 
      bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
 
4637
      bmBc[(uint) (unsigned char) pattern[j]] = plm1 - j;
4611
4638
  }
4612
4639
  else
4613
4640
  {
4614
4641
    for (j = 0; j < plm1; j++)
4615
 
      bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
 
4642
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
4616
4643
  }
4617
4644
}
4618
4645
 
4653
4680
 
4654
4681
      register const int v = plm1 - i;
4655
4682
      turboShift = u - v;
4656
 
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
 
4683
      bcShift    = bmBc[(uint) (unsigned char) text[i + j]] - plm1 + i;
4657
4684
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4658
4685
      shift      = (shift > bmGs[i]) ? shift : bmGs[i];
4659
4686
      if (shift == bmGs[i])
4660
4687
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4661
4688
      else
4662
4689
      {
4663
 
        if (turboShift < bcShift)
4664
 
          shift= max(shift, u + 1);
4665
 
        u = 0;
 
4690
        if (turboShift < bcShift)
 
4691
          shift = cmax(shift, u + 1);
 
4692
        u = 0;
4666
4693
      }
4667
4694
      j+= shift;
4668
4695
    }
4675
4702
      register int i = plm1;
4676
4703
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4677
4704
      {
4678
 
        i--;
4679
 
        if (i == plm1 - shift)
4680
 
          i-= u;
 
4705
        i--;
 
4706
        if (i == plm1 - shift)
 
4707
          i-= u;
4681
4708
      }
4682
 
 
4683
4709
      if (i < 0)
4684
 
        return 1;
 
4710
        return 1;
4685
4711
 
4686
 
      register const int v= plm1 - i;
4687
 
      turboShift= u - v;
4688
 
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4689
 
      shift= (turboShift > bcShift) ? turboShift : bcShift;
4690
 
      shift= max(shift, bmGs[i]);
4691
 
      
 
4712
      register const int v = plm1 - i;
 
4713
      turboShift = u - v;
 
4714
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
 
4715
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
 
4716
      shift      = cmax(shift, bmGs[i]);
4692
4717
      if (shift == bmGs[i])
4693
 
        u= (pattern_len - shift < v) ? pattern_len - shift : v;
 
4718
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4694
4719
      else
4695
4720
      {
4696
 
        if (turboShift < bcShift)
4697
 
          shift= max(shift, u + 1);
4698
 
        u = 0;
 
4721
        if (turboShift < bcShift)
 
4722
          shift = cmax(shift, u + 1);
 
4723
        u = 0;
4699
4724
      }
4700
 
 
4701
4725
      j+= shift;
4702
4726
    }
4703
4727
    return 0;
4726
4750
  assert(fixed == 1);
4727
4751
  List_iterator<Item> li(list);
4728
4752
  Item *item;
4729
 
  int result=0;
 
4753
  int result=0; 
4730
4754
  null_value=0;
4731
4755
  while ((item=li++))
4732
4756
  {
4759
4783
       IS NOT NULL(a)     -> IS NULL(a)
4760
4784
    @endverbatim
4761
4785
 
4762
 
  @param session                thread handler
 
4786
  @param thd            thread handler
4763
4787
 
4764
4788
  @return
4765
4789
    New item or
4766
4790
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4767
4791
*/
4768
4792
 
4769
 
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
 
4793
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
4770
4794
{
4771
4795
  return args[0];
4772
4796
}
4773
4797
 
4774
4798
 
4775
 
Item *Item_bool_rowready_func2::neg_transformer(Session *)
 
4799
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
4776
4800
{
4777
4801
  Item *item= negated_item();
4778
4802
  return item;
4782
4806
/**
4783
4807
  a IS NULL  ->  a IS NOT NULL.
4784
4808
*/
4785
 
Item *Item_func_isnull::neg_transformer(Session *)
 
4809
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
4786
4810
{
4787
4811
  Item *item= new Item_func_isnotnull(args[0]);
4788
4812
  return item;
4792
4816
/**
4793
4817
  a IS NOT NULL  ->  a IS NULL.
4794
4818
*/
4795
 
Item *Item_func_isnotnull::neg_transformer(Session *)
 
4819
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
4796
4820
{
4797
4821
  Item *item= new Item_func_isnull(args[0]);
4798
4822
  return item;
4799
4823
}
4800
4824
 
4801
4825
 
4802
 
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 ...)  -> */
4803
4827
                                        /* NOT a OR NOT b OR ... */
4804
4828
{
4805
 
  neg_arguments(session);
 
4829
  neg_arguments(thd);
4806
4830
  Item *item= new Item_cond_or(list);
4807
4831
  return item;
4808
4832
}
4809
4833
 
4810
4834
 
4811
 
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 ...)  -> */
4812
4836
                                        /* NOT a AND NOT b AND ... */
4813
4837
{
4814
 
  neg_arguments(session);
 
4838
  neg_arguments(thd);
4815
4839
  Item *item= new Item_cond_and(list);
4816
4840
  return item;
4817
4841
}
4818
4842
 
4819
4843
 
4820
 
Item *Item_func_nop_all::neg_transformer(Session *)
 
4844
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
4821
4845
{
4822
4846
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4823
4847
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4828
4852
  return new_item;
4829
4853
}
4830
4854
 
4831
 
Item *Item_func_not_all::neg_transformer(Session *)
 
4855
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
4832
4856
{
4833
4857
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4834
4858
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4884
4908
}
4885
4909
 
4886
4910
Item_equal::Item_equal(Item_field *f1, Item_field *f2)
4887
 
  : item::function::Boolean(), const_item(0), eval_item(0), cond_false(0)
 
4911
  : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
4888
4912
{
4889
 
  const_item_cache= false;
 
4913
  const_item_cache= 0;
4890
4914
  fields.push_back(f1);
4891
4915
  fields.push_back(f2);
4892
4916
}
4893
4917
 
4894
4918
Item_equal::Item_equal(Item *c, Item_field *f)
4895
 
  : item::function::Boolean(), eval_item(0), cond_false(0)
 
4919
  : Item_bool_func(), eval_item(0), cond_false(0)
4896
4920
{
4897
 
  const_item_cache= false;
 
4921
  const_item_cache= 0;
4898
4922
  fields.push_back(f);
4899
4923
  const_item= c;
4900
4924
}
4901
4925
 
4902
4926
 
4903
4927
Item_equal::Item_equal(Item_equal *item_equal)
4904
 
  : item::function::Boolean(), eval_item(0), cond_false(0)
 
4928
  : Item_bool_func(), eval_item(0), cond_false(0)
4905
4929
{
4906
 
  const_item_cache= false;
 
4930
  const_item_cache= 0;
4907
4931
  List_iterator_fast<Item_field> li(item_equal->fields);
4908
4932
  Item_field *item;
4909
4933
  while ((item= li++))
4927
4951
  func->set_cmp_func();
4928
4952
  func->quick_fix_field();
4929
4953
  if ((cond_false= !func->val_int()))
4930
 
    const_item_cache= true;
 
4954
    const_item_cache= 1;
4931
4955
}
4932
4956
 
4933
4957
void Item_equal::add(Item_field *f)
4951
4975
  @retval
4952
4976
    1       if nultiple equality contains a reference to field
4953
4977
  @retval
4954
 
    0       otherwise
 
4978
    0       otherwise    
4955
4979
*/
4956
4980
 
4957
4981
bool Item_equal::contains(Field *field)
4969
4993
 
4970
4994
/**
4971
4995
  Join members of another Item_equal object.
4972
 
 
 
4996
  
4973
4997
    The function actually merges two multiple equalities.
4974
4998
    After this operation the Item_equal object additionally contains
4975
4999
    the field items of another item of the type Item_equal.
4976
5000
    If the optional constant items are not equal the cond_false flag is
4977
 
    set to 1.
 
5001
    set to 1.  
4978
5002
  @param item    multiple equality whose members are to be joined
4979
5003
*/
4980
5004
 
4984
5008
  Item *c= item->const_item;
4985
5009
  if (c)
4986
5010
  {
4987
 
    /*
4988
 
      The flag cond_false will be set to 1 after this, if
4989
 
      the multiple equality already contains a constant and its
 
5011
    /* 
 
5012
      The flag cond_false will be set to 1 after this, if 
 
5013
      the multiple equality already contains a constant and its 
4990
5014
      value is  not equal to the value of c.
4991
5015
    */
4992
5016
    add(c);
4993
5017
  }
4994
5018
  cond_false|= item->cond_false;
4995
 
}
 
5019
4996
5020
 
4997
5021
 
4998
5022
/**
5068
5092
  }
5069
5093
}
5070
5094
 
5071
 
bool Item_equal::fix_fields(Session *, Item **)
 
5095
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
5072
5096
{
5073
5097
  List_iterator_fast<Item_field> li(fields);
5074
5098
  Item *item;
5075
5099
  not_null_tables_cache= used_tables_cache= 0;
5076
 
  const_item_cache= false;
 
5100
  const_item_cache= 0;
5077
5101
  while ((item= li++))
5078
5102
  {
5079
5103
    table_map tmp_table_map;
5110
5134
    return 0;
5111
5135
  List_iterator_fast<Item_field> it(fields);
5112
5136
  Item *item= const_item ? const_item : it++;
 
5137
  if ((null_value= item->null_value))
 
5138
    return 0;
5113
5139
  eval_item->store_value(item);
5114
 
  if ((null_value= item->null_value))
5115
 
    return 0;
5116
5140
  while ((item_field= it++))
5117
5141
  {
5118
5142
    /* Skip fields of non-const tables. They haven't been read yet */
5119
 
    if (item_field->field->getTable()->const_table)
 
5143
    if (item_field->field->table->const_table)
5120
5144
    {
5121
 
      if (eval_item->cmp(item_field) || (null_value= item_field->null_value))
 
5145
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5122
5146
        return 0;
5123
5147
    }
5124
5148
  }
5155
5179
      return 0;
5156
5180
 
5157
5181
    /*
5158
 
      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
5159
5183
      really transformed, i.e. when a new item has been created.
5160
5184
      Otherwise we'll be allocating a lot of unnecessary memory for
5161
5185
      change records at each execution.
5162
5186
    */
5163
5187
    if (new_item != item)
5164
 
      getSession().change_item_tree((Item **) it.ref(), new_item);
 
5188
      current_thd->change_item_tree((Item **) it.ref(), new_item);
5165
5189
  }
5166
5190
  return Item_func::transform(transformer, arg);
5167
5191
}
5188
5212
  str->append(')');
5189
5213
}
5190
5214
 
5191
 
} /* namespace drizzled */