~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_cmpfunc.cc

  • Committer: Monty Taylor
  • Date: 2008-10-08 01:10:45 UTC
  • mto: This revision was merged to the branch mainline in revision 491.
  • Revision ID: monty@inaugust.com-20081008011045-zqozbc81f8qhmxok
Get rid of pragma interface/pragma implementation.

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
 
 
26
 
#include <drizzled/cached_item.h>
27
 
#include <drizzled/check_stack_overrun.h>
28
 
#include <drizzled/current_session.h>
29
 
#include <drizzled/error.h>
30
 
#include <drizzled/internal/my_sys.h>
31
 
#include <drizzled/item/cache_int.h>
32
 
#include <drizzled/item/cmpfunc.h>
33
 
#include <drizzled/item/int_with_ref.h>
34
 
#include <drizzled/item/subselect.h>
35
 
#include <drizzled/session.h>
 
24
#include <drizzled/server_includes.h>
36
25
#include <drizzled/sql_select.h>
37
 
#include <drizzled/temporal.h>
38
 
#include <drizzled/time_functions.h>
39
 
 
40
 
#include <math.h>
41
 
#include <algorithm>
42
 
 
43
 
using namespace std;
44
 
 
45
 
namespace drizzled
46
 
{
47
 
 
48
 
extern const double log_10[309];
49
 
 
50
 
static Eq_creator eq_creator;
51
 
static Ne_creator ne_creator;
52
 
static Gt_creator gt_creator;
53
 
static Lt_creator lt_creator;
54
 
static Ge_creator ge_creator;
55
 
static Le_creator le_creator;
56
 
 
57
 
static bool convert_constant_item(Session *, Item_field *, Item **);
 
26
 
 
27
static bool convert_constant_item(THD *, Item_field *, Item **);
58
28
 
59
29
static Item_result item_store_type(Item_result a, Item *item,
60
30
                                   bool unsigned_flag)
109
79
  DESCRIPTION
110
80
    The function checks that two expressions have compatible row signatures
111
81
    i.e. that the number of columns they return are the same and that if they
112
 
    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 
113
83
    a row signature compatible with the signature of the corresponding component
114
84
    of the second expression.
115
85
 
170
140
      of the first row expression has a compatible row signature with
171
141
      the signature of the corresponding component of the second row
172
142
      expression.
173
 
    */
 
143
    */ 
174
144
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
175
145
      return 1;     // error found: invalid usage of rows
176
146
  }
214
184
    collect_cmp_types()
215
185
      items             Array of items to collect types from
216
186
      nitems            Number of items in the array
217
 
      skip_nulls        Don't collect types of NULL items if TRUE
218
187
 
219
188
  DESCRIPTION
220
189
    This function collects different result types for comparison of the first
225
194
    Bitmap of collected types - otherwise
226
195
*/
227
196
 
228
 
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)
229
198
{
230
199
  uint32_t i;
231
200
  uint32_t found_types;
234
203
  found_types= 0;
235
204
  for (i= 1; i < nitems ; i++)
236
205
  {
237
 
    if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
238
 
      continue; // Skip NULL constant items
239
 
    if ((left_result == ROW_RESULT ||
 
206
    if ((left_result == ROW_RESULT || 
240
207
         items[i]->result_type() == ROW_RESULT) &&
241
208
        cmp_row_type(items[0], items[i]))
242
209
      return 0;
243
 
    found_types|= 1<< (uint32_t)item_cmp_type(left_result,
 
210
    found_types|= 1<< (uint)item_cmp_type(left_result,
244
211
                                           items[i]->result_type());
245
212
  }
246
 
  /*
247
 
   Even if all right-hand items are NULLs and we are skipping them all, we need
248
 
   at least one type bit in the found_type bitmask.
249
 
  */
250
 
  if (skip_nulls && !found_types)
251
 
    found_types= 1 << (uint)left_result;
252
213
  return found_types;
253
214
}
254
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
 
255
225
 
256
226
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
257
227
{
259
229
}
260
230
 
261
231
 
262
 
const Eq_creator* Eq_creator::instance()
263
 
{
264
 
  return &eq_creator;
265
 
}
266
 
 
267
 
 
268
232
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
269
233
{
270
234
  return new Item_func_ne(a, b);
271
235
}
272
236
 
273
237
 
274
 
const Ne_creator* Ne_creator::instance()
275
 
{
276
 
  return &ne_creator;
277
 
}
278
 
 
279
 
 
280
238
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
281
239
{
282
240
  return new Item_func_gt(a, b);
283
241
}
284
242
 
285
243
 
286
 
const Gt_creator* Gt_creator::instance()
287
 
{
288
 
  return &gt_creator;
289
 
}
290
 
 
291
 
 
292
244
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
293
245
{
294
246
  return new Item_func_lt(a, b);
295
247
}
296
248
 
297
249
 
298
 
const Lt_creator* Lt_creator::instance()
299
 
{
300
 
  return &lt_creator;
301
 
}
302
 
 
303
 
 
304
250
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
305
251
{
306
252
  return new Item_func_ge(a, b);
307
253
}
308
254
 
309
255
 
310
 
const Ge_creator* Ge_creator::instance()
311
 
{
312
 
  return &ge_creator;
313
 
}
314
 
 
315
 
 
316
256
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
317
257
{
318
258
  return new Item_func_le(a, b);
319
259
}
320
260
 
321
 
const Le_creator* Le_creator::instance()
322
 
{
323
 
  return &le_creator;
324
 
}
325
 
 
326
 
 
327
261
/*
328
262
  Test functions
329
263
  Most of these  returns 0LL if false and 1LL if true and
427
361
    also when comparing bigint to strings (in which case strings
428
362
    are converted to bigints).
429
363
 
430
 
  @param  session             thread handle
 
364
  @param  thd             thread handle
431
365
  @param  field_item      item will be converted using the type of this field
432
366
  @param[in,out] item     reference to the item to convert
433
367
 
444
378
    1  Item was replaced with an integer version of the item
445
379
*/
446
380
 
447
 
static bool convert_constant_item(Session *session, Item_field *field_item,
 
381
static bool convert_constant_item(THD *thd, Item_field *field_item,
448
382
                                  Item **item)
449
383
{
450
384
  Field *field= field_item->field;
451
385
  int result= 0;
452
386
 
453
 
  field->setWriteSet();
454
 
 
455
387
  if (!(*item)->with_subselect && (*item)->const_item())
456
388
  {
457
 
    ulong orig_sql_mode= session->variables.sql_mode;
458
 
    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;
459
391
    uint64_t orig_field_val= 0; /* original field value if valid */
460
392
 
461
393
    /* For comparison purposes allow invalid dates like 2000-01-32 */
462
 
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
 
394
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
463
395
                             MODE_INVALID_DATES;
464
 
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
396
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
465
397
 
466
398
    /*
467
399
      Store the value of the field if it references an outer field because
468
400
      the call to save_in_field below overrides that value.
469
401
    */
470
402
    if (field_item->depended_from)
471
 
    {
472
403
      orig_field_val= field->val_int();
473
 
    }
474
 
 
475
404
    if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
476
405
    {
477
406
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
478
407
                                       test(field->flags & UNSIGNED_FLAG));
479
408
      if (tmp)
480
 
        session->change_item_tree(item, tmp);
 
409
        thd->change_item_tree(item, tmp);
481
410
      result= 1;                                        // Item was replaced
482
411
    }
483
 
 
484
412
    /* Restore the original field value. */
485
413
    if (field_item->depended_from)
486
414
    {
487
 
      result= field->store(orig_field_val, field->isUnsigned());
 
415
      result= field->store(orig_field_val, true);
488
416
      /* orig_field_val must be a valid value that can be restored back. */
489
417
      assert(!result);
490
418
    }
491
 
    session->variables.sql_mode= orig_sql_mode;
492
 
    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;
493
421
  }
494
422
  return result;
495
423
}
498
426
void Item_bool_func2::fix_length_and_dec()
499
427
{
500
428
  max_length= 1;                                     // Function returns 0 or 1
 
429
  THD *thd;
501
430
 
502
431
  /*
503
432
    As some compare functions are generated after sql_yacc,
506
435
  if (!args[0] || !args[1])
507
436
    return;
508
437
 
509
 
  /*
 
438
  /* 
510
439
    We allow to convert to Unicode character sets in some cases.
511
440
    The conditions when conversion is possible are:
512
441
    - arguments A and B have different charsets
513
442
    - A wins according to coercibility rules
514
443
    - character set of A is superset for character set of B
515
 
 
 
444
   
516
445
    If all of the above is true, then it's possible to convert
517
446
    B into the character set of A, and then compare according
518
447
    to the collation of A.
519
448
  */
520
449
 
521
 
 
 
450
  
522
451
  DTCollation coll;
523
452
  if (args[0]->result_type() == STRING_RESULT &&
524
453
      args[1]->result_type() == STRING_RESULT &&
525
454
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
526
455
    return;
527
 
 
 
456
    
528
457
  args[0]->cmp_context= args[1]->cmp_context=
529
458
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
530
459
  // Make a special case of compare with fields to get nicer DATE comparisons
535
464
    return;
536
465
  }
537
466
 
538
 
  Item_field *field_item= NULL;
 
467
  thd= current_thd;
539
468
 
540
469
  if (args[0]->real_item()->type() == FIELD_ITEM)
541
470
  {
542
 
    field_item= static_cast<Item_field*>(args[0]->real_item());
 
471
    Item_field *field_item= (Item_field*) (args[0]->real_item());
543
472
    if (field_item->field->can_be_compared_as_int64_t() &&
544
473
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
545
474
    {
546
 
      if (convert_constant_item(&getSession(), field_item, &args[1]))
 
475
      if (convert_constant_item(thd, field_item, &args[1]))
547
476
      {
548
477
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
549
478
                         INT_RESULT);           // Works for all types.
554
483
 
555
484
    if (args[1]->real_item()->type() == FIELD_ITEM)
556
485
    {
557
 
      field_item= static_cast<Item_field*>(args[1]->real_item());
 
486
      Item_field *field_item= (Item_field*) (args[1]->real_item());
558
487
      if (field_item->field->can_be_compared_as_int64_t() &&
559
488
          !(field_item->is_datetime() &&
560
489
            args[0]->result_type() == STRING_RESULT))
561
490
      {
562
 
        if (convert_constant_item(&getSession(), field_item, &args[0]))
 
491
        if (convert_constant_item(thd, field_item, &args[0]))
563
492
        {
564
493
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
565
494
                           INT_RESULT); // Works for all types.
572
501
  set_cmp_func();
573
502
}
574
503
 
575
 
Arg_comparator::Arg_comparator():
576
 
  session(current_session),
577
 
  a_cache(0),
578
 
  b_cache(0)
579
 
{}
580
 
 
581
 
Arg_comparator::Arg_comparator(Item **a1, Item **a2):
582
 
  a(a1),
583
 
  b(a2),
584
 
  session(current_session),
585
 
  a_cache(0),
586
 
  b_cache(0)
587
 
{}
588
504
 
589
505
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
590
506
{
591
507
  owner= item;
592
508
  func= comparator_matrix[type]
593
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
594
 
 
 
509
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
595
510
  switch (type) {
596
511
  case ROW_RESULT:
597
 
    {
598
 
      uint32_t n= (*a)->cols();
599
 
      if (n != (*b)->cols())
600
 
      {
601
 
        my_error(ER_OPERAND_COLUMNS, MYF(0), n);
602
 
        comparators= 0;
603
 
        return 1;
604
 
      }
605
 
      if (!(comparators= new Arg_comparator[n]))
606
 
        return 1;
607
 
      for (uint32_t i=0; i < n; i++)
608
 
      {
609
 
        if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
610
 
        {
611
 
          my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
612
 
          return 1;
613
 
        }
614
 
        comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
615
 
      }
616
 
      break;
617
 
    }
618
 
 
 
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
  }
619
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)
620
546
    {
621
547
      /*
622
 
        We must set cmp_charset here as we may be called from for an automatic
623
 
        generated item, like in natural join
 
548
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
549
        without removing end space
624
550
      */
625
 
      if (cmp_collation.set((*a)->collation, (*b)->collation) ||
626
 
          cmp_collation.derivation == DERIVATION_NONE)
627
 
      {
628
 
        my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
629
 
        return 1;
630
 
      }
631
 
      if (cmp_collation.collation == &my_charset_bin)
632
 
      {
633
 
        /*
634
 
          We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
635
 
          without removing end space
636
 
        */
637
 
        if (func == &Arg_comparator::compare_string)
638
 
          func= &Arg_comparator::compare_binary_string;
639
 
        else if (func == &Arg_comparator::compare_e_string)
640
 
          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;
641
555
 
642
 
        /*
643
 
          As this is binary compassion, mark all fields that they can't be
644
 
          transformed. Otherwise we would get into trouble with comparisons
645
 
like:
646
 
WHERE col= 'j' AND col LIKE BINARY 'j'
647
 
which would be transformed to:
648
 
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'
649
563
      */
650
 
        (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
651
 
        (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
652
 
      }
653
 
      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);
654
566
    }
 
567
    break;
 
568
  }
655
569
  case INT_RESULT:
656
 
    {
657
 
      if (func == &Arg_comparator::compare_int_signed)
658
 
      {
659
 
        if ((*a)->unsigned_flag)
660
 
          func= (((*b)->unsigned_flag)?
661
 
                 &Arg_comparator::compare_int_unsigned :
662
 
                 &Arg_comparator::compare_int_unsigned_signed);
663
 
        else if ((*b)->unsigned_flag)
664
 
          func= &Arg_comparator::compare_int_signed_unsigned;
665
 
      }
666
 
      else if (func== &Arg_comparator::compare_e_int)
667
 
      {
668
 
        if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
669
 
          func= &Arg_comparator::compare_e_int_diff_signedness;
670
 
      }
671
 
      break;
672
 
    }
 
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
  }
673
587
  case DECIMAL_RESULT:
674
588
    break;
675
589
  case REAL_RESULT:
 
590
  {
 
591
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
676
592
    {
677
 
      if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
678
 
      {
679
 
        precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
680
 
        if (func == &Arg_comparator::compare_real)
681
 
          func= &Arg_comparator::compare_real_fixed;
682
 
        else if (func == &Arg_comparator::compare_e_real)
683
 
          func= &Arg_comparator::compare_e_real_fixed;
684
 
      }
685
 
      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;
686
598
    }
687
 
  }
688
 
 
 
599
    break;
 
600
  }
 
601
  default:
 
602
    assert(0);
 
603
  }
689
604
  return 0;
690
605
}
691
606
 
693
608
/**
694
609
  @brief Convert date provided in a string to the int representation.
695
610
 
696
 
  @param[in]   session        thread handle
 
611
  @param[in]   thd        thread handle
697
612
  @param[in]   str        a string to convert
698
613
  @param[in]   warn_type  type of the timestamp for issuing the warning
699
614
  @param[in]   warn_name  field name for issuing the warning
712
627
    converted value. 0 on error and on zero-dates -- check 'failure'
713
628
*/
714
629
 
715
 
static int64_t
716
 
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,
717
632
                  char *warn_name, bool *error_arg)
718
633
{
719
 
  int64_t value= 0;
720
 
  type::cut_t error= type::VALID;
721
 
  type::Time l_time;
722
 
  type::timestamp_t ret;
723
 
 
724
 
  ret= l_time.store(str->ptr(), str->length(),
725
 
                    (TIME_FUZZY_DATE | MODE_INVALID_DATES | (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
726
 
                    error);
727
 
 
728
 
  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)
729
645
  {
730
646
    /*
731
647
      Do not return yet, we may still want to throw a "trailing garbage"
732
648
      warning.
733
649
    */
734
650
    *error_arg= false;
735
 
    l_time.convert(value);
 
651
    value= TIME_to_uint64_t_datetime(&l_time);
736
652
  }
737
653
  else
738
654
  {
739
655
    *error_arg= true;
740
 
    error= type::CUT;                                   /* force warning */
 
656
    error= 1;                                   /* force warning */
741
657
  }
742
658
 
743
 
  if (error != type::VALID)
744
 
  {
745
 
    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,
746
661
                                 str->ptr(), str->length(),
747
662
                                 warn_type, warn_name);
748
 
  }
749
663
 
750
664
  return value;
751
665
}
768
682
         int result and the other item (b or a) is an item with string result.
769
683
         If the second item is a constant one then it's checked to be
770
684
         convertible to the DATE/DATETIME type. If the constant can't be
771
 
         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.
772
687
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
773
688
      the comparison is handled by other comparators.
774
 
 
775
689
    If the datetime comparator can be used and one the operands of the
776
690
    comparison is a string constant that was successfully converted to a
777
691
    DATE/DATETIME type then the result of the conversion is returned in the
784
698
*/
785
699
 
786
700
enum Arg_comparator::enum_date_cmp_type
787
 
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
788
 
                                     int64_t *const_value)
 
701
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
789
702
{
790
703
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
791
704
  Item *str_arg= 0, *date_arg= 0;
792
705
 
793
 
  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)
794
707
    return CMP_DATE_DFLT;
795
708
 
796
 
  if (in_a->is_datetime())
 
709
  if (a->is_datetime())
797
710
  {
798
 
    if (in_b->is_datetime())
799
 
    {
 
711
    if (b->is_datetime())
800
712
      cmp_type= CMP_DATE_WITH_DATE;
801
 
    }
802
 
    else if (in_b->result_type() == STRING_RESULT)
 
713
    else if (b->result_type() == STRING_RESULT)
803
714
    {
804
715
      cmp_type= CMP_DATE_WITH_STR;
805
 
      date_arg= in_a;
806
 
      str_arg= in_b;
 
716
      date_arg= a;
 
717
      str_arg= b;
807
718
    }
808
719
  }
809
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
720
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
810
721
  {
811
722
    cmp_type= CMP_STR_WITH_DATE;
812
 
    date_arg= in_b;
813
 
    str_arg= in_a;
 
723
    date_arg= b;
 
724
    str_arg= a;
814
725
  }
815
726
 
816
727
  if (cmp_type != CMP_DATE_DFLT)
823
734
        (str_arg->type() != Item::FUNC_ITEM ||
824
735
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
825
736
    {
826
 
      /*
827
 
       * OK, we are here if we've got a date field (or something which can be 
828
 
       * compared as a date field) on one side of the equation, and a constant
829
 
       * string on the other side.  In this case, we must verify that the constant
830
 
       * string expression can indeed be evaluated as a datetime.  If it cannot, 
831
 
       * we throw an error here and stop processsing.  Bad data should ALWAYS 
832
 
       * produce an error, and no implicit conversion or truncation should take place.
833
 
       *
834
 
       * If the conversion to a DateTime temporal is successful, then we convert
835
 
       * the Temporal instance to a uint64_t for the comparison operator, which
836
 
       * compares date(times) using int64_t semantics.
837
 
       *
838
 
       * @TODO
839
 
       *
840
 
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
841
 
       * from val_int(), not uint64_t...
842
 
       */
843
 
      int64_t value;
844
 
      String *str_val;
845
 
      String tmp;
846
 
      /* DateTime used to pick up as many string conversion possibilities as possible. */
847
 
      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);
848
743
 
849
744
      str_val= str_arg->val_str(&tmp);
850
 
      if (! str_val)
851
 
      {
852
 
        /* 
853
 
         * If we are here, it is most likely due to the comparison item
854
 
         * being a NULL.  Although this is incorrect (SQL demands that the term IS NULL
855
 
         * be used, not = NULL since no item can be equal to NULL).
856
 
         *
857
 
         * So, return gracefully.
858
 
         */
859
 
        return CMP_DATE_DFLT;
860
 
      }
861
 
      if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
862
 
      {
863
 
        /* Chuck an error. Bad datetime input. */
864
 
        my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
865
 
        return CMP_DATE_DFLT; /* :( What else can I return... */
866
 
      }
867
 
 
868
 
      /* String conversion was good.  Convert to an integer for comparison purposes. */
869
 
      temporal.to_int64_t(&value);
870
 
 
 
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;
871
750
      if (const_value)
872
751
        *const_value= value;
873
752
    }
876
755
}
877
756
 
878
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
 
879
821
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
880
822
                                        Item **a1, Item **a2,
881
823
                                        Item_result type)
882
824
{
883
 
  enum_date_cmp_type cmp_type;
884
 
  int64_t const_value= -1;
 
825
  enum enum_date_cmp_type cmp_type;
 
826
  uint64_t const_value= (uint64_t)-1;
885
827
  a= a1;
886
828
  b= a2;
887
829
 
888
830
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
889
831
  {
 
832
    thd= current_thd;
890
833
    owner= owner_arg;
891
834
    a_type= (*a)->field_type();
892
835
    b_type= (*b)->field_type();
893
836
    a_cache= 0;
894
837
    b_cache= 0;
895
838
 
896
 
    if (const_value != -1)
 
839
    if (const_value != (uint64_t)-1)
897
840
    {
898
841
      Item_cache_int *cache= new Item_cache_int();
899
842
      /* Mark the cache as non-const to prevent re-caching. */
914
857
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
915
858
    func= &Arg_comparator::compare_datetime;
916
859
    get_value_func= &get_datetime_value;
917
 
 
 
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;
918
873
    return 0;
919
874
  }
920
875
 
924
879
 
925
880
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
926
881
{
 
882
  thd= current_thd;
927
883
  /* A caller will handle null values by itself. */
928
884
  owner= NULL;
929
885
  a= a1;
943
899
 
944
900
  SYNOPSIS
945
901
    get_datetime_value()
946
 
    session                 thread handle
 
902
    thd                 thread handle
947
903
    item_arg   [in/out] item to retrieve DATETIME value from
948
904
    cache_arg  [in/out] pointer to place to store the caching item to
949
905
    warn_item  [in]     item for issuing the conversion warning
967
923
    obtained value
968
924
*/
969
925
 
970
 
int64_t
971
 
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,
972
928
                   Item *warn_item, bool *is_null)
973
929
{
974
 
  int64_t value= 0;
 
930
  uint64_t value= 0;
975
931
  String buf, *str= 0;
976
932
  Item *item= **item_arg;
977
933
 
986
942
      compare it with 100000000L - any DATE value should be less than it.
987
943
      Don't shift cached DATETIME values up for the second time.
988
944
    */
989
 
    if (f_type == DRIZZLE_TYPE_DATE ||
 
945
    if (f_type == DRIZZLE_TYPE_NEWDATE ||
990
946
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
991
947
      value*= 1000000L;
992
948
  }
995
951
    str= item->val_str(&buf);
996
952
    *is_null= item->null_value;
997
953
  }
998
 
 
999
954
  if (*is_null)
1000
955
    return ~(uint64_t) 0;
1001
 
 
1002
956
  /*
1003
957
    Convert strings to the integer DATE/DATETIME representation.
1004
958
    Even if both dates provided in strings we can't compare them directly as
1009
963
  {
1010
964
    bool error;
1011
965
    enum_field_types f_type= warn_item->field_type();
1012
 
    type::timestamp_t t_type= f_type == DRIZZLE_TYPE_DATE ? type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME;
1013
 
    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);
1014
969
    /*
1015
970
      If str did not contain a valid date according to the current
1016
971
      SQL_MODE, get_date_from_str() has already thrown a warning,
1032
987
    *cache_arg= cache;
1033
988
    *item_arg= cache_arg;
1034
989
  }
1035
 
 
1036
990
  return value;
1037
991
}
1038
992
 
1063
1017
  uint64_t a_value, b_value;
1064
1018
 
1065
1019
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1066
 
  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);
1067
1021
  if (!is_nulls_eq && is_null)
1068
1022
  {
1069
1023
    if (owner)
1072
1026
  }
1073
1027
 
1074
1028
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1075
 
  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);
1076
1030
  if (is_null)
1077
1031
  {
1078
1032
    if (owner)
1086
1040
  /* Compare values. */
1087
1041
  if (is_nulls_eq)
1088
1042
    return (a_value == b_value);
1089
 
  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);
1090
1044
}
1091
1045
 
1092
1046
 
1127
1081
      owner->null_value= 0;
1128
1082
      uint32_t res1_length= res1->length();
1129
1083
      uint32_t res2_length= res2->length();
1130
 
      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));
1131
1085
      return cmp ? cmp : (int) (res1_length - res2_length);
1132
1086
    }
1133
1087
  }
1189
1143
 
1190
1144
int Arg_comparator::compare_decimal()
1191
1145
{
1192
 
  type::Decimal value1;
1193
 
  type::Decimal *val1= (*a)->val_decimal(&value1);
 
1146
  my_decimal value1;
 
1147
  my_decimal *val1= (*a)->val_decimal(&value1);
1194
1148
  if (!(*a)->null_value)
1195
1149
  {
1196
 
    type::Decimal value2;
1197
 
    type::Decimal *val2= (*b)->val_decimal(&value2);
 
1150
    my_decimal value2;
 
1151
    my_decimal *val2= (*b)->val_decimal(&value2);
1198
1152
    if (!(*b)->null_value)
1199
1153
    {
1200
1154
      owner->null_value= 0;
1201
 
      return class_decimal_cmp(val1, val2);
 
1155
      return my_decimal_cmp(val1, val2);
1202
1156
    }
1203
1157
  }
1204
1158
  owner->null_value= 1;
1216
1170
 
1217
1171
int Arg_comparator::compare_e_decimal()
1218
1172
{
1219
 
  type::Decimal value1, value2;
1220
 
  type::Decimal *val1= (*a)->val_decimal(&value1);
1221
 
  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);
1222
1176
  if ((*a)->null_value || (*b)->null_value)
1223
1177
    return test((*a)->null_value && (*b)->null_value);
1224
 
  return test(class_decimal_cmp(val1, val2) == 0);
 
1178
  return test(my_decimal_cmp(val1, val2) == 0);
1225
1179
}
1226
1180
 
1227
1181
 
1489
1443
}
1490
1444
 
1491
1445
 
1492
 
bool Item_in_optimizer::fix_left(Session *session, Item **)
 
1446
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
1493
1447
{
1494
 
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
 
1448
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
1495
1449
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1496
1450
    return 1;
1497
1451
 
1523
1477
}
1524
1478
 
1525
1479
 
1526
 
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
 
1480
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1527
1481
{
1528
1482
  assert(fixed == 0);
1529
 
  if (fix_left(session, ref))
 
1483
  if (fix_left(thd, ref))
1530
1484
    return true;
1531
1485
  if (args[0]->maybe_null)
1532
1486
    maybe_null=1;
1533
1487
 
1534
 
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
 
1488
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
1535
1489
    return true;
1536
1490
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1537
1491
  if (args[0]->cols() != sub->engine->cols())
1555
1509
  bool tmp;
1556
1510
  assert(fixed == 1);
1557
1511
  cache->store(args[0]);
1558
 
 
 
1512
  
1559
1513
  if (cache->null_value)
1560
1514
  {
1561
1515
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1583
1537
          We disable the predicates we've pushed down into subselect, run the
1584
1538
          subselect and see if it has produced any rows.
1585
1539
        */
1586
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
 
1540
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
1587
1541
        if (cache->cols() == 1)
1588
1542
        {
1589
1543
          item_subs->set_cond_guard_var(0, false);
1604
1558
            if (cache->element_index(i)->null_value)
1605
1559
              item_subs->set_cond_guard_var(i, false);
1606
1560
          }
1607
 
 
 
1561
          
1608
1562
          (void) args[1]->val_bool_result();
1609
1563
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1610
 
 
 
1564
          
1611
1565
          /* Turn all predicates back on */
1612
1566
          for (i= 0; i < ncols; i++)
1613
1567
            item_subs->set_cond_guard_var(i, true);
1631
1585
 
1632
1586
void Item_in_optimizer::cleanup()
1633
1587
{
1634
 
  item::function::Boolean::cleanup();
 
1588
  Item_bool_func::cleanup();
1635
1589
  if (!save_cache)
1636
1590
    cache= 0;
1637
1591
  return;
1678
1632
  if (!new_item)
1679
1633
    return 0;
1680
1634
  /*
1681
 
    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
1682
1636
    really transformed, i.e. when a new item has been created.
1683
1637
    Otherwise we'll be allocating a lot of unnecessary memory for
1684
1638
    change records at each execution.
1685
1639
  */
1686
1640
  if ((*args) != new_item)
1687
 
    getSession().change_item_tree(args, new_item);
 
1641
    current_thd->change_item_tree(args, new_item);
1688
1642
 
1689
1643
  /*
1690
1644
    Transform the right IN operand which should be an Item_in_subselect or a
1809
1763
void Item_func_interval::fix_length_and_dec()
1810
1764
{
1811
1765
  uint32_t rows= row->cols();
1812
 
 
 
1766
  
1813
1767
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1814
1768
                            DECIMAL_RESULT) ||
1815
1769
                           (row->element_index(0)->result_type() ==
1826
1780
 
1827
1781
    if (not_null_consts &&
1828
1782
        (intervals=
1829
 
          (interval_range*) memory::sql_alloc(sizeof(interval_range) * (rows - 1))))
 
1783
          (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
1830
1784
    {
1831
1785
      if (use_decimal_comparison)
1832
1786
      {
1839
1793
          {
1840
1794
            range->type= DECIMAL_RESULT;
1841
1795
            range->dec.init();
1842
 
            type::Decimal *dec= el->val_decimal(&range->dec);
 
1796
            my_decimal *dec= el->val_decimal(&range->dec);
1843
1797
            if (dec != &range->dec)
1844
1798
            {
1845
1799
              range->dec= *dec;
1889
1843
{
1890
1844
  assert(fixed == 1);
1891
1845
  double value;
1892
 
  type::Decimal dec_buf, *dec= NULL;
 
1846
  my_decimal dec_buf, *dec= NULL;
1893
1847
  uint32_t i;
1894
1848
 
1895
1849
  if (use_decimal_comparison)
1897
1851
    dec= row->element_index(0)->val_decimal(&dec_buf);
1898
1852
    if (row->element_index(0)->null_value)
1899
1853
      return -1;
1900
 
    class_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
 
1854
    my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
1901
1855
  }
1902
1856
  else
1903
1857
  {
1922
1876
        and we are comparing against a decimal
1923
1877
      */
1924
1878
      if (dec && range->type == DECIMAL_RESULT)
1925
 
        cmp_result= class_decimal_cmp(&range->dec, dec) <= 0;
 
1879
        cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
1926
1880
      else
1927
1881
        cmp_result= (range->dbl <= value);
1928
1882
      if (cmp_result)
1932
1886
    }
1933
1887
    interval_range *range= intervals+start;
1934
1888
    return ((dec && range->type == DECIMAL_RESULT) ?
1935
 
            class_decimal_cmp(dec, &range->dec) < 0 :
 
1889
            my_decimal_cmp(dec, &range->dec) < 0 :
1936
1890
            value < range->dbl) ? 0 : start + 1;
1937
1891
  }
1938
1892
 
1943
1897
        ((el->result_type() == DECIMAL_RESULT) ||
1944
1898
         (el->result_type() == INT_RESULT)))
1945
1899
    {
1946
 
      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);
1947
1901
      /* Skip NULL ranges. */
1948
1902
      if (el->null_value)
1949
1903
        continue;
1950
 
      if (class_decimal_cmp(e_dec, dec) > 0)
 
1904
      if (my_decimal_cmp(e_dec, dec) > 0)
1951
1905
        return i - 1;
1952
1906
    }
1953
 
    else
 
1907
    else 
1954
1908
    {
1955
1909
      double val= el->val_real();
1956
1910
      /* Skip NULL ranges. */
1972
1926
    The function saves in ref the pointer to the item or to a newly created
1973
1927
    item that is considered as a replacement for the original one.
1974
1928
 
1975
 
  @param session     reference to the global context of the query thread
 
1929
  @param thd     reference to the global context of the query thread
1976
1930
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1977
1931
                 item is to be assigned
1978
1932
 
1992
1946
    1   got error
1993
1947
*/
1994
1948
 
1995
 
bool Item_func_between::fix_fields(Session *session, Item **ref)
 
1949
bool Item_func_between::fix_fields(THD *thd, Item **ref)
1996
1950
{
1997
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
1951
  if (Item_func_opt_neg::fix_fields(thd, ref))
1998
1952
    return 1;
1999
1953
 
2000
 
  session->getLex()->current_select->between_count++;
 
1954
  thd->lex->current_select->between_count++;
2001
1955
 
2002
1956
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
2003
1957
  if (pred_level && !negated)
2017
1971
  max_length= 1;
2018
1972
  int i;
2019
1973
  bool datetime_found= false;
 
1974
  int time_items_found= 0;
2020
1975
  compare_as_dates= true;
 
1976
  THD *thd= current_thd;
2021
1977
 
2022
1978
  /*
2023
1979
    As some compare functions are generated after sql_yacc,
2045
2001
        datetime_found= true;
2046
2002
        continue;
2047
2003
      }
 
2004
      if (args[i]->field_type() == DRIZZLE_TYPE_TIME &&
 
2005
          args[i]->result_as_int64_t())
 
2006
        time_items_found++;
2048
2007
    }
2049
2008
  }
2050
2009
  if (!datetime_found)
2055
2014
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2056
2015
    le_cmp.set_datetime_cmp_func(args, args + 2);
2057
2016
  }
2058
 
  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)
2059
2024
  {
2060
2025
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2061
2026
    if (field_item->field->can_be_compared_as_int64_t())
2064
2029
        The following can't be recoded with || as convert_constant_item
2065
2030
        changes the argument
2066
2031
      */
2067
 
      if (convert_constant_item(&getSession(), field_item, &args[1]))
 
2032
      if (convert_constant_item(thd, field_item, &args[1]))
2068
2033
        cmp_type=INT_RESULT;                    // Works for all types.
2069
 
      if (convert_constant_item(&getSession(), field_item, &args[2]))
 
2034
      if (convert_constant_item(thd, field_item, &args[2]))
2070
2035
        cmp_type=INT_RESULT;                    // Works for all types.
2071
2036
    }
2072
2037
  }
2125
2090
  {
2126
2091
    int64_t value=args[0]->val_int(), a, b;
2127
2092
    if ((null_value=args[0]->null_value))
2128
 
      return 0;
 
2093
      return 0;                                 /* purecov: inspected */
2129
2094
    a=args[1]->val_int();
2130
2095
    b=args[2]->val_int();
2131
2096
    if (!args[1]->null_value && !args[2]->null_value)
2143
2108
  }
2144
2109
  else if (cmp_type == DECIMAL_RESULT)
2145
2110
  {
2146
 
    type::Decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
 
2111
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2147
2112
               a_buf, *a_dec, b_buf, *b_dec;
2148
2113
    if ((null_value=args[0]->null_value))
2149
 
      return 0;
 
2114
      return 0;                                 /* purecov: inspected */
2150
2115
    a_dec= args[1]->val_decimal(&a_buf);
2151
2116
    b_dec= args[2]->val_decimal(&b_buf);
2152
2117
    if (!args[1]->null_value && !args[2]->null_value)
2153
 
      return (int64_t) ((class_decimal_cmp(dec, a_dec) >= 0 &&
2154
 
                          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);
2155
2120
    if (args[1]->null_value && args[2]->null_value)
2156
2121
      null_value=1;
2157
2122
    else if (args[1]->null_value)
2158
 
      null_value= (class_decimal_cmp(dec, b_dec) <= 0);
 
2123
      null_value= (my_decimal_cmp(dec, b_dec) <= 0);
2159
2124
    else
2160
 
      null_value= (class_decimal_cmp(dec, a_dec) >= 0);
 
2125
      null_value= (my_decimal_cmp(dec, a_dec) >= 0);
2161
2126
  }
2162
2127
  else
2163
2128
  {
2164
2129
    double value= args[0]->val_real(),a,b;
2165
2130
    if ((null_value=args[0]->null_value))
2166
 
      return 0;
 
2131
      return 0;                                 /* purecov: inspected */
2167
2132
    a= args[1]->val_real();
2168
2133
    b= args[2]->val_real();
2169
2134
    if (!args[1]->null_value && !args[2]->null_value)
2200
2165
Item_func_ifnull::fix_length_and_dec()
2201
2166
{
2202
2167
  agg_result_type(&hybrid_type, args, 2);
2203
 
  maybe_null= args[1]->maybe_null;
2204
 
  decimals= max(args[0]->decimals, args[1]->decimals);
 
2168
  maybe_null=args[1]->maybe_null;
 
2169
  decimals= cmax(args[0]->decimals, args[1]->decimals);
2205
2170
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2206
2171
 
2207
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
 
2172
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
2208
2173
  {
2209
2174
    int len0= args[0]->max_length - args[0]->decimals
2210
2175
      - (args[0]->unsigned_flag ? 0 : 1);
2212
2177
    int len1= args[1]->max_length - args[1]->decimals
2213
2178
      - (args[1]->unsigned_flag ? 0 : 1);
2214
2179
 
2215
 
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
 
2180
    max_length= cmax(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2216
2181
  }
2217
2182
  else
2218
 
  {
2219
 
    max_length= max(args[0]->max_length, args[1]->max_length);
2220
 
  }
 
2183
    max_length= cmax(args[0]->max_length, args[1]->max_length);
2221
2184
 
2222
 
  switch (hybrid_type)
2223
 
  {
 
2185
  switch (hybrid_type) {
2224
2186
  case STRING_RESULT:
2225
2187
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2226
2188
    break;
2227
 
 
2228
2189
  case DECIMAL_RESULT:
2229
2190
  case REAL_RESULT:
2230
2191
    break;
2231
 
 
2232
2192
  case INT_RESULT:
2233
2193
    decimals= 0;
2234
2194
    break;
2235
 
 
2236
2195
  case ROW_RESULT:
 
2196
  default:
2237
2197
    assert(0);
2238
2198
  }
2239
 
 
2240
2199
  cached_field_type= agg_field_type(args, 2);
2241
2200
}
2242
2201
 
2243
2202
 
2244
2203
uint32_t Item_func_ifnull::decimal_precision() const
2245
2204
{
2246
 
  int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2247
 
  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);
2248
2207
}
2249
2208
 
2250
2209
 
2251
 
enum_field_types Item_func_ifnull::field_type() const
 
2210
enum_field_types Item_func_ifnull::field_type() const 
2252
2211
{
2253
2212
  return cached_field_type;
2254
2213
}
2291
2250
}
2292
2251
 
2293
2252
 
2294
 
type::Decimal *Item_func_ifnull::decimal_op(type::Decimal *decimal_value)
 
2253
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
2295
2254
{
2296
2255
  assert(fixed == 1);
2297
 
  type::Decimal *value= args[0]->val_decimal(decimal_value);
 
2256
  my_decimal *value= args[0]->val_decimal(decimal_value);
2298
2257
  if (!args[0]->null_value)
2299
2258
  {
2300
2259
    null_value= 0;
2334
2293
    The function saves in ref the pointer to the item or to a newly created
2335
2294
    item that is considered as a replacement for the original one.
2336
2295
 
2337
 
  @param session     reference to the global context of the query thread
 
2296
  @param thd     reference to the global context of the query thread
2338
2297
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2339
2298
                 item is to be assigned
2340
2299
 
2353
2312
*/
2354
2313
 
2355
2314
bool
2356
 
Item_func_if::fix_fields(Session *session, Item **ref)
 
2315
Item_func_if::fix_fields(THD *thd, Item **ref)
2357
2316
{
2358
2317
  assert(fixed == 0);
2359
2318
  args[0]->top_level_item();
2360
2319
 
2361
 
  if (Item_func::fix_fields(session, ref))
 
2320
  if (Item_func::fix_fields(thd, ref))
2362
2321
    return 1;
2363
2322
 
2364
2323
  not_null_tables_cache= (args[1]->not_null_tables() &
2371
2330
void
2372
2331
Item_func_if::fix_length_and_dec()
2373
2332
{
2374
 
  maybe_null= args[1]->maybe_null || args[2]->maybe_null;
2375
 
  decimals= max(args[1]->decimals, args[2]->decimals);
2376
 
  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;
2377
2336
 
2378
 
  enum Item_result arg1_type= args[1]->result_type();
2379
 
  enum Item_result arg2_type= args[2]->result_type();
2380
 
  bool null1= args[1]->const_item() && args[1]->null_value;
2381
 
  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;
2382
2341
 
2383
2342
  if (null1)
2384
2343
  {
2416
2375
    int len2= args[2]->max_length - args[2]->decimals
2417
2376
      - (args[2]->unsigned_flag ? 0 : 1);
2418
2377
 
2419
 
    max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2378
    max_length=cmax(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2420
2379
  }
2421
2380
  else
2422
 
    max_length= max(args[1]->max_length, args[2]->max_length);
 
2381
    max_length= cmax(args[1]->max_length, args[2]->max_length);
2423
2382
}
2424
2383
 
2425
2384
 
2426
2385
uint32_t Item_func_if::decimal_precision() const
2427
2386
{
2428
 
  int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2429
 
                  decimals);
2430
 
  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);
2431
2390
}
2432
2391
 
2433
2392
 
2464
2423
}
2465
2424
 
2466
2425
 
2467
 
type::Decimal *
2468
 
Item_func_if::val_decimal(type::Decimal *decimal_value)
 
2426
my_decimal *
 
2427
Item_func_if::val_decimal(my_decimal *decimal_value)
2469
2428
{
2470
2429
  assert(fixed == 1);
2471
2430
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
2472
 
  type::Decimal *value= arg->val_decimal(decimal_value);
 
2431
  my_decimal *value= arg->val_decimal(decimal_value);
2473
2432
  null_value= arg->null_value;
2474
2433
  return value;
2475
2434
}
2549
2508
}
2550
2509
 
2551
2510
 
2552
 
type::Decimal *
2553
 
Item_func_nullif::val_decimal(type::Decimal * decimal_value)
 
2511
my_decimal *
 
2512
Item_func_nullif::val_decimal(my_decimal * decimal_value)
2554
2513
{
2555
2514
  assert(fixed == 1);
2556
 
  type::Decimal *res;
 
2515
  my_decimal *res;
2557
2516
  if (!cmp.compare())
2558
2517
  {
2559
2518
    null_value=1;
2568
2527
bool
2569
2528
Item_func_nullif::is_null()
2570
2529
{
2571
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
 
2530
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
2572
2531
}
2573
2532
 
2574
2533
 
2593
2552
           failed
2594
2553
*/
2595
2554
 
2596
 
Item *Item_func_case::find_item(String *)
 
2555
Item *Item_func_case::find_item(String *str __attribute__((unused)))
2597
2556
{
2598
2557
  uint32_t value_added_map= 0;
2599
2558
 
2614
2573
    {
2615
2574
      cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2616
2575
      assert(cmp_type != ROW_RESULT);
2617
 
      assert(cmp_items[(uint32_t)cmp_type]);
2618
 
      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)))
2619
2578
      {
2620
 
        cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
 
2579
        cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2621
2580
        if ((null_value=args[first_expr_num]->null_value))
2622
2581
          return else_expr_num != -1 ? args[else_expr_num] : 0;
2623
 
        value_added_map|= 1<<(uint32_t)cmp_type;
 
2582
        value_added_map|= 1<<(uint)cmp_type;
2624
2583
      }
2625
 
      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)
2626
2585
        return args[i + 1];
2627
2586
    }
2628
2587
  }
2686
2645
}
2687
2646
 
2688
2647
 
2689
 
type::Decimal *Item_func_case::val_decimal(type::Decimal *decimal_value)
 
2648
my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
2690
2649
{
2691
2650
  assert(fixed == 1);
2692
2651
  char buff[MAX_FIELD_WIDTH];
2693
2652
  String dummy_str(buff, sizeof(buff), default_charset());
2694
2653
  Item *item= find_item(&dummy_str);
2695
 
  type::Decimal *res;
 
2654
  my_decimal *res;
2696
2655
 
2697
2656
  if (!item)
2698
2657
  {
2706
2665
}
2707
2666
 
2708
2667
 
2709
 
bool Item_func_case::fix_fields(Session *session, Item **ref)
 
2668
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2710
2669
{
2711
2670
  /*
2712
2671
    buff should match stack usage from
2713
2672
    Item_func_case::val_int() -> Item_func_case::find_item()
2714
2673
  */
2715
 
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
2716
 
                     +sizeof(double)*2+sizeof(int64_t)*2];
2717
 
  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);
2718
2676
  /*
2719
2677
    Call check_stack_overrun after fix_fields to be sure that stack variable
2720
2678
    is not optimized away
2721
2679
  */
2722
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
2680
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2723
2681
    return true;                                // Fatal error flag is set!
2724
2682
  return res;
2725
2683
}
2735
2693
 
2736
2694
void Item_func_case::agg_num_lengths(Item *arg)
2737
2695
{
2738
 
  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,
2739
2697
                                           arg->unsigned_flag) - arg->decimals;
2740
 
  set_if_bigger(max_length, len);
 
2698
  set_if_bigger(max_length, len); 
2741
2699
  set_if_bigger(decimals, arg->decimals);
2742
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
 
2700
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
2743
2701
}
2744
2702
 
2745
2703
 
2748
2706
  Item **agg;
2749
2707
  uint32_t nagg;
2750
2708
  uint32_t found_types= 0;
2751
 
  if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
 
2709
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2752
2710
    return;
2753
 
 
 
2711
  
2754
2712
  /*
2755
2713
    Aggregate all THEN and ELSE expression types
2756
2714
    and collations when string result
2757
2715
  */
2758
 
 
 
2716
  
2759
2717
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2760
2718
    agg[nagg]= args[nagg*2+1];
2761
 
 
 
2719
  
2762
2720
  if (else_expr_num != -1)
2763
2721
    agg[nagg++]= args[else_expr_num];
2764
 
 
 
2722
  
2765
2723
  agg_result_type(&cached_result_type, agg, nagg);
2766
2724
  if ((cached_result_type == STRING_RESULT) &&
2767
2725
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2768
2726
    return;
2769
 
 
 
2727
  
2770
2728
  cached_field_type= agg_field_type(agg, nagg);
2771
2729
  /*
2772
2730
    Aggregate first expression and all THEN expression types
2774
2732
  */
2775
2733
  if (first_expr_num != -1)
2776
2734
  {
 
2735
    uint32_t i;
2777
2736
    agg[0]= args[first_expr_num];
2778
2737
    left_result_type= agg[0]->result_type();
2779
2738
 
2783
2742
    if (!(found_types= collect_cmp_types(agg, nagg)))
2784
2743
      return;
2785
2744
 
2786
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2745
    for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2787
2746
    {
2788
2747
      if (found_types & (1 << i) && !cmp_items[i])
2789
2748
      {
2801
2760
 
2802
2761
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2803
2762
    maybe_null=1;
2804
 
 
 
2763
  
2805
2764
  max_length=0;
2806
2765
  decimals=0;
2807
2766
  unsigned_flag= true;
2816
2775
  {
2817
2776
    for (uint32_t i= 0; i < ncases; i+= 2)
2818
2777
      agg_num_lengths(args[i + 1]);
2819
 
    if (else_expr_num != -1)
 
2778
    if (else_expr_num != -1) 
2820
2779
      agg_num_lengths(args[else_expr_num]);
2821
 
    max_length= class_decimal_precision_to_length(max_length + decimals, decimals,
 
2780
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2822
2781
                                               unsigned_flag);
2823
2782
  }
2824
2783
}
2830
2789
  for (uint32_t i=0 ; i < ncases ; i+=2)
2831
2790
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2832
2791
 
2833
 
  if (else_expr_num != -1)
 
2792
  if (else_expr_num != -1) 
2834
2793
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2835
 
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
2794
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2836
2795
}
2837
2796
 
2838
2797
 
2869
2828
 
2870
2829
void Item_func_case::cleanup()
2871
2830
{
 
2831
  uint32_t i;
2872
2832
  Item_func::cleanup();
2873
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2833
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2874
2834
  {
2875
2835
    delete cmp_items[i];
2876
2836
    cmp_items[i]= 0;
2877
2837
  }
 
2838
  return;
2878
2839
}
2879
2840
 
2880
2841
 
2925
2886
}
2926
2887
 
2927
2888
 
2928
 
type::Decimal *Item_func_coalesce::decimal_op(type::Decimal *decimal_value)
 
2889
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
2929
2890
{
2930
2891
  assert(fixed == 1);
2931
2892
  null_value= 0;
2932
2893
  for (uint32_t i= 0; i < arg_count; i++)
2933
2894
  {
2934
 
    type::Decimal *res= args[i]->val_decimal(decimal_value);
 
2895
    my_decimal *res= args[i]->val_decimal(decimal_value);
2935
2896
    if (!args[i]->null_value)
2936
2897
      return res;
2937
2898
  }
2944
2905
{
2945
2906
  cached_field_type= agg_field_type(args, arg_count);
2946
2907
  agg_result_type(&hybrid_type, args, arg_count);
2947
 
 
2948
2908
  switch (hybrid_type) {
2949
2909
  case STRING_RESULT:
2950
2910
    count_only_length();
2951
2911
    decimals= NOT_FIXED_DEC;
2952
2912
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2953
2913
    break;
2954
 
 
2955
2914
  case DECIMAL_RESULT:
2956
2915
    count_decimal_length();
2957
2916
    break;
2958
 
 
2959
2917
  case REAL_RESULT:
2960
2918
    count_real_length();
2961
2919
    break;
2962
 
 
2963
2920
  case INT_RESULT:
2964
2921
    count_only_length();
2965
2922
    decimals= 0;
2966
2923
    break;
2967
 
 
2968
2924
  case ROW_RESULT:
 
2925
  default:
2969
2926
    assert(0);
2970
2927
  }
2971
2928
}
3023
2980
 
3024
2981
 
3025
2982
/*
3026
 
  Compare two integers in IN value list format (packed_int64_t)
 
2983
  Compare two integers in IN value list format (packed_int64_t) 
3027
2984
 
3028
2985
  SYNOPSIS
3029
2986
    cmp_int64_t()
3045
3002
    0           left argument is equal to the right argument.
3046
3003
    1           left argument is greater than the right argument.
3047
3004
*/
3048
 
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3049
 
                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)
3050
3008
{
3051
3009
  if (a->unsigned_flag != b->unsigned_flag)
3052
 
  {
3053
 
    /*
3054
 
      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 
3055
3013
      positive signed range. Report no match.
3056
 
    */
 
3014
    */  
3057
3015
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3058
3016
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3059
3017
      return a->unsigned_flag ? 1 : -1;
3060
3018
    /*
3061
 
      Although the signedness differs both args can fit into the signed
 
3019
      Although the signedness differs both args can fit into the signed 
3062
3020
      positive range. Make them signed and compare as usual.
3063
 
    */
 
3021
    */  
3064
3022
    return cmp_longs (a->val, b->val);
3065
3023
  }
3066
3024
  if (a->unsigned_flag)
3069
3027
    return cmp_longs (a->val, b->val);
3070
3028
}
3071
3029
 
3072
 
static int cmp_double(void *, double *a, double *b)
 
3030
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
3073
3031
{
3074
3032
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3075
3033
}
3076
3034
 
3077
 
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)
3078
3036
{
3079
3037
  return a->compare(b);
3080
3038
}
3081
3039
 
3082
3040
 
3083
 
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)
3084
3042
{
3085
3043
  /*
3086
3044
    We need call of fixing buffer pointer, because fast sort just copy
3088
3046
  */
3089
3047
  a->fix_buffer_pointer();
3090
3048
  b->fix_buffer_pointer();
3091
 
  return class_decimal_cmp(a, b);
3092
 
}
3093
 
 
3094
 
 
3095
 
void in_vector::sort()
3096
 
{
3097
 
  internal::my_qsort2(base,used_count,size,compare, (void *) collation);
 
3049
  return my_decimal_cmp(a, b);
3098
3050
}
3099
3051
 
3100
3052
 
3129
3081
{
3130
3082
  if (base)
3131
3083
  {
3132
 
    // base was allocated with help of memory::sql_alloc => following is OK
 
3084
    // base was allocated with help of sql_alloc => following is OK
3133
3085
    for (uint32_t i=0 ; i < count ; i++)
3134
3086
      ((String*) base)[i].free();
3135
3087
  }
3163
3115
  return (unsigned char*) item->val_str(&tmp);
3164
3116
}
3165
3117
 
3166
 
in_row::in_row(uint32_t elements, Item *)
 
3118
in_row::in_row(uint32_t elements, Item * item __attribute__((unused)))
3167
3119
{
3168
3120
  base= (char*) new cmp_item_row[count= elements];
3169
3121
  size= sizeof(cmp_item_row);
3196
3148
  return;
3197
3149
}
3198
3150
 
3199
 
in_int64_t::in_int64_t(uint32_t elements) :
3200
 
  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)
3201
3153
{}
3202
3154
 
3203
3155
void in_int64_t::set(uint32_t pos,Item *item)
3204
3156
{
3205
3157
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3206
 
 
 
3158
  
3207
3159
  buff->val= item->val_int();
3208
3160
  buff->unsigned_flag= item->unsigned_flag;
3209
3161
}
3217
3169
  return (unsigned char*) &tmp;
3218
3170
}
3219
3171
 
3220
 
in_datetime::in_datetime(Item *warn_item_arg, uint32_t elements) :
3221
 
  in_int64_t(elements),
3222
 
  session(current_session),
3223
 
  warn_item(warn_item_arg),
3224
 
  lval_cache(0)
3225
 
{}
3226
 
 
3227
 
void in_datetime::set(uint32_t pos, Item *item)
 
3172
void in_datetime::set(uint32_t pos,Item *item)
3228
3173
{
3229
3174
  Item **tmp_item= &item;
3230
3175
  bool is_null;
3231
3176
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3232
3177
 
3233
 
  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);
3234
3179
  buff->unsigned_flag= 1L;
3235
3180
}
3236
3181
 
3238
3183
{
3239
3184
  bool is_null;
3240
3185
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3241
 
  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);
3242
3187
  if (item->null_value)
3243
3188
    return 0;
3244
3189
  tmp.unsigned_flag= 1L;
3258
3203
{
3259
3204
  tmp= item->val_real();
3260
3205
  if (item->null_value)
3261
 
    return 0;
 
3206
    return 0;                                   /* purecov: inspected */
3262
3207
  return (unsigned char*) &tmp;
3263
3208
}
3264
3209
 
3265
3210
 
3266
3211
in_decimal::in_decimal(uint32_t elements)
3267
 
  :in_vector(elements, sizeof(type::Decimal),(qsort2_cmp) cmp_decimal, 0)
 
3212
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3268
3213
{}
3269
3214
 
3270
3215
 
3271
3216
void in_decimal::set(uint32_t pos, Item *item)
3272
3217
{
3273
 
  /* as far as 'item' is constant, we can store reference on type::Decimal */
3274
 
  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;
3275
3220
  dec->len= DECIMAL_BUFF_LENGTH;
3276
3221
  dec->fix_buffer_pointer();
3277
 
  type::Decimal *res= item->val_decimal(dec);
3278
 
  /* 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 */ 
3279
3224
  if (!item->null_value && res != dec)
3280
 
    class_decimal2decimal(res, dec);
 
3225
    my_decimal2decimal(res, dec);
3281
3226
}
3282
3227
 
3283
3228
 
3284
3229
unsigned char *in_decimal::get_value(Item *item)
3285
3230
{
3286
 
  type::Decimal *result= item->val_decimal(&val);
 
3231
  my_decimal *result= item->val_decimal(&val);
3287
3232
  if (item->null_value)
3288
3233
    return 0;
3289
3234
  return (unsigned char *)result;
3296
3241
  switch (type) {
3297
3242
  case STRING_RESULT:
3298
3243
    return new cmp_item_sort_string(cs);
3299
 
 
3300
3244
  case INT_RESULT:
3301
3245
    return new cmp_item_int;
3302
 
 
3303
3246
  case REAL_RESULT:
3304
3247
    return new cmp_item_real;
3305
 
 
3306
3248
  case ROW_RESULT:
3307
3249
    return new cmp_item_row;
3308
 
 
3309
3250
  case DECIMAL_RESULT:
3310
3251
    return new cmp_item_decimal;
 
3252
  default:
 
3253
    assert(0);
 
3254
    break;
3311
3255
  }
3312
 
 
3313
3256
  return 0; // to satisfy compiler :)
3314
3257
}
3315
3258
 
3352
3295
void cmp_item_row::alloc_comparators()
3353
3296
{
3354
3297
  if (!comparators)
3355
 
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
 
3298
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
3356
3299
}
3357
3300
 
3358
3301
 
3388
3331
    return;
3389
3332
  }
3390
3333
  n= tmpl->n;
3391
 
  if ((comparators= (cmp_item **) memory::sql_alloc(sizeof(cmp_item *)*n)))
 
3334
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
3392
3335
  {
3393
3336
    item->bring_value();
3394
3337
    item->null_value= 0;
3442
3385
 
3443
3386
void cmp_item_decimal::store_value(Item *item)
3444
3387
{
3445
 
  type::Decimal *val= item->val_decimal(&value);
 
3388
  my_decimal *val= item->val_decimal(&value);
3446
3389
  /* val may be zero if item is nnull */
3447
3390
  if (val && val != &value)
3448
 
    class_decimal2decimal(val, &value);
 
3391
    my_decimal2decimal(val, &value);
3449
3392
}
3450
3393
 
3451
3394
 
3452
3395
int cmp_item_decimal::cmp(Item *arg)
3453
3396
{
3454
 
  type::Decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
 
3397
  my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
3455
3398
  if (arg->null_value)
3456
3399
    return 1;
3457
 
  return class_decimal_cmp(&value, tmp);
 
3400
  return my_decimal_cmp(&value, tmp);
3458
3401
}
3459
3402
 
3460
3403
 
3461
3404
int cmp_item_decimal::compare(cmp_item *arg)
3462
3405
{
3463
3406
  cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
3464
 
  return class_decimal_cmp(&value, &l_cmp->value);
 
3407
  return my_decimal_cmp(&value, &l_cmp->value);
3465
3408
}
3466
3409
 
3467
3410
 
3475
3418
{
3476
3419
  bool is_null;
3477
3420
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3478
 
  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);
3479
3422
}
3480
3423
 
3481
3424
 
3484
3427
  bool is_null;
3485
3428
  Item **tmp_item= &arg;
3486
3429
  return value !=
3487
 
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3430
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3488
3431
}
3489
3432
 
3490
3433
 
3521
3464
    The function saves in ref the pointer to the item or to a newly created
3522
3465
    item that is considered as a replacement for the original one.
3523
3466
 
3524
 
  @param session     reference to the global context of the query thread
 
3467
  @param thd     reference to the global context of the query thread
3525
3468
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3526
3469
                 item is to be assigned
3527
3470
 
3542
3485
*/
3543
3486
 
3544
3487
bool
3545
 
Item_func_in::fix_fields(Session *session, Item **ref)
 
3488
Item_func_in::fix_fields(THD *thd, Item **ref)
3546
3489
{
3547
3490
  Item **arg, **arg_end;
3548
3491
 
3549
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
3492
  if (Item_func_opt_neg::fix_fields(thd, ref))
3550
3493
    return 1;
3551
3494
 
3552
3495
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3574
3517
{
3575
3518
  Item **arg, **arg_end;
3576
3519
  bool const_itm= 1;
 
3520
  THD *thd= current_thd;
3577
3521
  bool datetime_found= false;
3578
3522
  /* true <=> arguments values will be compared as DATETIMEs. */
3579
3523
  bool compare_as_datetime= false;
3580
3524
  Item *date_arg= 0;
3581
3525
  uint32_t found_types= 0;
3582
 
  uint32_t type_cnt= 0;
 
3526
  uint32_t type_cnt= 0, i;
3583
3527
  Item_result cmp_type= STRING_RESULT;
3584
3528
  left_result_type= args[0]->result_type();
3585
 
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
 
3529
  if (!(found_types= collect_cmp_types(args, arg_count)))
3586
3530
    return;
3587
 
 
 
3531
  
3588
3532
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3589
3533
  {
3590
3534
    if (!arg[0]->const_item())
3593
3537
      break;
3594
3538
    }
3595
3539
  }
3596
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3540
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
3597
3541
  {
3598
3542
    if (found_types & 1 << i)
3599
3543
    {
3604
3548
 
3605
3549
  if (type_cnt == 1)
3606
3550
  {
3607
 
    if (cmp_type == STRING_RESULT &&
 
3551
    if (cmp_type == STRING_RESULT && 
3608
3552
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3609
3553
      return;
3610
3554
    arg_types_compatible= true;
3635
3579
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3636
3580
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3637
3581
    {
3638
 
      uint32_t col, num_cols= args[0]->cols();
 
3582
      uint32_t col, cols= args[0]->cols();
3639
3583
 
3640
 
      for (col= 0; col < num_cols; col++)
 
3584
      for (col= 0; col < cols; col++)
3641
3585
      {
3642
3586
        bool skip_column= false;
3643
3587
        /*
3700
3644
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3701
3645
  {
3702
3646
    if (compare_as_datetime)
3703
 
    {
3704
3647
      array= new in_datetime(date_arg, arg_count - 1);
3705
 
    }
3706
3648
    else
3707
3649
    {
3708
3650
      /*
3709
3651
        IN must compare INT columns and constants as int values (the same
3710
3652
        way as equality does).
3711
 
        So we must check here if the column on the left and all the constant
3712
 
        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 
3713
3655
        comparison type accordingly.
3714
 
      */
 
3656
      */  
3715
3657
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3658
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
3716
3659
          cmp_type != INT_RESULT)
3717
3660
      {
3718
3661
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3721
3664
          bool all_converted= true;
3722
3665
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3723
3666
          {
3724
 
            if (!convert_constant_item (&getSession(), field_item, &arg[0]))
 
3667
            if (!convert_constant_item (thd, field_item, &arg[0]))
3725
3668
              all_converted= false;
3726
3669
          }
3727
3670
          if (all_converted)
3728
3671
            cmp_type= INT_RESULT;
3729
3672
        }
3730
3673
      }
3731
 
 
3732
3674
      switch (cmp_type) {
3733
3675
      case STRING_RESULT:
3734
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
 
3676
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
3735
3677
                            cmp_collation.collation);
3736
3678
        break;
3737
 
 
3738
3679
      case INT_RESULT:
3739
3680
        array= new in_int64_t(arg_count-1);
3740
3681
        break;
3741
 
 
3742
3682
      case REAL_RESULT:
3743
3683
        array= new in_double(arg_count-1);
3744
3684
        break;
3745
 
 
3746
3685
      case ROW_RESULT:
3747
3686
        /*
3748
3687
          The row comparator was created at the beginning but only DATETIME
3751
3690
        */
3752
3691
        ((in_row*)array)->tmp.store_value(args[0]);
3753
3692
        break;
3754
 
 
3755
3693
      case DECIMAL_RESULT:
3756
3694
        array= new in_decimal(arg_count - 1);
3757
3695
        break;
 
3696
      default:
 
3697
        assert(0);
 
3698
        return;
3758
3699
      }
3759
3700
    }
3760
 
 
3761
 
    if (array && !(getSession().is_fatal_error))                // If not EOM
 
3701
    if (array && !(thd->is_fatal_error))                // If not EOM
3762
3702
    {
3763
3703
      uint32_t j=0;
3764
 
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
 
3704
      for (uint32_t i=1 ; i < arg_count ; i++)
3765
3705
      {
3766
 
        if (!args[arg_num]->null_value)                 // Skip NULL values
3767
 
        {
3768
 
          array->set(j,args[arg_num]);
3769
 
          j++;
3770
 
        }
3771
 
        else
3772
 
          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;
3773
3711
      }
3774
3712
      if ((array->used_count= j))
3775
 
        array->sort();
 
3713
        array->sort();
3776
3714
    }
3777
3715
  }
3778
3716
  else
3781
3719
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3782
3720
    else
3783
3721
    {
3784
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3722
      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
3785
3723
      {
3786
3724
        if (found_types & (1 << i) && !cmp_items[i])
3787
3725
        {
3853
3791
  for (uint32_t i= 1 ; i < arg_count ; i++)
3854
3792
  {
3855
3793
    Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3856
 
    in_item= cmp_items[(uint32_t)cmp_type];
 
3794
    in_item= cmp_items[(uint)cmp_type];
3857
3795
    assert(in_item);
3858
 
    if (!(value_added_map & (1 << (uint32_t)cmp_type)))
 
3796
    if (!(value_added_map & (1 << (uint)cmp_type)))
3859
3797
    {
3860
3798
      in_item->store_value(args[0]);
3861
3799
      if ((null_value=args[0]->null_value))
3862
3800
        return 0;
3863
3801
      have_null= 0;
3864
 
      value_added_map|= 1 << (uint32_t)cmp_type;
 
3802
      value_added_map|= 1 << (uint)cmp_type;
3865
3803
    }
3866
3804
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
3867
3805
      return (int64_t) (!negated);
3873
3811
}
3874
3812
 
3875
3813
 
3876
 
Item_cond::Item_cond(Session *session, Item_cond *item)
3877
 
  :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),
3878
3855
   abort_on_null(item->abort_on_null),
3879
3856
   and_tables_cache(item->and_tables_cache)
3880
3857
{
3884
3861
}
3885
3862
 
3886
3863
 
3887
 
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
 
3864
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3888
3865
{
3889
 
  List<Item>::iterator li(item->list.begin());
 
3866
  List_iterator_fast<Item> li(item->list);
3890
3867
  while (Item *it= li++)
3891
 
    list.push_back(it->copy_andor_structure(session));
 
3868
    list.push_back(it->copy_andor_structure(thd));
3892
3869
}
3893
3870
 
3894
3871
 
3895
3872
bool
3896
 
Item_cond::fix_fields(Session *session, Item **)
 
3873
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
3897
3874
{
3898
3875
  assert(fixed == 0);
3899
 
  List<Item>::iterator li(list.begin());
 
3876
  List_iterator<Item> li(list);
3900
3877
  Item *item;
3901
 
  void *orig_session_marker= session->session_marker;
 
3878
  void *orig_thd_marker= thd->thd_marker;
3902
3879
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3903
3880
  not_null_tables_cache= used_tables_cache= 0;
3904
 
  const_item_cache= true;
 
3881
  const_item_cache= 1;
3905
3882
 
3906
3883
  if (functype() == COND_OR_FUNC)
3907
 
    session->session_marker= 0;
 
3884
    thd->thd_marker= 0;
3908
3885
  /*
3909
3886
    and_table_cache is the value that Item_cond_or() returns for
3910
3887
    not_null_tables()
3911
3888
  */
3912
3889
  and_tables_cache= ~(table_map) 0;
3913
3890
 
3914
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
3891
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3915
3892
    return true;                                // Fatal error flag is set!
3916
3893
  /*
3917
3894
    The following optimization reduces the depth of an AND-OR tree.
3936
3913
           !((Item_cond*) item)->list.is_empty())
3937
3914
    {                                           // Identical function
3938
3915
      li.replace(((Item_cond*) item)->list);
3939
 
      ((Item_cond*) item)->list.clear();
 
3916
      ((Item_cond*) item)->list.empty();
3940
3917
      item= *li.ref();                          // new current item
3941
3918
    }
3942
3919
    if (abort_on_null)
3944
3921
 
3945
3922
    // item can be substituted in fix_fields
3946
3923
    if ((!item->fixed &&
3947
 
         item->fix_fields(session, li.ref())) ||
 
3924
         item->fix_fields(thd, li.ref())) ||
3948
3925
        (item= *li.ref())->check_cols(1))
3949
 
      return true;
 
3926
      return true; /* purecov: inspected */
3950
3927
    used_tables_cache|=     item->used_tables();
3951
3928
    if (item->const_item())
3952
3929
      and_tables_cache= (table_map) 0;
3956
3933
      not_null_tables_cache|= tmp_table_map;
3957
3934
      and_tables_cache&= tmp_table_map;
3958
3935
      const_item_cache= false;
3959
 
    }
 
3936
    }  
3960
3937
    with_sum_func=          with_sum_func || item->with_sum_func;
3961
3938
    with_subselect|=        item->with_subselect;
3962
3939
    if (item->maybe_null)
3963
3940
      maybe_null=1;
3964
3941
  }
3965
 
  session->getLex()->current_select->cond_count+= list.elements;
3966
 
  session->session_marker= orig_session_marker;
 
3942
  thd->lex->current_select->cond_count+= list.elements;
 
3943
  thd->thd_marker= orig_thd_marker;
3967
3944
  fix_length_and_dec();
3968
3945
  fixed= 1;
3969
3946
  return false;
3970
3947
}
3971
3948
 
3972
3949
 
3973
 
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)))
3974
3951
{
3975
 
  List<Item>::iterator li(list.begin());
 
3952
  List_iterator<Item> li(list);
3976
3953
  Item *item;
3977
3954
 
3978
3955
  used_tables_cache=0;
3979
 
  const_item_cache= true;
 
3956
  const_item_cache=1;
3980
3957
 
3981
3958
  and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
3982
3959
  not_null_tables_cache= 0;
3997
3974
      not_null_tables_cache|= tmp_table_map;
3998
3975
      and_tables_cache&= tmp_table_map;
3999
3976
      const_item_cache= false;
4000
 
    }
 
3977
    }  
4001
3978
  }
4002
3979
}
4003
3980
 
4004
3981
 
4005
3982
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
4006
3983
{
4007
 
  List<Item>::iterator li(list.begin());
 
3984
  List_iterator_fast<Item> li(list);
4008
3985
  Item *item;
4009
3986
  while ((item= li++))
4010
3987
    if (item->walk(processor, walk_subquery, arg))
4015
3992
 
4016
3993
/**
4017
3994
  Transform an Item_cond object with a transformer callback function.
4018
 
 
 
3995
  
4019
3996
    The function recursively applies the transform method to each
4020
3997
     member item of the condition list.
4021
3998
    If the call of the method for a member item returns a new item
4022
3999
    the old item is substituted for a new one.
4023
4000
    After this the transformer is applied to the root node
4024
 
    of the Item_cond object.
4025
 
 
 
4001
    of the Item_cond object. 
 
4002
     
4026
4003
  @param transformer   the transformer callback function to be applied to
4027
4004
                       the nodes of the tree of the object
4028
4005
  @param arg           parameter to be passed to the transformer
4029
4006
 
4030
4007
  @return
4031
 
    Item returned as the result of transformation of the root node
 
4008
    Item returned as the result of transformation of the root node 
4032
4009
*/
4033
4010
 
4034
4011
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4035
4012
{
4036
 
  List<Item>::iterator li(list.begin());
 
4013
  List_iterator<Item> li(list);
4037
4014
  Item *item;
4038
4015
  while ((item= li++))
4039
4016
  {
4042
4019
      return 0;
4043
4020
 
4044
4021
    /*
4045
 
      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
4046
4023
      really transformed, i.e. when a new item has been created.
4047
4024
      Otherwise we'll be allocating a lot of unnecessary memory for
4048
4025
      change records at each execution.
4049
4026
    */
4050
4027
    if (new_item != item)
4051
 
      getSession().change_item_tree(li.ref(), new_item);
 
4028
      current_thd->change_item_tree(li.ref(), new_item);
4052
4029
  }
4053
4030
  return Item_func::transform(transformer, arg);
4054
4031
}
4057
4034
/**
4058
4035
  Compile Item_cond object with a processor and a transformer
4059
4036
  callback functions.
4060
 
 
 
4037
  
4061
4038
    First the function applies the analyzer to the root node of
4062
4039
    the Item_func object. Then if the analyzer succeeeds (returns true)
4063
4040
    the function recursively applies the compile method to member
4065
4042
    If the call of the method for a member item returns a new item
4066
4043
    the old item is substituted for a new one.
4067
4044
    After this the transformer is applied to the root node
4068
 
    of the Item_cond object.
4069
 
 
 
4045
    of the Item_cond object. 
 
4046
     
4070
4047
  @param analyzer      the analyzer callback function to be applied to the
4071
4048
                       nodes of the tree of the object
4072
4049
  @param[in,out] arg_p parameter to be passed to the analyzer
4075
4052
  @param arg_t         parameter to be passed to the transformer
4076
4053
 
4077
4054
  @return
4078
 
    Item returned as the result of transformation of the root node
 
4055
    Item returned as the result of transformation of the root node 
4079
4056
*/
4080
4057
 
4081
4058
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4083
4060
{
4084
4061
  if (!(this->*analyzer)(arg_p))
4085
4062
    return 0;
4086
 
 
4087
 
  List<Item>::iterator li(list.begin());
 
4063
  
 
4064
  List_iterator<Item> li(list);
4088
4065
  Item *item;
4089
4066
  while ((item= li++))
4090
4067
  {
4091
 
    /*
 
4068
    /* 
4092
4069
      The same parameter value of arg_p must be passed
4093
4070
      to analyze any argument of the condition formula.
4094
 
    */
 
4071
    */   
4095
4072
    unsigned char *arg_v= *arg_p;
4096
4073
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4097
4074
    if (new_item && new_item != item)
4103
4080
void Item_cond::traverse_cond(Cond_traverser traverser,
4104
4081
                              void *arg, traverse_order order)
4105
4082
{
4106
 
  List<Item>::iterator li(list.begin());
 
4083
  List_iterator<Item> li(list);
4107
4084
  Item *item;
4108
4085
 
4109
 
  switch (order) {
4110
 
  case (T_PREFIX):
 
4086
  switch(order) {
 
4087
  case(PREFIX):
4111
4088
    (*traverser)(this, arg);
4112
4089
    while ((item= li++))
4113
4090
    {
4115
4092
    }
4116
4093
    (*traverser)(NULL, arg);
4117
4094
    break;
4118
 
  case (T_POSTFIX):
 
4095
  case(POSTFIX):
4119
4096
    while ((item= li++))
4120
4097
    {
4121
4098
      item->traverse_cond(traverser, arg, order);
4132
4109
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4133
4110
  sql_select.cc)
4134
4111
 
4135
 
  @param session                        Thread handler
 
4112
  @param thd                    Thread handler
4136
4113
  @param ref_pointer_array      Pointer to array of reference fields
4137
4114
  @param fields         All fields in select
4138
4115
 
4141
4118
    that have or refer (HAVING) to a SUM expression.
4142
4119
*/
4143
4120
 
4144
 
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,
4145
4122
                               List<Item> &fields)
4146
4123
{
4147
 
  List<Item>::iterator li(list.begin());
 
4124
  List_iterator<Item> li(list);
4148
4125
  Item *item;
4149
4126
  while ((item= li++))
4150
 
    item->split_sum_func(session, ref_pointer_array,
4151
 
                         fields, li.ref(), true);
 
4127
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
4152
4128
}
4153
4129
 
4154
4130
 
4161
4137
 
4162
4138
void Item_cond::update_used_tables()
4163
4139
{
4164
 
  List<Item>::iterator li(list.begin());
 
4140
  List_iterator_fast<Item> li(list);
4165
4141
  Item *item;
4166
4142
 
4167
4143
  used_tables_cache=0;
4168
 
  const_item_cache= true;
 
4144
  const_item_cache=1;
4169
4145
  while ((item=li++))
4170
4146
  {
4171
4147
    item->update_used_tables();
4178
4154
void Item_cond::print(String *str, enum_query_type query_type)
4179
4155
{
4180
4156
  str->append('(');
4181
 
  List<Item>::iterator li(list.begin());
 
4157
  List_iterator_fast<Item> li(list);
4182
4158
  Item *item;
4183
4159
  if ((item=li++))
4184
4160
    item->print(str, query_type);
4193
4169
}
4194
4170
 
4195
4171
 
4196
 
void Item_cond::neg_arguments(Session *session)
 
4172
void Item_cond::neg_arguments(THD *thd)
4197
4173
{
4198
 
  List<Item>::iterator li(list.begin());
 
4174
  List_iterator<Item> li(list);
4199
4175
  Item *item;
4200
4176
  while ((item= li++))          /* Apply not transformation to the arguments */
4201
4177
  {
4202
 
    Item *new_item= item->neg_transformer(session);
 
4178
    Item *new_item= item->neg_transformer(thd);
4203
4179
    if (!new_item)
4204
4180
    {
4205
4181
      if (!(new_item= new Item_func_not(item)))
4233
4209
int64_t Item_cond_and::val_int()
4234
4210
{
4235
4211
  assert(fixed == 1);
4236
 
  List<Item>::iterator li(list.begin());
 
4212
  List_iterator_fast<Item> li(list);
4237
4213
  Item *item;
4238
4214
  null_value= 0;
4239
4215
  while ((item=li++))
4251
4227
int64_t Item_cond_or::val_int()
4252
4228
{
4253
4229
  assert(fixed == 1);
4254
 
  List<Item>::iterator li(list.begin());
 
4230
  List_iterator_fast<Item> li(list);
4255
4231
  Item *item;
4256
4232
  null_value=0;
4257
4233
  while ((item=li++))
4394
4370
  if (canDoTurboBM)
4395
4371
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4396
4372
  return my_wildcmp(cmp.cmp_collation.collation,
4397
 
                    res->ptr(),res->ptr()+res->length(),
 
4373
                    res->ptr(),res->ptr()+res->length(),
4398
4374
                    res2->ptr(),res2->ptr()+res2->length(),
4399
 
                    make_escape_code(cmp.cmp_collation.collation, escape),
4400
 
                    internal::wild_one,internal::wild_many) ? 0 : 1;
 
4375
                    escape,wild_one,wild_many) ? 0 : 1;
4401
4376
}
4402
4377
 
4403
4378
 
4414
4389
    if (!res2)
4415
4390
      return OPTIMIZE_NONE;
4416
4391
 
4417
 
    if (*res2->ptr() != internal::wild_many)
 
4392
    if (*res2->ptr() != wild_many)
4418
4393
    {
4419
 
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != internal::wild_one)
 
4394
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
4420
4395
        return OPTIMIZE_OP;
4421
4396
    }
4422
4397
  }
4424
4399
}
4425
4400
 
4426
4401
 
4427
 
bool Item_func_like::fix_fields(Session *session, Item **ref)
 
4402
bool Item_func_like::fix_fields(THD *thd, Item **ref)
4428
4403
{
4429
4404
  assert(fixed == 0);
4430
 
  if (Item_bool_func2::fix_fields(session, ref) ||
4431
 
      escape_item->fix_fields(session, &escape_item))
 
4405
  if (Item_bool_func2::fix_fields(thd, ref) ||
 
4406
      escape_item->fix_fields(thd, &escape_item))
4432
4407
    return true;
4433
4408
 
4434
4409
  if (!escape_item->const_during_execution())
4436
4411
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4437
4412
    return true;
4438
4413
  }
4439
 
 
 
4414
  
4440
4415
  if (escape_item->const_item())
4441
4416
  {
4442
 
    
4443
4417
    /* If we are on execution stage */
4444
4418
    String *escape_str= escape_item->val_str(&tmp_value1);
4445
4419
    if (escape_str)
4446
4420
    {
4447
 
      escape= (char *)memory::sql_alloc(escape_str->length());
4448
 
      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
      }
4449
4459
    }
4450
4460
    else
4451
 
    {
4452
 
      escape= (char *)memory::sql_alloc(1);
4453
 
      strcpy(escape, "\\");
4454
 
    } 
4455
 
   
 
4461
      escape= '\\';
 
4462
 
4456
4463
    /*
4457
4464
      We could also do boyer-more for non-const items, but as we would have to
4458
4465
      recompute the tables for each row it's not worth it.
4459
4466
    */
4460
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
 
4467
    if (args[1]->const_item() && !use_strnxfrm(collation.collation)) 
4461
4468
    {
4462
4469
      String* res2 = args[1]->val_str(&tmp_value2);
4463
4470
      if (!res2)
4464
4471
        return false;                           // Null argument
4465
 
 
 
4472
      
4466
4473
      const size_t len   = res2->length();
4467
4474
      const char*  first = res2->ptr();
4468
4475
      const char*  last  = first + len - 1;
4470
4477
        len must be > 2 ('%pattern%')
4471
4478
        heuristic: only do TurboBM for pattern_len > 2
4472
4479
      */
4473
 
 
 
4480
      
4474
4481
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4475
 
          *first == internal::wild_many &&
4476
 
          *last  == internal::wild_many)
 
4482
          *first == wild_many &&
 
4483
          *last  == wild_many)
4477
4484
      {
4478
4485
        const char* tmp = first + 1;
4479
 
        for (; *tmp != internal::wild_many && *tmp != internal::wild_one; tmp++)
4480
 
        {
4481
 
          if (escape == tmp)
4482
 
            break;
4483
 
        }
4484
 
  
 
4486
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
4485
4487
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
4486
4488
      }
4487
4489
      if (canDoTurboBM)
4488
4490
      {
4489
4491
        pattern     = first + 1;
4490
4492
        pattern_len = (int) len - 2;
4491
 
        int *suff = (int*) session->getMemRoot()->allocate((int) (sizeof(int)*
4492
 
                                                                  ((pattern_len + 1)*2+
4493
 
                                                                   alphabet_size)));
 
4493
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
 
4494
                                      ((pattern_len + 1)*2+
 
4495
                                      alphabet_size)));
4494
4496
        bmGs      = suff + pattern_len + 1;
4495
4497
        bmBc      = bmGs + pattern_len + 1;
4496
4498
        turboBM_compute_good_suffix_shifts(suff);
4507
4509
  Item_bool_func2::cleanup();
4508
4510
}
4509
4511
 
4510
 
static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
4511
 
{
4512
4512
#ifdef LIKE_CMP_TOUPPER
4513
 
  return cs->toupper(a);
 
4513
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
4514
4514
#else
4515
 
  return cs->sort_order[a];
 
4515
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
4516
4516
#endif
4517
 
}
 
4517
 
4518
4518
 
4519
4519
/**
4520
4520
  Precomputation dependent only on pattern_len.
4532
4532
 
4533
4533
  if (!cs->sort_order)
4534
4534
  {
4535
 
    for (int i = pattern_len - 2; i >= 0; i--)
 
4535
    int i;
 
4536
    for (i = pattern_len - 2; i >= 0; i--)
4536
4537
    {
4537
4538
      int tmp = *(splm1 + i - f);
4538
4539
      if (g < i && tmp < i - g)
4539
 
        suff[i] = tmp;
 
4540
        suff[i] = tmp;
4540
4541
      else
4541
4542
      {
4542
 
        if (i < g)
4543
 
          g = i;
4544
 
        f = i;
4545
 
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4546
 
          g--;
4547
 
        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;
4548
4549
      }
4549
4550
    }
4550
4551
  }
4551
4552
  else
4552
4553
  {
4553
 
    for (int i = pattern_len - 2; 0 <= i; --i)
 
4554
    int i;
 
4555
    for (i = pattern_len - 2; 0 <= i; --i)
4554
4556
    {
4555
4557
      int tmp = *(splm1 + i - f);
4556
4558
      if (g < i && tmp < i - g)
4557
 
        suff[i] = tmp;
 
4559
        suff[i] = tmp;
4558
4560
      else
4559
4561
      {
4560
 
        if (i < g)
4561
 
          g = i;
4562
 
        f = i;
4563
 
        while (g >= 0 &&
4564
 
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4565
 
          g--;
4566
 
        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;
4567
4569
      }
4568
4570
    }
4569
4571
  }
4632
4634
  if (!cs->sort_order)
4633
4635
  {
4634
4636
    for (j = 0; j < plm1; j++)
4635
 
      bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
 
4637
      bmBc[(uint) (unsigned char) pattern[j]] = plm1 - j;
4636
4638
  }
4637
4639
  else
4638
4640
  {
4639
4641
    for (j = 0; j < plm1; j++)
4640
 
      bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
 
4642
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
4641
4643
  }
4642
4644
}
4643
4645
 
4651
4653
 
4652
4654
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
4653
4655
{
4654
 
  int bcShift;
4655
 
  int turboShift;
 
4656
  register int bcShift;
 
4657
  register int turboShift;
4656
4658
  int shift = pattern_len;
4657
4659
  int j     = 0;
4658
4660
  int u     = 0;
4666
4668
  {
4667
4669
    while (j <= tlmpl)
4668
4670
    {
4669
 
      int i= plm1;
 
4671
      register int i= plm1;
4670
4672
      while (i >= 0 && pattern[i] == text[i + j])
4671
4673
      {
4672
4674
        i--;
4676
4678
      if (i < 0)
4677
4679
        return 1;
4678
4680
 
4679
 
      const int v = plm1 - i;
 
4681
      register const int v = plm1 - i;
4680
4682
      turboShift = u - v;
4681
 
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
 
4683
      bcShift    = bmBc[(uint) (unsigned char) text[i + j]] - plm1 + i;
4682
4684
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4683
4685
      shift      = (shift > bmGs[i]) ? shift : bmGs[i];
4684
4686
      if (shift == bmGs[i])
4685
4687
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4686
4688
      else
4687
4689
      {
4688
 
        if (turboShift < bcShift)
4689
 
          shift= max(shift, u + 1);
4690
 
        u = 0;
 
4690
        if (turboShift < bcShift)
 
4691
          shift = cmax(shift, u + 1);
 
4692
        u = 0;
4691
4693
      }
4692
4694
      j+= shift;
4693
4695
    }
4697
4699
  {
4698
4700
    while (j <= tlmpl)
4699
4701
    {
4700
 
      int i = plm1;
 
4702
      register int i = plm1;
4701
4703
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4702
4704
      {
4703
 
        i--;
4704
 
        if (i == plm1 - shift)
4705
 
          i-= u;
 
4705
        i--;
 
4706
        if (i == plm1 - shift)
 
4707
          i-= u;
4706
4708
      }
4707
 
 
4708
4709
      if (i < 0)
4709
 
        return 1;
 
4710
        return 1;
4710
4711
 
4711
 
      const int v= plm1 - i;
4712
 
      turboShift= u - v;
4713
 
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4714
 
      shift= (turboShift > bcShift) ? turboShift : bcShift;
4715
 
      shift= max(shift, bmGs[i]);
4716
 
      
 
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]);
4717
4717
      if (shift == bmGs[i])
4718
 
        u= (pattern_len - shift < v) ? pattern_len - shift : v;
 
4718
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
4719
4719
      else
4720
4720
      {
4721
 
        if (turboShift < bcShift)
4722
 
          shift= max(shift, u + 1);
4723
 
        u = 0;
 
4721
        if (turboShift < bcShift)
 
4722
          shift = cmax(shift, u + 1);
 
4723
        u = 0;
4724
4724
      }
4725
 
 
4726
4725
      j+= shift;
4727
4726
    }
4728
4727
    return 0;
4749
4748
int64_t Item_cond_xor::val_int()
4750
4749
{
4751
4750
  assert(fixed == 1);
4752
 
  List<Item>::iterator li(list.begin());
 
4751
  List_iterator<Item> li(list);
4753
4752
  Item *item;
4754
 
  int result=0;
 
4753
  int result=0; 
4755
4754
  null_value=0;
4756
4755
  while ((item=li++))
4757
4756
  {
4784
4783
       IS NOT NULL(a)     -> IS NULL(a)
4785
4784
    @endverbatim
4786
4785
 
4787
 
  @param session                thread handler
 
4786
  @param thd            thread handler
4788
4787
 
4789
4788
  @return
4790
4789
    New item or
4791
4790
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4792
4791
*/
4793
4792
 
4794
 
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
 
4793
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
4795
4794
{
4796
4795
  return args[0];
4797
4796
}
4798
4797
 
4799
4798
 
4800
 
Item *Item_bool_rowready_func2::neg_transformer(Session *)
 
4799
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
4801
4800
{
4802
4801
  Item *item= negated_item();
4803
4802
  return item;
4807
4806
/**
4808
4807
  a IS NULL  ->  a IS NOT NULL.
4809
4808
*/
4810
 
Item *Item_func_isnull::neg_transformer(Session *)
 
4809
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
4811
4810
{
4812
4811
  Item *item= new Item_func_isnotnull(args[0]);
4813
4812
  return item;
4817
4816
/**
4818
4817
  a IS NOT NULL  ->  a IS NULL.
4819
4818
*/
4820
 
Item *Item_func_isnotnull::neg_transformer(Session *)
 
4819
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
4821
4820
{
4822
4821
  Item *item= new Item_func_isnull(args[0]);
4823
4822
  return item;
4824
4823
}
4825
4824
 
4826
4825
 
4827
 
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 ...)  -> */
4828
4827
                                        /* NOT a OR NOT b OR ... */
4829
4828
{
4830
 
  neg_arguments(session);
 
4829
  neg_arguments(thd);
4831
4830
  Item *item= new Item_cond_or(list);
4832
4831
  return item;
4833
4832
}
4834
4833
 
4835
4834
 
4836
 
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 ...)  -> */
4837
4836
                                        /* NOT a AND NOT b AND ... */
4838
4837
{
4839
 
  neg_arguments(session);
 
4838
  neg_arguments(thd);
4840
4839
  Item *item= new Item_cond_and(list);
4841
4840
  return item;
4842
4841
}
4843
4842
 
4844
4843
 
4845
 
Item *Item_func_nop_all::neg_transformer(Session *)
 
4844
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
4846
4845
{
4847
4846
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4848
4847
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4853
4852
  return new_item;
4854
4853
}
4855
4854
 
4856
 
Item *Item_func_not_all::neg_transformer(Session *)
 
4855
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
4857
4856
{
4858
4857
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4859
4858
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4909
4908
}
4910
4909
 
4911
4910
Item_equal::Item_equal(Item_field *f1, Item_field *f2)
4912
 
  : 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)
4913
4912
{
4914
 
  const_item_cache= false;
 
4913
  const_item_cache= 0;
4915
4914
  fields.push_back(f1);
4916
4915
  fields.push_back(f2);
4917
4916
}
4918
4917
 
4919
4918
Item_equal::Item_equal(Item *c, Item_field *f)
4920
 
  : item::function::Boolean(), eval_item(0), cond_false(0)
 
4919
  : Item_bool_func(), eval_item(0), cond_false(0)
4921
4920
{
4922
 
  const_item_cache= false;
 
4921
  const_item_cache= 0;
4923
4922
  fields.push_back(f);
4924
4923
  const_item= c;
4925
4924
}
4926
4925
 
4927
4926
 
4928
4927
Item_equal::Item_equal(Item_equal *item_equal)
4929
 
  : item::function::Boolean(), eval_item(0), cond_false(0)
 
4928
  : Item_bool_func(), eval_item(0), cond_false(0)
4930
4929
{
4931
 
  const_item_cache= false;
4932
 
  List<Item_field>::iterator li(item_equal->fields.begin());
 
4930
  const_item_cache= 0;
 
4931
  List_iterator_fast<Item_field> li(item_equal->fields);
4933
4932
  Item_field *item;
4934
4933
  while ((item= li++))
4935
4934
  {
4952
4951
  func->set_cmp_func();
4953
4952
  func->quick_fix_field();
4954
4953
  if ((cond_false= !func->val_int()))
4955
 
    const_item_cache= true;
 
4954
    const_item_cache= 1;
4956
4955
}
4957
4956
 
4958
4957
void Item_equal::add(Item_field *f)
4976
4975
  @retval
4977
4976
    1       if nultiple equality contains a reference to field
4978
4977
  @retval
4979
 
    0       otherwise
 
4978
    0       otherwise    
4980
4979
*/
4981
4980
 
4982
4981
bool Item_equal::contains(Field *field)
4983
4982
{
4984
 
  List<Item_field>::iterator it(fields.begin());
 
4983
  List_iterator_fast<Item_field> it(fields);
4985
4984
  Item_field *item;
4986
4985
  while ((item= it++))
4987
4986
  {
4994
4993
 
4995
4994
/**
4996
4995
  Join members of another Item_equal object.
4997
 
 
 
4996
  
4998
4997
    The function actually merges two multiple equalities.
4999
4998
    After this operation the Item_equal object additionally contains
5000
4999
    the field items of another item of the type Item_equal.
5001
5000
    If the optional constant items are not equal the cond_false flag is
5002
 
    set to 1.
 
5001
    set to 1.  
5003
5002
  @param item    multiple equality whose members are to be joined
5004
5003
*/
5005
5004
 
5009
5008
  Item *c= item->const_item;
5010
5009
  if (c)
5011
5010
  {
5012
 
    /*
5013
 
      The flag cond_false will be set to 1 after this, if
5014
 
      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 
5015
5014
      value is  not equal to the value of c.
5016
5015
    */
5017
5016
    add(c);
5018
5017
  }
5019
5018
  cond_false|= item->cond_false;
5020
 
}
 
5019
5021
5020
 
5022
5021
 
5023
5022
/**
5040
5039
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
5041
5040
{
5042
5041
  bool swap;
5043
 
  List<Item_field>::iterator it(fields.begin());
 
5042
  List_iterator<Item_field> it(fields);
5044
5043
  do
5045
5044
  {
5046
5045
    Item_field *item1= it++;
5064
5063
        ref1= ref2;
5065
5064
      }
5066
5065
    }
5067
 
    it= fields.begin();
 
5066
    it.rewind();
5068
5067
  } while (swap);
5069
5068
}
5070
5069
 
5081
5080
 
5082
5081
void Item_equal::update_const()
5083
5082
{
5084
 
  List<Item_field>::iterator it(fields.begin());
 
5083
  List_iterator<Item_field> it(fields);
5085
5084
  Item *item;
5086
5085
  while ((item= it++))
5087
5086
  {
5093
5092
  }
5094
5093
}
5095
5094
 
5096
 
bool Item_equal::fix_fields(Session *, Item **)
 
5095
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
5097
5096
{
5098
 
  List<Item_field>::iterator li(fields.begin());
 
5097
  List_iterator_fast<Item_field> li(fields);
5099
5098
  Item *item;
5100
5099
  not_null_tables_cache= used_tables_cache= 0;
5101
 
  const_item_cache= false;
 
5100
  const_item_cache= 0;
5102
5101
  while ((item= li++))
5103
5102
  {
5104
5103
    table_map tmp_table_map;
5115
5114
 
5116
5115
void Item_equal::update_used_tables()
5117
5116
{
5118
 
  List<Item_field>::iterator li(fields.begin());
 
5117
  List_iterator_fast<Item_field> li(fields);
5119
5118
  Item *item;
5120
5119
  not_null_tables_cache= used_tables_cache= 0;
5121
5120
  if ((const_item_cache= cond_false))
5133
5132
  Item_field *item_field;
5134
5133
  if (cond_false)
5135
5134
    return 0;
5136
 
  List<Item_field>::iterator it(fields.begin());
 
5135
  List_iterator_fast<Item_field> it(fields);
5137
5136
  Item *item= const_item ? const_item : it++;
 
5137
  if ((null_value= item->null_value))
 
5138
    return 0;
5138
5139
  eval_item->store_value(item);
5139
 
  if ((null_value= item->null_value))
5140
 
    return 0;
5141
5140
  while ((item_field= it++))
5142
5141
  {
5143
5142
    /* Skip fields of non-const tables. They haven't been read yet */
5144
 
    if (item_field->field->getTable()->const_table)
 
5143
    if (item_field->field->table->const_table)
5145
5144
    {
5146
 
      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))
5147
5146
        return 0;
5148
5147
    }
5149
5148
  }
5159
5158
 
5160
5159
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
5161
5160
{
5162
 
  List<Item_field>::iterator it(fields.begin());
 
5161
  List_iterator_fast<Item_field> it(fields);
5163
5162
  Item *item;
5164
5163
  while ((item= it++))
5165
5164
  {
5171
5170
 
5172
5171
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
5173
5172
{
5174
 
  List<Item_field>::iterator it(fields.begin());
 
5173
  List_iterator<Item_field> it(fields);
5175
5174
  Item *item;
5176
5175
  while ((item= it++))
5177
5176
  {
5180
5179
      return 0;
5181
5180
 
5182
5181
    /*
5183
 
      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
5184
5183
      really transformed, i.e. when a new item has been created.
5185
5184
      Otherwise we'll be allocating a lot of unnecessary memory for
5186
5185
      change records at each execution.
5187
5186
    */
5188
5187
    if (new_item != item)
5189
 
      getSession().change_item_tree((Item **) it.ref(), new_item);
 
5188
      current_thd->change_item_tree((Item **) it.ref(), new_item);
5190
5189
  }
5191
5190
  return Item_func::transform(transformer, arg);
5192
5191
}
5195
5194
{
5196
5195
  str->append(func_name());
5197
5196
  str->append('(');
5198
 
  List<Item_field>::iterator it(fields.begin());
 
5197
  List_iterator_fast<Item_field> it(fields);
5199
5198
  Item *item;
5200
5199
  if (const_item)
5201
5200
    const_item->print(str, query_type);
5213
5212
  str->append(')');
5214
5213
}
5215
5214
 
5216
 
cmp_item_datetime::cmp_item_datetime(Item *warn_item_arg) :
5217
 
  session(current_session),
5218
 
  warn_item(warn_item_arg),
5219
 
  lval_cache(0)
5220
 
{}
5221
 
 
5222
 
} /* namespace drizzled */