~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Joe Daly
  • Date: 2010-05-21 02:16:56 UTC
  • mto: This revision was merged to the branch mainline in revision 1555.
  • Revision ID: skinny.moey@gmail.com-20100521021656-bx6piitfh77jnl28
add statistics_variables.h

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>
36
 
#include <drizzled/sql_select.h>
37
 
#include <drizzled/temporal.h>
38
 
#include <drizzled/time_functions.h>
39
 
 
 
24
#include "config.h"
 
25
#include "drizzled/sql_select.h"
 
26
#include "drizzled/error.h"
 
27
#include "drizzled/temporal.h"
 
28
#include "drizzled/item/cmpfunc.h"
 
29
#include "drizzled/cached_item.h"
 
30
#include "drizzled/item/cache_int.h"
 
31
#include "drizzled/item/int_with_ref.h"
 
32
#include "drizzled/check_stack_overrun.h"
 
33
#include "drizzled/time_functions.h"
 
34
#include "drizzled/internal/my_sys.h"
40
35
#include <math.h>
41
36
#include <algorithm>
42
37
 
468
463
      the call to save_in_field below overrides that value.
469
464
    */
470
465
    if (field_item->depended_from)
471
 
    {
472
466
      orig_field_val= field->val_int();
473
 
    }
474
 
 
475
467
    if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
476
468
    {
477
469
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
480
472
        session->change_item_tree(item, tmp);
481
473
      result= 1;                                        // Item was replaced
482
474
    }
483
 
 
484
475
    /* Restore the original field value. */
485
476
    if (field_item->depended_from)
486
477
    {
487
 
      result= field->store(orig_field_val, field->isUnsigned());
 
478
      result= field->store(orig_field_val, true);
488
479
      /* orig_field_val must be a valid value that can be restored back. */
489
480
      assert(!result);
490
481
    }
498
489
void Item_bool_func2::fix_length_and_dec()
499
490
{
500
491
  max_length= 1;                                     // Function returns 0 or 1
 
492
  Session *session;
501
493
 
502
494
  /*
503
495
    As some compare functions are generated after sql_yacc,
535
527
    return;
536
528
  }
537
529
 
 
530
  session= current_session;
538
531
  Item_field *field_item= NULL;
539
532
 
540
533
  if (args[0]->real_item()->type() == FIELD_ITEM)
543
536
    if (field_item->field->can_be_compared_as_int64_t() &&
544
537
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
545
538
    {
546
 
      if (convert_constant_item(&getSession(), field_item, &args[1]))
 
539
      if (convert_constant_item(session, field_item, &args[1]))
547
540
      {
548
541
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
549
542
                         INT_RESULT);           // Works for all types.
559
552
          !(field_item->is_datetime() &&
560
553
            args[0]->result_type() == STRING_RESULT))
561
554
      {
562
 
        if (convert_constant_item(&getSession(), field_item, &args[0]))
 
555
        if (convert_constant_item(session, field_item, &args[0]))
563
556
        {
564
557
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
565
558
                           INT_RESULT); // Works for all types.
572
565
  set_cmp_func();
573
566
}
574
567
 
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
568
 
589
569
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
590
570
{
591
571
  owner= item;
592
572
  func= comparator_matrix[type]
593
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
594
 
 
 
573
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
595
574
  switch (type) {
596
575
  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
 
 
 
576
  {
 
577
    uint32_t n= (*a)->cols();
 
578
    if (n != (*b)->cols())
 
579
    {
 
580
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
 
581
      comparators= 0;
 
582
      return 1;
 
583
    }
 
584
    if (!(comparators= new Arg_comparator[n]))
 
585
      return 1;
 
586
    for (uint32_t i=0; i < n; i++)
 
587
    {
 
588
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
 
589
      {
 
590
        my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
 
591
        return 1;
 
592
      }
 
593
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
 
594
    }
 
595
    break;
 
596
  }
619
597
  case STRING_RESULT:
 
598
  {
 
599
    /*
 
600
      We must set cmp_charset here as we may be called from for an automatic
 
601
      generated item, like in natural join
 
602
    */
 
603
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
 
604
        cmp_collation.derivation == DERIVATION_NONE)
 
605
    {
 
606
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
 
607
      return 1;
 
608
    }
 
609
    if (cmp_collation.collation == &my_charset_bin)
620
610
    {
621
611
      /*
622
 
        We must set cmp_charset here as we may be called from for an automatic
623
 
        generated item, like in natural join
 
612
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
613
        without removing end space
624
614
      */
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;
 
615
      if (func == &Arg_comparator::compare_string)
 
616
        func= &Arg_comparator::compare_binary_string;
 
617
      else if (func == &Arg_comparator::compare_e_string)
 
618
        func= &Arg_comparator::compare_e_binary_string;
641
619
 
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'
 
620
      /*
 
621
        As this is binary compassion, mark all fields that they can't be
 
622
        transformed. Otherwise we would get into trouble with comparisons
 
623
        like:
 
624
        WHERE col= 'j' AND col LIKE BINARY 'j'
 
625
        which would be transformed to:
 
626
        WHERE col= 'j'
649
627
      */
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;
 
628
      (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
 
629
      (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
654
630
    }
 
631
    break;
 
632
  }
655
633
  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
 
    }
 
634
  {
 
635
    if (func == &Arg_comparator::compare_int_signed)
 
636
    {
 
637
      if ((*a)->unsigned_flag)
 
638
        func= (((*b)->unsigned_flag)?
 
639
               &Arg_comparator::compare_int_unsigned :
 
640
               &Arg_comparator::compare_int_unsigned_signed);
 
641
      else if ((*b)->unsigned_flag)
 
642
        func= &Arg_comparator::compare_int_signed_unsigned;
 
643
    }
 
644
    else if (func== &Arg_comparator::compare_e_int)
 
645
    {
 
646
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
 
647
        func= &Arg_comparator::compare_e_int_diff_signedness;
 
648
    }
 
649
    break;
 
650
  }
673
651
  case DECIMAL_RESULT:
674
652
    break;
675
653
  case REAL_RESULT:
 
654
  {
 
655
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
676
656
    {
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;
 
657
      precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
 
658
      if (func == &Arg_comparator::compare_real)
 
659
        func= &Arg_comparator::compare_real_fixed;
 
660
      else if (func == &Arg_comparator::compare_e_real)
 
661
        func= &Arg_comparator::compare_e_real_fixed;
686
662
    }
687
 
  }
688
 
 
 
663
    break;
 
664
  }
 
665
  default:
 
666
    assert(0);
 
667
  }
689
668
  return 0;
690
669
}
691
670
 
712
691
    converted value. 0 on error and on zero-dates -- check 'failure'
713
692
*/
714
693
 
715
 
static int64_t
716
 
get_date_from_str(Session *session, String *str, type::timestamp_t warn_type,
 
694
static uint64_t
 
695
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
717
696
                  char *warn_name, bool *error_arg)
718
697
{
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)
 
698
  uint64_t value= 0;
 
699
  int error;
 
700
  DRIZZLE_TIME l_time;
 
701
  enum enum_drizzle_timestamp_type ret;
 
702
 
 
703
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
 
704
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
 
705
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
706
                       &error);
 
707
 
 
708
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
729
709
  {
730
710
    /*
731
711
      Do not return yet, we may still want to throw a "trailing garbage"
732
712
      warning.
733
713
    */
734
714
    *error_arg= false;
735
 
    l_time.convert(value);
 
715
    value= TIME_to_uint64_t_datetime(&l_time);
736
716
  }
737
717
  else
738
718
  {
739
719
    *error_arg= true;
740
 
    error= type::CUT;                                   /* force warning */
 
720
    error= 1;                                   /* force warning */
741
721
  }
742
722
 
743
 
  if (error != type::VALID)
744
 
  {
 
723
  if (error > 0)
745
724
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
746
725
                                 str->ptr(), str->length(),
747
726
                                 warn_type, warn_name);
748
 
  }
749
727
 
750
728
  return value;
751
729
}
784
762
*/
785
763
 
786
764
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)
 
765
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
789
766
{
790
767
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
791
768
  Item *str_arg= 0, *date_arg= 0;
792
769
 
793
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
770
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
794
771
    return CMP_DATE_DFLT;
795
772
 
796
 
  if (in_a->is_datetime())
 
773
  if (a->is_datetime())
797
774
  {
798
 
    if (in_b->is_datetime())
799
 
    {
 
775
    if (b->is_datetime())
800
776
      cmp_type= CMP_DATE_WITH_DATE;
801
 
    }
802
 
    else if (in_b->result_type() == STRING_RESULT)
 
777
    else if (b->result_type() == STRING_RESULT)
803
778
    {
804
779
      cmp_type= CMP_DATE_WITH_STR;
805
 
      date_arg= in_a;
806
 
      str_arg= in_b;
 
780
      date_arg= a;
 
781
      str_arg= b;
807
782
    }
808
783
  }
809
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
784
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
810
785
  {
811
786
    cmp_type= CMP_STR_WITH_DATE;
812
 
    date_arg= in_b;
813
 
    str_arg= in_a;
 
787
    date_arg= b;
 
788
    str_arg= a;
814
789
  }
815
790
 
816
791
  if (cmp_type != CMP_DATE_DFLT)
840
815
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
841
816
       * from val_int(), not uint64_t...
842
817
       */
843
 
      int64_t value;
 
818
      uint64_t value;
844
819
      String *str_val;
845
820
      String tmp;
846
821
      /* DateTime used to pick up as many string conversion possibilities as possible. */
866
841
      }
867
842
 
868
843
      /* String conversion was good.  Convert to an integer for comparison purposes. */
869
 
      temporal.to_int64_t(&value);
 
844
      int64_t int_value;
 
845
      temporal.to_int64_t(&int_value);
 
846
      value= (uint64_t) int_value;
870
847
 
871
848
      if (const_value)
872
849
        *const_value= value;
880
857
                                        Item **a1, Item **a2,
881
858
                                        Item_result type)
882
859
{
883
 
  enum_date_cmp_type cmp_type;
884
 
  int64_t const_value= -1;
 
860
  enum enum_date_cmp_type cmp_type;
 
861
  uint64_t const_value= (uint64_t)-1;
885
862
  a= a1;
886
863
  b= a2;
887
864
 
888
865
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
889
866
  {
 
867
    session= current_session;
890
868
    owner= owner_arg;
891
869
    a_type= (*a)->field_type();
892
870
    b_type= (*b)->field_type();
893
871
    a_cache= 0;
894
872
    b_cache= 0;
895
873
 
896
 
    if (const_value != -1)
 
874
    if (const_value != (uint64_t)-1)
897
875
    {
898
876
      Item_cache_int *cache= new Item_cache_int();
899
877
      /* Mark the cache as non-const to prevent re-caching. */
914
892
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
915
893
    func= &Arg_comparator::compare_datetime;
916
894
    get_value_func= &get_datetime_value;
917
 
 
918
895
    return 0;
919
896
  }
920
897
 
924
901
 
925
902
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
926
903
{
 
904
  session= current_session;
927
905
  /* A caller will handle null values by itself. */
928
906
  owner= NULL;
929
907
  a= a1;
967
945
    obtained value
968
946
*/
969
947
 
970
 
int64_t
 
948
uint64_t
971
949
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
972
950
                   Item *warn_item, bool *is_null)
973
951
{
974
 
  int64_t value= 0;
 
952
  uint64_t value= 0;
975
953
  String buf, *str= 0;
976
954
  Item *item= **item_arg;
977
955
 
995
973
    str= item->val_str(&buf);
996
974
    *is_null= item->null_value;
997
975
  }
998
 
 
999
976
  if (*is_null)
1000
977
    return ~(uint64_t) 0;
1001
 
 
1002
978
  /*
1003
979
    Convert strings to the integer DATE/DATETIME representation.
1004
980
    Even if both dates provided in strings we can't compare them directly as
1009
985
  {
1010
986
    bool error;
1011
987
    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;
 
988
    enum enum_drizzle_timestamp_type t_type= f_type ==
 
989
      DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
1013
990
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
1014
991
    /*
1015
992
      If str did not contain a valid date according to the current
1032
1009
    *cache_arg= cache;
1033
1010
    *item_arg= cache_arg;
1034
1011
  }
1035
 
 
1036
1012
  return value;
1037
1013
}
1038
1014
 
1189
1165
 
1190
1166
int Arg_comparator::compare_decimal()
1191
1167
{
1192
 
  type::Decimal value1;
1193
 
  type::Decimal *val1= (*a)->val_decimal(&value1);
 
1168
  my_decimal value1;
 
1169
  my_decimal *val1= (*a)->val_decimal(&value1);
1194
1170
  if (!(*a)->null_value)
1195
1171
  {
1196
 
    type::Decimal value2;
1197
 
    type::Decimal *val2= (*b)->val_decimal(&value2);
 
1172
    my_decimal value2;
 
1173
    my_decimal *val2= (*b)->val_decimal(&value2);
1198
1174
    if (!(*b)->null_value)
1199
1175
    {
1200
1176
      owner->null_value= 0;
1201
 
      return class_decimal_cmp(val1, val2);
 
1177
      return my_decimal_cmp(val1, val2);
1202
1178
    }
1203
1179
  }
1204
1180
  owner->null_value= 1;
1216
1192
 
1217
1193
int Arg_comparator::compare_e_decimal()
1218
1194
{
1219
 
  type::Decimal value1, value2;
1220
 
  type::Decimal *val1= (*a)->val_decimal(&value1);
1221
 
  type::Decimal *val2= (*b)->val_decimal(&value2);
 
1195
  my_decimal value1, value2;
 
1196
  my_decimal *val1= (*a)->val_decimal(&value1);
 
1197
  my_decimal *val2= (*b)->val_decimal(&value2);
1222
1198
  if ((*a)->null_value || (*b)->null_value)
1223
1199
    return test((*a)->null_value && (*b)->null_value);
1224
 
  return test(class_decimal_cmp(val1, val2) == 0);
 
1200
  return test(my_decimal_cmp(val1, val2) == 0);
1225
1201
}
1226
1202
 
1227
1203
 
1631
1607
 
1632
1608
void Item_in_optimizer::cleanup()
1633
1609
{
1634
 
  item::function::Boolean::cleanup();
 
1610
  Item_bool_func::cleanup();
1635
1611
  if (!save_cache)
1636
1612
    cache= 0;
1637
1613
  return;
1684
1660
    change records at each execution.
1685
1661
  */
1686
1662
  if ((*args) != new_item)
1687
 
    getSession().change_item_tree(args, new_item);
 
1663
    current_session->change_item_tree(args, new_item);
1688
1664
 
1689
1665
  /*
1690
1666
    Transform the right IN operand which should be an Item_in_subselect or a
1839
1815
          {
1840
1816
            range->type= DECIMAL_RESULT;
1841
1817
            range->dec.init();
1842
 
            type::Decimal *dec= el->val_decimal(&range->dec);
 
1818
            my_decimal *dec= el->val_decimal(&range->dec);
1843
1819
            if (dec != &range->dec)
1844
1820
            {
1845
1821
              range->dec= *dec;
1889
1865
{
1890
1866
  assert(fixed == 1);
1891
1867
  double value;
1892
 
  type::Decimal dec_buf, *dec= NULL;
 
1868
  my_decimal dec_buf, *dec= NULL;
1893
1869
  uint32_t i;
1894
1870
 
1895
1871
  if (use_decimal_comparison)
1897
1873
    dec= row->element_index(0)->val_decimal(&dec_buf);
1898
1874
    if (row->element_index(0)->null_value)
1899
1875
      return -1;
1900
 
    class_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
 
1876
    my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
1901
1877
  }
1902
1878
  else
1903
1879
  {
1922
1898
        and we are comparing against a decimal
1923
1899
      */
1924
1900
      if (dec && range->type == DECIMAL_RESULT)
1925
 
        cmp_result= class_decimal_cmp(&range->dec, dec) <= 0;
 
1901
        cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
1926
1902
      else
1927
1903
        cmp_result= (range->dbl <= value);
1928
1904
      if (cmp_result)
1932
1908
    }
1933
1909
    interval_range *range= intervals+start;
1934
1910
    return ((dec && range->type == DECIMAL_RESULT) ?
1935
 
            class_decimal_cmp(dec, &range->dec) < 0 :
 
1911
            my_decimal_cmp(dec, &range->dec) < 0 :
1936
1912
            value < range->dbl) ? 0 : start + 1;
1937
1913
  }
1938
1914
 
1943
1919
        ((el->result_type() == DECIMAL_RESULT) ||
1944
1920
         (el->result_type() == INT_RESULT)))
1945
1921
    {
1946
 
      type::Decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
 
1922
      my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
1947
1923
      /* Skip NULL ranges. */
1948
1924
      if (el->null_value)
1949
1925
        continue;
1950
 
      if (class_decimal_cmp(e_dec, dec) > 0)
 
1926
      if (my_decimal_cmp(e_dec, dec) > 0)
1951
1927
        return i - 1;
1952
1928
    }
1953
1929
    else
1997
1973
  if (Item_func_opt_neg::fix_fields(session, ref))
1998
1974
    return 1;
1999
1975
 
2000
 
  session->getLex()->current_select->between_count++;
 
1976
  session->lex->current_select->between_count++;
2001
1977
 
2002
1978
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
2003
1979
  if (pred_level && !negated)
2018
1994
  int i;
2019
1995
  bool datetime_found= false;
2020
1996
  compare_as_dates= true;
 
1997
  Session *session= current_session;
2021
1998
 
2022
1999
  /*
2023
2000
    As some compare functions are generated after sql_yacc,
2055
2032
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2056
2033
    le_cmp.set_datetime_cmp_func(args, args + 2);
2057
2034
  }
2058
 
  else if (args[0]->real_item()->type() == FIELD_ITEM)
 
2035
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
 
2036
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2059
2037
  {
2060
2038
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2061
2039
    if (field_item->field->can_be_compared_as_int64_t())
2064
2042
        The following can't be recoded with || as convert_constant_item
2065
2043
        changes the argument
2066
2044
      */
2067
 
      if (convert_constant_item(&getSession(), field_item, &args[1]))
 
2045
      if (convert_constant_item(session, field_item, &args[1]))
2068
2046
        cmp_type=INT_RESULT;                    // Works for all types.
2069
 
      if (convert_constant_item(&getSession(), field_item, &args[2]))
 
2047
      if (convert_constant_item(session, field_item, &args[2]))
2070
2048
        cmp_type=INT_RESULT;                    // Works for all types.
2071
2049
    }
2072
2050
  }
2143
2121
  }
2144
2122
  else if (cmp_type == DECIMAL_RESULT)
2145
2123
  {
2146
 
    type::Decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
 
2124
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2147
2125
               a_buf, *a_dec, b_buf, *b_dec;
2148
2126
    if ((null_value=args[0]->null_value))
2149
2127
      return 0;
2150
2128
    a_dec= args[1]->val_decimal(&a_buf);
2151
2129
    b_dec= args[2]->val_decimal(&b_buf);
2152
2130
    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);
 
2131
      return (int64_t) ((my_decimal_cmp(dec, a_dec) >= 0 &&
 
2132
                          my_decimal_cmp(dec, b_dec) <= 0) != negated);
2155
2133
    if (args[1]->null_value && args[2]->null_value)
2156
2134
      null_value=1;
2157
2135
    else if (args[1]->null_value)
2158
 
      null_value= (class_decimal_cmp(dec, b_dec) <= 0);
 
2136
      null_value= (my_decimal_cmp(dec, b_dec) <= 0);
2159
2137
    else
2160
 
      null_value= (class_decimal_cmp(dec, a_dec) >= 0);
 
2138
      null_value= (my_decimal_cmp(dec, a_dec) >= 0);
2161
2139
  }
2162
2140
  else
2163
2141
  {
2215
2193
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2216
2194
  }
2217
2195
  else
2218
 
  {
2219
2196
    max_length= max(args[0]->max_length, args[1]->max_length);
2220
 
  }
2221
2197
 
2222
2198
  switch (hybrid_type)
2223
2199
  {
2224
2200
  case STRING_RESULT:
2225
2201
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2226
2202
    break;
2227
 
 
2228
2203
  case DECIMAL_RESULT:
2229
2204
  case REAL_RESULT:
2230
2205
    break;
2231
 
 
2232
2206
  case INT_RESULT:
2233
2207
    decimals= 0;
2234
2208
    break;
2235
 
 
2236
2209
  case ROW_RESULT:
 
2210
  default:
2237
2211
    assert(0);
2238
2212
  }
2239
 
 
2240
2213
  cached_field_type= agg_field_type(args, 2);
2241
2214
}
2242
2215
 
2291
2264
}
2292
2265
 
2293
2266
 
2294
 
type::Decimal *Item_func_ifnull::decimal_op(type::Decimal *decimal_value)
 
2267
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
2295
2268
{
2296
2269
  assert(fixed == 1);
2297
 
  type::Decimal *value= args[0]->val_decimal(decimal_value);
 
2270
  my_decimal *value= args[0]->val_decimal(decimal_value);
2298
2271
  if (!args[0]->null_value)
2299
2272
  {
2300
2273
    null_value= 0;
2464
2437
}
2465
2438
 
2466
2439
 
2467
 
type::Decimal *
2468
 
Item_func_if::val_decimal(type::Decimal *decimal_value)
 
2440
my_decimal *
 
2441
Item_func_if::val_decimal(my_decimal *decimal_value)
2469
2442
{
2470
2443
  assert(fixed == 1);
2471
2444
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
2472
 
  type::Decimal *value= arg->val_decimal(decimal_value);
 
2445
  my_decimal *value= arg->val_decimal(decimal_value);
2473
2446
  null_value= arg->null_value;
2474
2447
  return value;
2475
2448
}
2549
2522
}
2550
2523
 
2551
2524
 
2552
 
type::Decimal *
2553
 
Item_func_nullif::val_decimal(type::Decimal * decimal_value)
 
2525
my_decimal *
 
2526
Item_func_nullif::val_decimal(my_decimal * decimal_value)
2554
2527
{
2555
2528
  assert(fixed == 1);
2556
 
  type::Decimal *res;
 
2529
  my_decimal *res;
2557
2530
  if (!cmp.compare())
2558
2531
  {
2559
2532
    null_value=1;
2686
2659
}
2687
2660
 
2688
2661
 
2689
 
type::Decimal *Item_func_case::val_decimal(type::Decimal *decimal_value)
 
2662
my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
2690
2663
{
2691
2664
  assert(fixed == 1);
2692
2665
  char buff[MAX_FIELD_WIDTH];
2693
2666
  String dummy_str(buff, sizeof(buff), default_charset());
2694
2667
  Item *item= find_item(&dummy_str);
2695
 
  type::Decimal *res;
 
2668
  my_decimal *res;
2696
2669
 
2697
2670
  if (!item)
2698
2671
  {
2735
2708
 
2736
2709
void Item_func_case::agg_num_lengths(Item *arg)
2737
2710
{
2738
 
  uint32_t len= class_decimal_length_to_precision(arg->max_length, arg->decimals,
 
2711
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2739
2712
                                           arg->unsigned_flag) - arg->decimals;
2740
2713
  set_if_bigger(max_length, len);
2741
2714
  set_if_bigger(decimals, arg->decimals);
2774
2747
  */
2775
2748
  if (first_expr_num != -1)
2776
2749
  {
 
2750
    uint32_t i;
2777
2751
    agg[0]= args[first_expr_num];
2778
2752
    left_result_type= agg[0]->result_type();
2779
2753
 
2783
2757
    if (!(found_types= collect_cmp_types(agg, nagg)))
2784
2758
      return;
2785
2759
 
2786
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2760
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2787
2761
    {
2788
2762
      if (found_types & (1 << i) && !cmp_items[i])
2789
2763
      {
2818
2792
      agg_num_lengths(args[i + 1]);
2819
2793
    if (else_expr_num != -1)
2820
2794
      agg_num_lengths(args[else_expr_num]);
2821
 
    max_length= class_decimal_precision_to_length(max_length + decimals, decimals,
 
2795
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2822
2796
                                               unsigned_flag);
2823
2797
  }
2824
2798
}
2869
2843
 
2870
2844
void Item_func_case::cleanup()
2871
2845
{
 
2846
  uint32_t i;
2872
2847
  Item_func::cleanup();
2873
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2848
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2874
2849
  {
2875
2850
    delete cmp_items[i];
2876
2851
    cmp_items[i]= 0;
2877
2852
  }
 
2853
  return;
2878
2854
}
2879
2855
 
2880
2856
 
2925
2901
}
2926
2902
 
2927
2903
 
2928
 
type::Decimal *Item_func_coalesce::decimal_op(type::Decimal *decimal_value)
 
2904
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
2929
2905
{
2930
2906
  assert(fixed == 1);
2931
2907
  null_value= 0;
2932
2908
  for (uint32_t i= 0; i < arg_count; i++)
2933
2909
  {
2934
 
    type::Decimal *res= args[i]->val_decimal(decimal_value);
 
2910
    my_decimal *res= args[i]->val_decimal(decimal_value);
2935
2911
    if (!args[i]->null_value)
2936
2912
      return res;
2937
2913
  }
2944
2920
{
2945
2921
  cached_field_type= agg_field_type(args, arg_count);
2946
2922
  agg_result_type(&hybrid_type, args, arg_count);
2947
 
 
2948
2923
  switch (hybrid_type) {
2949
2924
  case STRING_RESULT:
2950
2925
    count_only_length();
2951
2926
    decimals= NOT_FIXED_DEC;
2952
2927
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2953
2928
    break;
2954
 
 
2955
2929
  case DECIMAL_RESULT:
2956
2930
    count_decimal_length();
2957
2931
    break;
2958
 
 
2959
2932
  case REAL_RESULT:
2960
2933
    count_real_length();
2961
2934
    break;
2962
 
 
2963
2935
  case INT_RESULT:
2964
2936
    count_only_length();
2965
2937
    decimals= 0;
2966
2938
    break;
2967
 
 
2968
2939
  case ROW_RESULT:
 
2940
  default:
2969
2941
    assert(0);
2970
2942
  }
2971
2943
}
3080
3052
}
3081
3053
 
3082
3054
 
3083
 
static int cmp_decimal(void *, type::Decimal *a, type::Decimal *b)
 
3055
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
3084
3056
{
3085
3057
  /*
3086
3058
    We need call of fixing buffer pointer, because fast sort just copy
3088
3060
  */
3089
3061
  a->fix_buffer_pointer();
3090
3062
  b->fix_buffer_pointer();
3091
 
  return class_decimal_cmp(a, b);
 
3063
  return my_decimal_cmp(a, b);
3092
3064
}
3093
3065
 
3094
3066
 
3196
3168
  return;
3197
3169
}
3198
3170
 
3199
 
in_int64_t::in_int64_t(uint32_t elements) :
3200
 
  in_vector(elements, sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
 
3171
in_int64_t::in_int64_t(uint32_t elements)
 
3172
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3201
3173
{}
3202
3174
 
3203
3175
void in_int64_t::set(uint32_t pos,Item *item)
3217
3189
  return (unsigned char*) &tmp;
3218
3190
}
3219
3191
 
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)
 
3192
void in_datetime::set(uint32_t pos,Item *item)
3228
3193
{
3229
3194
  Item **tmp_item= &item;
3230
3195
  bool is_null;
3264
3229
 
3265
3230
 
3266
3231
in_decimal::in_decimal(uint32_t elements)
3267
 
  :in_vector(elements, sizeof(type::Decimal),(qsort2_cmp) cmp_decimal, 0)
 
3232
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3268
3233
{}
3269
3234
 
3270
3235
 
3271
3236
void in_decimal::set(uint32_t pos, Item *item)
3272
3237
{
3273
 
  /* as far as 'item' is constant, we can store reference on type::Decimal */
3274
 
  type::Decimal *dec= ((type::Decimal *)base) + pos;
 
3238
  /* as far as 'item' is constant, we can store reference on my_decimal */
 
3239
  my_decimal *dec= ((my_decimal *)base) + pos;
3275
3240
  dec->len= DECIMAL_BUFF_LENGTH;
3276
3241
  dec->fix_buffer_pointer();
3277
 
  type::Decimal *res= item->val_decimal(dec);
 
3242
  my_decimal *res= item->val_decimal(dec);
3278
3243
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
3279
3244
  if (!item->null_value && res != dec)
3280
 
    class_decimal2decimal(res, dec);
 
3245
    my_decimal2decimal(res, dec);
3281
3246
}
3282
3247
 
3283
3248
 
3284
3249
unsigned char *in_decimal::get_value(Item *item)
3285
3250
{
3286
 
  type::Decimal *result= item->val_decimal(&val);
 
3251
  my_decimal *result= item->val_decimal(&val);
3287
3252
  if (item->null_value)
3288
3253
    return 0;
3289
3254
  return (unsigned char *)result;
3296
3261
  switch (type) {
3297
3262
  case STRING_RESULT:
3298
3263
    return new cmp_item_sort_string(cs);
3299
 
 
3300
3264
  case INT_RESULT:
3301
3265
    return new cmp_item_int;
3302
 
 
3303
3266
  case REAL_RESULT:
3304
3267
    return new cmp_item_real;
3305
 
 
3306
3268
  case ROW_RESULT:
3307
3269
    return new cmp_item_row;
3308
 
 
3309
3270
  case DECIMAL_RESULT:
3310
3271
    return new cmp_item_decimal;
 
3272
  default:
 
3273
    assert(0);
 
3274
    break;
3311
3275
  }
3312
 
 
3313
3276
  return 0; // to satisfy compiler :)
3314
3277
}
3315
3278
 
3442
3405
 
3443
3406
void cmp_item_decimal::store_value(Item *item)
3444
3407
{
3445
 
  type::Decimal *val= item->val_decimal(&value);
 
3408
  my_decimal *val= item->val_decimal(&value);
3446
3409
  /* val may be zero if item is nnull */
3447
3410
  if (val && val != &value)
3448
 
    class_decimal2decimal(val, &value);
 
3411
    my_decimal2decimal(val, &value);
3449
3412
}
3450
3413
 
3451
3414
 
3452
3415
int cmp_item_decimal::cmp(Item *arg)
3453
3416
{
3454
 
  type::Decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
 
3417
  my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
3455
3418
  if (arg->null_value)
3456
3419
    return 1;
3457
 
  return class_decimal_cmp(&value, tmp);
 
3420
  return my_decimal_cmp(&value, tmp);
3458
3421
}
3459
3422
 
3460
3423
 
3461
3424
int cmp_item_decimal::compare(cmp_item *arg)
3462
3425
{
3463
3426
  cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
3464
 
  return class_decimal_cmp(&value, &l_cmp->value);
 
3427
  return my_decimal_cmp(&value, &l_cmp->value);
3465
3428
}
3466
3429
 
3467
3430
 
3574
3537
{
3575
3538
  Item **arg, **arg_end;
3576
3539
  bool const_itm= 1;
 
3540
  Session *session= current_session;
3577
3541
  bool datetime_found= false;
3578
3542
  /* true <=> arguments values will be compared as DATETIMEs. */
3579
3543
  bool compare_as_datetime= false;
3580
3544
  Item *date_arg= 0;
3581
3545
  uint32_t found_types= 0;
3582
 
  uint32_t type_cnt= 0;
 
3546
  uint32_t type_cnt= 0, i;
3583
3547
  Item_result cmp_type= STRING_RESULT;
3584
3548
  left_result_type= args[0]->result_type();
3585
3549
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
3593
3557
      break;
3594
3558
    }
3595
3559
  }
3596
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3560
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
3597
3561
  {
3598
3562
    if (found_types & 1 << i)
3599
3563
    {
3700
3664
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3701
3665
  {
3702
3666
    if (compare_as_datetime)
3703
 
    {
3704
3667
      array= new in_datetime(date_arg, arg_count - 1);
3705
 
    }
3706
3668
    else
3707
3669
    {
3708
3670
      /*
3713
3675
        comparison type accordingly.
3714
3676
      */
3715
3677
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3678
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3716
3679
          cmp_type != INT_RESULT)
3717
3680
      {
3718
3681
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3721
3684
          bool all_converted= true;
3722
3685
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3723
3686
          {
3724
 
            if (!convert_constant_item (&getSession(), field_item, &arg[0]))
 
3687
            if (!convert_constant_item (session, field_item, &arg[0]))
3725
3688
              all_converted= false;
3726
3689
          }
3727
3690
          if (all_converted)
3728
3691
            cmp_type= INT_RESULT;
3729
3692
        }
3730
3693
      }
3731
 
 
3732
3694
      switch (cmp_type) {
3733
3695
      case STRING_RESULT:
3734
3696
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3735
3697
                            cmp_collation.collation);
3736
3698
        break;
3737
 
 
3738
3699
      case INT_RESULT:
3739
3700
        array= new in_int64_t(arg_count-1);
3740
3701
        break;
3741
 
 
3742
3702
      case REAL_RESULT:
3743
3703
        array= new in_double(arg_count-1);
3744
3704
        break;
3745
 
 
3746
3705
      case ROW_RESULT:
3747
3706
        /*
3748
3707
          The row comparator was created at the beginning but only DATETIME
3751
3710
        */
3752
3711
        ((in_row*)array)->tmp.store_value(args[0]);
3753
3712
        break;
3754
 
 
3755
3713
      case DECIMAL_RESULT:
3756
3714
        array= new in_decimal(arg_count - 1);
3757
3715
        break;
 
3716
      default:
 
3717
        assert(0);
 
3718
        return;
3758
3719
      }
3759
3720
    }
3760
 
 
3761
 
    if (array && !(getSession().is_fatal_error))                // If not EOM
 
3721
    if (array && !(session->is_fatal_error))            // If not EOM
3762
3722
    {
3763
3723
      uint32_t j=0;
3764
3724
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3765
3725
      {
3766
 
        if (!args[arg_num]->null_value)                 // Skip NULL values
 
3726
        if (!args[arg_num]->null_value)                 // Skip NULL values
3767
3727
        {
3768
3728
          array->set(j,args[arg_num]);
3769
 
          j++;
 
3729
          j++;
3770
3730
        }
3771
 
        else
3772
 
          have_null= 1;
 
3731
        else
 
3732
          have_null= 1;
3773
3733
      }
3774
3734
      if ((array->used_count= j))
3775
 
        array->sort();
 
3735
        array->sort();
3776
3736
    }
3777
3737
  }
3778
3738
  else
3781
3741
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3782
3742
    else
3783
3743
    {
3784
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3744
      for (i= 0; i <= (uint32_t) DECIMAL_RESULT; i++)
3785
3745
      {
3786
3746
        if (found_types & (1 << i) && !cmp_items[i])
3787
3747
        {
3874
3834
 
3875
3835
 
3876
3836
Item_cond::Item_cond(Session *session, Item_cond *item)
3877
 
  :item::function::Boolean(session, item),
 
3837
  :Item_bool_func(session, item),
3878
3838
   abort_on_null(item->abort_on_null),
3879
3839
   and_tables_cache(item->and_tables_cache)
3880
3840
{
3886
3846
 
3887
3847
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3888
3848
{
3889
 
  List<Item>::iterator li(item->list.begin());
 
3849
  List_iterator_fast<Item> li(item->list);
3890
3850
  while (Item *it= li++)
3891
3851
    list.push_back(it->copy_andor_structure(session));
3892
3852
}
3896
3856
Item_cond::fix_fields(Session *session, Item **)
3897
3857
{
3898
3858
  assert(fixed == 0);
3899
 
  List<Item>::iterator li(list.begin());
 
3859
  List_iterator<Item> li(list);
3900
3860
  Item *item;
3901
3861
  void *orig_session_marker= session->session_marker;
3902
3862
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
3903
3863
  not_null_tables_cache= used_tables_cache= 0;
3904
 
  const_item_cache= true;
 
3864
  const_item_cache= 1;
3905
3865
 
3906
3866
  if (functype() == COND_OR_FUNC)
3907
3867
    session->session_marker= 0;
3936
3896
           !((Item_cond*) item)->list.is_empty())
3937
3897
    {                                           // Identical function
3938
3898
      li.replace(((Item_cond*) item)->list);
3939
 
      ((Item_cond*) item)->list.clear();
 
3899
      ((Item_cond*) item)->list.empty();
3940
3900
      item= *li.ref();                          // new current item
3941
3901
    }
3942
3902
    if (abort_on_null)
3962
3922
    if (item->maybe_null)
3963
3923
      maybe_null=1;
3964
3924
  }
3965
 
  session->getLex()->current_select->cond_count+= list.elements;
 
3925
  session->lex->current_select->cond_count+= list.elements;
3966
3926
  session->session_marker= orig_session_marker;
3967
3927
  fix_length_and_dec();
3968
3928
  fixed= 1;
3972
3932
 
3973
3933
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3974
3934
{
3975
 
  List<Item>::iterator li(list.begin());
 
3935
  List_iterator<Item> li(list);
3976
3936
  Item *item;
3977
3937
 
3978
3938
  used_tables_cache=0;
3979
 
  const_item_cache= true;
 
3939
  const_item_cache=1;
3980
3940
 
3981
3941
  and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
3982
3942
  not_null_tables_cache= 0;
4004
3964
 
4005
3965
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
4006
3966
{
4007
 
  List<Item>::iterator li(list.begin());
 
3967
  List_iterator_fast<Item> li(list);
4008
3968
  Item *item;
4009
3969
  while ((item= li++))
4010
3970
    if (item->walk(processor, walk_subquery, arg))
4033
3993
 
4034
3994
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4035
3995
{
4036
 
  List<Item>::iterator li(list.begin());
 
3996
  List_iterator<Item> li(list);
4037
3997
  Item *item;
4038
3998
  while ((item= li++))
4039
3999
  {
4048
4008
      change records at each execution.
4049
4009
    */
4050
4010
    if (new_item != item)
4051
 
      getSession().change_item_tree(li.ref(), new_item);
 
4011
      current_session->change_item_tree(li.ref(), new_item);
4052
4012
  }
4053
4013
  return Item_func::transform(transformer, arg);
4054
4014
}
4084
4044
  if (!(this->*analyzer)(arg_p))
4085
4045
    return 0;
4086
4046
 
4087
 
  List<Item>::iterator li(list.begin());
 
4047
  List_iterator<Item> li(list);
4088
4048
  Item *item;
4089
4049
  while ((item= li++))
4090
4050
  {
4103
4063
void Item_cond::traverse_cond(Cond_traverser traverser,
4104
4064
                              void *arg, traverse_order order)
4105
4065
{
4106
 
  List<Item>::iterator li(list.begin());
 
4066
  List_iterator<Item> li(list);
4107
4067
  Item *item;
4108
4068
 
4109
4069
  switch (order) {
4144
4104
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4145
4105
                               List<Item> &fields)
4146
4106
{
4147
 
  List<Item>::iterator li(list.begin());
 
4107
  List_iterator<Item> li(list);
4148
4108
  Item *item;
4149
4109
  while ((item= li++))
4150
4110
    item->split_sum_func(session, ref_pointer_array,
4161
4121
 
4162
4122
void Item_cond::update_used_tables()
4163
4123
{
4164
 
  List<Item>::iterator li(list.begin());
 
4124
  List_iterator_fast<Item> li(list);
4165
4125
  Item *item;
4166
4126
 
4167
4127
  used_tables_cache=0;
4168
 
  const_item_cache= true;
 
4128
  const_item_cache=1;
4169
4129
  while ((item=li++))
4170
4130
  {
4171
4131
    item->update_used_tables();
4178
4138
void Item_cond::print(String *str, enum_query_type query_type)
4179
4139
{
4180
4140
  str->append('(');
4181
 
  List<Item>::iterator li(list.begin());
 
4141
  List_iterator_fast<Item> li(list);
4182
4142
  Item *item;
4183
4143
  if ((item=li++))
4184
4144
    item->print(str, query_type);
4195
4155
 
4196
4156
void Item_cond::neg_arguments(Session *session)
4197
4157
{
4198
 
  List<Item>::iterator li(list.begin());
 
4158
  List_iterator<Item> li(list);
4199
4159
  Item *item;
4200
4160
  while ((item= li++))          /* Apply not transformation to the arguments */
4201
4161
  {
4233
4193
int64_t Item_cond_and::val_int()
4234
4194
{
4235
4195
  assert(fixed == 1);
4236
 
  List<Item>::iterator li(list.begin());
 
4196
  List_iterator_fast<Item> li(list);
4237
4197
  Item *item;
4238
4198
  null_value= 0;
4239
4199
  while ((item=li++))
4251
4211
int64_t Item_cond_or::val_int()
4252
4212
{
4253
4213
  assert(fixed == 1);
4254
 
  List<Item>::iterator li(list.begin());
 
4214
  List_iterator_fast<Item> li(list);
4255
4215
  Item *item;
4256
4216
  null_value=0;
4257
4217
  while ((item=li++))
4488
4448
      {
4489
4449
        pattern     = first + 1;
4490
4450
        pattern_len = (int) len - 2;
4491
 
        int *suff = (int*) session->getMemRoot()->allocate((int) (sizeof(int)*
4492
 
                                                                  ((pattern_len + 1)*2+
4493
 
                                                                   alphabet_size)));
 
4451
        int *suff = (int*) session->alloc((int) (sizeof(int)*
 
4452
                                      ((pattern_len + 1)*2+
 
4453
                                      alphabet_size)));
4494
4454
        bmGs      = suff + pattern_len + 1;
4495
4455
        bmBc      = bmGs + pattern_len + 1;
4496
4456
        turboBM_compute_good_suffix_shifts(suff);
4507
4467
  Item_bool_func2::cleanup();
4508
4468
}
4509
4469
 
4510
 
static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
4511
 
{
4512
4470
#ifdef LIKE_CMP_TOUPPER
4513
 
  return cs->toupper(a);
 
4471
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
4514
4472
#else
4515
 
  return cs->sort_order[a];
 
4473
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
4516
4474
#endif
4517
 
}
 
4475
 
4518
4476
 
4519
4477
/**
4520
4478
  Precomputation dependent only on pattern_len.
4651
4609
 
4652
4610
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
4653
4611
{
4654
 
  int bcShift;
4655
 
  int turboShift;
 
4612
  register int bcShift;
 
4613
  register int turboShift;
4656
4614
  int shift = pattern_len;
4657
4615
  int j     = 0;
4658
4616
  int u     = 0;
4666
4624
  {
4667
4625
    while (j <= tlmpl)
4668
4626
    {
4669
 
      int i= plm1;
 
4627
      register int i= plm1;
4670
4628
      while (i >= 0 && pattern[i] == text[i + j])
4671
4629
      {
4672
4630
        i--;
4676
4634
      if (i < 0)
4677
4635
        return 1;
4678
4636
 
4679
 
      const int v = plm1 - i;
 
4637
      register const int v = plm1 - i;
4680
4638
      turboShift = u - v;
4681
4639
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
4682
4640
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4697
4655
  {
4698
4656
    while (j <= tlmpl)
4699
4657
    {
4700
 
      int i = plm1;
 
4658
      register int i = plm1;
4701
4659
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4702
4660
      {
4703
4661
        i--;
4708
4666
      if (i < 0)
4709
4667
        return 1;
4710
4668
 
4711
 
      const int v= plm1 - i;
 
4669
      register const int v= plm1 - i;
4712
4670
      turboShift= u - v;
4713
4671
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4714
4672
      shift= (turboShift > bcShift) ? turboShift : bcShift;
4749
4707
int64_t Item_cond_xor::val_int()
4750
4708
{
4751
4709
  assert(fixed == 1);
4752
 
  List<Item>::iterator li(list.begin());
 
4710
  List_iterator<Item> li(list);
4753
4711
  Item *item;
4754
4712
  int result=0;
4755
4713
  null_value=0;
4909
4867
}
4910
4868
 
4911
4869
Item_equal::Item_equal(Item_field *f1, Item_field *f2)
4912
 
  : item::function::Boolean(), const_item(0), eval_item(0), cond_false(0)
 
4870
  : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
4913
4871
{
4914
 
  const_item_cache= false;
 
4872
  const_item_cache= 0;
4915
4873
  fields.push_back(f1);
4916
4874
  fields.push_back(f2);
4917
4875
}
4918
4876
 
4919
4877
Item_equal::Item_equal(Item *c, Item_field *f)
4920
 
  : item::function::Boolean(), eval_item(0), cond_false(0)
 
4878
  : Item_bool_func(), eval_item(0), cond_false(0)
4921
4879
{
4922
 
  const_item_cache= false;
 
4880
  const_item_cache= 0;
4923
4881
  fields.push_back(f);
4924
4882
  const_item= c;
4925
4883
}
4926
4884
 
4927
4885
 
4928
4886
Item_equal::Item_equal(Item_equal *item_equal)
4929
 
  : item::function::Boolean(), eval_item(0), cond_false(0)
 
4887
  : Item_bool_func(), eval_item(0), cond_false(0)
4930
4888
{
4931
 
  const_item_cache= false;
4932
 
  List<Item_field>::iterator li(item_equal->fields.begin());
 
4889
  const_item_cache= 0;
 
4890
  List_iterator_fast<Item_field> li(item_equal->fields);
4933
4891
  Item_field *item;
4934
4892
  while ((item= li++))
4935
4893
  {
4952
4910
  func->set_cmp_func();
4953
4911
  func->quick_fix_field();
4954
4912
  if ((cond_false= !func->val_int()))
4955
 
    const_item_cache= true;
 
4913
    const_item_cache= 1;
4956
4914
}
4957
4915
 
4958
4916
void Item_equal::add(Item_field *f)
4981
4939
 
4982
4940
bool Item_equal::contains(Field *field)
4983
4941
{
4984
 
  List<Item_field>::iterator it(fields.begin());
 
4942
  List_iterator_fast<Item_field> it(fields);
4985
4943
  Item_field *item;
4986
4944
  while ((item= it++))
4987
4945
  {
5040
4998
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
5041
4999
{
5042
5000
  bool swap;
5043
 
  List<Item_field>::iterator it(fields.begin());
 
5001
  List_iterator<Item_field> it(fields);
5044
5002
  do
5045
5003
  {
5046
5004
    Item_field *item1= it++;
5064
5022
        ref1= ref2;
5065
5023
      }
5066
5024
    }
5067
 
    it= fields.begin();
 
5025
    it.rewind();
5068
5026
  } while (swap);
5069
5027
}
5070
5028
 
5081
5039
 
5082
5040
void Item_equal::update_const()
5083
5041
{
5084
 
  List<Item_field>::iterator it(fields.begin());
 
5042
  List_iterator<Item_field> it(fields);
5085
5043
  Item *item;
5086
5044
  while ((item= it++))
5087
5045
  {
5095
5053
 
5096
5054
bool Item_equal::fix_fields(Session *, Item **)
5097
5055
{
5098
 
  List<Item_field>::iterator li(fields.begin());
 
5056
  List_iterator_fast<Item_field> li(fields);
5099
5057
  Item *item;
5100
5058
  not_null_tables_cache= used_tables_cache= 0;
5101
 
  const_item_cache= false;
 
5059
  const_item_cache= 0;
5102
5060
  while ((item= li++))
5103
5061
  {
5104
5062
    table_map tmp_table_map;
5115
5073
 
5116
5074
void Item_equal::update_used_tables()
5117
5075
{
5118
 
  List<Item_field>::iterator li(fields.begin());
 
5076
  List_iterator_fast<Item_field> li(fields);
5119
5077
  Item *item;
5120
5078
  not_null_tables_cache= used_tables_cache= 0;
5121
5079
  if ((const_item_cache= cond_false))
5133
5091
  Item_field *item_field;
5134
5092
  if (cond_false)
5135
5093
    return 0;
5136
 
  List<Item_field>::iterator it(fields.begin());
 
5094
  List_iterator_fast<Item_field> it(fields);
5137
5095
  Item *item= const_item ? const_item : it++;
 
5096
  if ((null_value= item->null_value))
 
5097
    return 0;
5138
5098
  eval_item->store_value(item);
5139
 
  if ((null_value= item->null_value))
5140
 
    return 0;
5141
5099
  while ((item_field= it++))
5142
5100
  {
5143
5101
    /* Skip fields of non-const tables. They haven't been read yet */
5144
 
    if (item_field->field->getTable()->const_table)
 
5102
    if (item_field->field->table->const_table)
5145
5103
    {
5146
 
      if (eval_item->cmp(item_field) || (null_value= item_field->null_value))
 
5104
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5147
5105
        return 0;
5148
5106
    }
5149
5107
  }
5159
5117
 
5160
5118
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
5161
5119
{
5162
 
  List<Item_field>::iterator it(fields.begin());
 
5120
  List_iterator_fast<Item_field> it(fields);
5163
5121
  Item *item;
5164
5122
  while ((item= it++))
5165
5123
  {
5171
5129
 
5172
5130
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
5173
5131
{
5174
 
  List<Item_field>::iterator it(fields.begin());
 
5132
  List_iterator<Item_field> it(fields);
5175
5133
  Item *item;
5176
5134
  while ((item= it++))
5177
5135
  {
5186
5144
      change records at each execution.
5187
5145
    */
5188
5146
    if (new_item != item)
5189
 
      getSession().change_item_tree((Item **) it.ref(), new_item);
 
5147
      current_session->change_item_tree((Item **) it.ref(), new_item);
5190
5148
  }
5191
5149
  return Item_func::transform(transformer, arg);
5192
5150
}
5195
5153
{
5196
5154
  str->append(func_name());
5197
5155
  str->append('(');
5198
 
  List<Item_field>::iterator it(fields.begin());
 
5156
  List_iterator_fast<Item_field> it(fields);
5199
5157
  Item *item;
5200
5158
  if (const_item)
5201
5159
    const_item->print(str, query_type);
5213
5171
  str->append(')');
5214
5172
}
5215
5173
 
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
5174
} /* namespace drizzled */