~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/rem/rem0cmp.c

  • Committer: Brian Aker
  • Date: 2008-10-28 08:36:02 UTC
  • mfrom: (520.4.13 merge-innodb-plugin)
  • Revision ID: brian@tangent.org-20081028083602-0p3zzlhlxr5q2sqo
Merging Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
                                /* out: 1, 0, -1, if dtuple is greater, equal,
47
47
                                less than rec, respectively, when only the
48
48
                                common first fields are compared */
49
 
        dtuple_t*       dtuple, /* in: data tuple */
50
 
        rec_t*          rec,    /* in: physical record which differs from
 
49
        const dtuple_t* dtuple, /* in: data tuple */
 
50
        const rec_t*    rec,    /* in: physical record which differs from
51
51
                                dtuple in some of the common fields, or which
52
52
                                has an equal number or more fields than
53
53
                                dtuple */
70
70
                                        equal, less than b, respectively */
71
71
        int             mysql_type,     /* in: MySQL type */
72
72
        uint            charset_number, /* in: number of the charset */
73
 
        unsigned char*  a,              /* in: data field */
 
73
        const unsigned char* a,         /* in: data field */
74
74
        unsigned int    a_length,       /* in: data field length,
75
75
                                        not UNIV_SQL_NULL */
76
 
        unsigned char*  b,              /* in: data field */
 
76
        const unsigned char* b,         /* in: data field */
77
77
        unsigned int    b_length);      /* in: data field length,
78
78
                                        not UNIV_SQL_NULL */
79
79
#endif /* !UNIV_HOTBACKUP */
93
93
 
94
94
/*****************************************************************
95
95
Returns TRUE if two columns are equal for comparison purposes. */
96
 
 
 
96
UNIV_INTERN
97
97
ibool
98
98
cmp_cols_are_equal(
99
99
/*===============*/
157
157
                                        equal, less than b, respectively */
158
158
        ulint           mtype,          /* in: main type */
159
159
        ulint           prtype,         /* in: precise type */
160
 
        unsigned char*  a,              /* in: data field */
 
160
        const byte*     a,              /* in: data field */
161
161
        unsigned int    a_length,       /* in: data field length,
162
162
                                        not UNIV_SQL_NULL */
163
 
        unsigned char*  b,              /* in: data field */
 
163
        const byte*     b,              /* in: data field */
164
164
        unsigned int    b_length)       /* in: data field length,
165
165
                                        not UNIV_SQL_NULL */
166
166
{
260
260
        case DATA_VARMYSQL:
261
261
        case DATA_MYSQL:
262
262
                return(innobase_mysql_cmp(
263
 
                               (int)(prtype & DATA_DRIZZLE_TYPE_MASK),
 
263
                               (int)(prtype & DATA_MYSQL_TYPE_MASK),
264
264
                               (uint)dtype_get_charset_coll(prtype),
265
265
                               a, a_length, b, b_length));
266
266
        default:
277
277
/*****************************************************************
278
278
This function is used to compare two data fields for which we know the
279
279
data type. */
280
 
 
 
280
UNIV_INTERN
281
281
int
282
282
cmp_data_data_slow(
283
283
/*===============*/
285
285
                                less than data2, respectively */
286
286
        ulint           mtype,  /* in: main type */
287
287
        ulint           prtype, /* in: precise type */
288
 
        byte*           data1,  /* in: data field (== a pointer to a memory
 
288
        const byte*     data1,  /* in: data field (== a pointer to a memory
289
289
                                buffer) */
290
290
        ulint           len1,   /* in: data field length or UNIV_SQL_NULL */
291
 
        byte*           data2,  /* in: data field (== a pointer to a memory
 
291
        const byte*     data2,  /* in: data field (== a pointer to a memory
292
292
                                buffer) */
293
293
        ulint           len2)   /* in: data field length or UNIV_SQL_NULL */
294
294
{
318
318
            || (mtype == DATA_BLOB
319
319
                && 0 == (prtype & DATA_BINARY_TYPE)
320
320
                && dtype_get_charset_coll(prtype)
321
 
                != DATA_DRIZZLE_LATIN1_SWEDISH_CHARSET_COLL)) {
 
321
                != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
322
322
 
323
323
                return(cmp_whole_field(mtype, prtype,
324
324
                                       data1, (unsigned) len1,
403
403
the m fields rec has. If rec has an externally stored field we do not
404
404
compare it but return with value 0 if such a comparison should be
405
405
made. */
406
 
 
 
406
UNIV_INTERN
407
407
int
408
408
cmp_dtuple_rec_with_match(
409
409
/*======================*/
412
412
                                common first fields are compared, or
413
413
                                until the first externally stored field in
414
414
                                rec */
415
 
        dtuple_t*       dtuple, /* in: data tuple */
416
 
        rec_t*          rec,    /* in: physical record which differs from
 
415
        const dtuple_t* dtuple, /* in: data tuple */
 
416
        const rec_t*    rec,    /* in: physical record which differs from
417
417
                                dtuple in some of the common fields, or which
418
418
                                has an equal number or more fields than
419
419
                                dtuple */
427
427
                                value for current comparison */
428
428
{
429
429
#ifndef UNIV_HOTBACKUP
430
 
        dfield_t*       dtuple_field;   /* current field in logical record */
 
430
        const dfield_t* dtuple_field;   /* current field in logical record */
431
431
        ulint           dtuple_f_len;   /* the length of the current field
432
432
                                        in the logical record */
433
 
        byte*           dtuple_b_ptr;   /* pointer to the current byte in
 
433
        const byte*     dtuple_b_ptr;   /* pointer to the current byte in
434
434
                                        logical field data */
435
435
        ulint           dtuple_byte;    /* value of current byte to be compared
436
436
                                        in dtuple*/
437
437
        ulint           rec_f_len;      /* length of current field in rec */
438
 
        byte*           rec_b_ptr;      /* pointer to the current byte in
 
438
        const byte*     rec_b_ptr;      /* pointer to the current byte in
439
439
                                        rec field */
440
440
        ulint           rec_byte;       /* value of current byte to be
441
441
                                        compared in rec */
459
459
                                                     rec_offs_comp(offsets));
460
460
                ulint   tup_info = dtuple_get_info_bits(dtuple);
461
461
 
462
 
                if (rec_info & REC_INFO_MIN_REC_FLAG) {
 
462
                if (UNIV_UNLIKELY(rec_info & REC_INFO_MIN_REC_FLAG)) {
463
463
                        ret = !(tup_info & REC_INFO_MIN_REC_FLAG);
464
464
                        goto order_resolved;
465
 
                } else if (tup_info & REC_INFO_MIN_REC_FLAG) {
 
465
                } else if (UNIV_UNLIKELY(tup_info & REC_INFO_MIN_REC_FLAG)) {
466
466
                        ret = -1;
467
467
                        goto order_resolved;
468
468
                }
527
527
                    || (mtype == DATA_BLOB
528
528
                        && 0 == (prtype & DATA_BINARY_TYPE)
529
529
                        && dtype_get_charset_coll(prtype)
530
 
                        != DATA_DRIZZLE_LATIN1_SWEDISH_CHARSET_COLL)) {
 
530
                        != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
531
531
 
532
532
                        ret = cmp_whole_field(mtype, prtype,
533
533
                                              dfield_get_data(dtuple_field),
598
598
                        }
599
599
 
600
600
                        ret = (int) (dtuple_byte - rec_byte);
601
 
                        if (UNIV_UNLIKELY(ret)) {
 
601
                        if (UNIV_LIKELY(ret)) {
602
602
                                if (ret < 0) {
603
603
                                        ret = -1;
604
604
                                        goto order_resolved;
645
645
 
646
646
/******************************************************************
647
647
Compares a data tuple to a physical record. */
648
 
 
 
648
UNIV_INTERN
649
649
int
650
650
cmp_dtuple_rec(
651
651
/*===========*/
652
652
                                /* out: 1, 0, -1, if dtuple is greater, equal,
653
653
                                less than rec, respectively; see the comments
654
654
                                for cmp_dtuple_rec_with_match */
655
 
        dtuple_t*       dtuple, /* in: data tuple */
656
 
        rec_t*          rec,    /* in: physical record */
 
655
        const dtuple_t* dtuple, /* in: data tuple */
 
656
        const rec_t*    rec,    /* in: physical record */
657
657
        const ulint*    offsets)/* in: array returned by rec_get_offsets() */
658
658
{
659
659
        ulint   matched_fields  = 0;
667
667
/******************************************************************
668
668
Checks if a dtuple is a prefix of a record. The last field in dtuple
669
669
is allowed to be a prefix of the corresponding field in the record. */
670
 
 
 
670
UNIV_INTERN
671
671
ibool
672
672
cmp_dtuple_is_prefix_of_rec(
673
673
/*========================*/
674
674
                                /* out: TRUE if prefix */
675
 
        dtuple_t*       dtuple, /* in: data tuple */
676
 
        rec_t*          rec,    /* in: physical record */
 
675
        const dtuple_t* dtuple, /* in: data tuple */
 
676
        const rec_t*    rec,    /* in: physical record */
677
677
        const ulint*    offsets)/* in: array returned by rec_get_offsets() */
678
678
{
679
679
        ulint   n_fields;
704
704
        return(FALSE);
705
705
}
706
706
 
 
707
#ifndef UNIV_HOTBACKUP
 
708
/*****************************************************************
 
709
Compare two physical records that contain the same number of columns,
 
710
none of which are stored externally. */
 
711
UNIV_INTERN
 
712
int
 
713
cmp_rec_rec_simple(
 
714
/*===============*/
 
715
                                        /* out: 1, 0 , -1 if rec1 is greater,
 
716
                                        equal, less, respectively, than rec2 */
 
717
        const rec_t*            rec1,   /* in: physical record */
 
718
        const rec_t*            rec2,   /* in: physical record */
 
719
        const ulint*            offsets1,/* in: rec_get_offsets(rec1, index) */
 
720
        const ulint*            offsets2,/* in: rec_get_offsets(rec2, index) */
 
721
        const dict_index_t*     index)  /* in: data dictionary index */
 
722
{
 
723
        ulint           rec1_f_len;     /* length of current field in rec1 */
 
724
        const byte*     rec1_b_ptr;     /* pointer to the current byte
 
725
                                        in rec1 field */
 
726
        ulint           rec1_byte;      /* value of current byte to be
 
727
                                        compared in rec1 */
 
728
        ulint           rec2_f_len;     /* length of current field in rec2 */
 
729
        const byte*     rec2_b_ptr;     /* pointer to the current byte
 
730
                                        in rec2 field */
 
731
        ulint           rec2_byte;      /* value of current byte to be
 
732
                                        compared in rec2 */
 
733
        ulint           cur_field;      /* current field number */
 
734
        ulint           n_uniq;
 
735
 
 
736
        n_uniq = dict_index_get_n_unique(index);
 
737
        ut_ad(rec_offs_n_fields(offsets1) >= n_uniq);
 
738
        ut_ad(rec_offs_n_fields(offsets2) >= n_uniq);
 
739
 
 
740
        ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2));
 
741
 
 
742
        for (cur_field = 0; cur_field < n_uniq; cur_field++) {
 
743
 
 
744
                ulint   cur_bytes;
 
745
                ulint   mtype;
 
746
                ulint   prtype;
 
747
 
 
748
                {
 
749
                        const dict_col_t*       col
 
750
                                = dict_index_get_nth_col(index, cur_field);
 
751
 
 
752
                        mtype = col->mtype;
 
753
                        prtype = col->prtype;
 
754
                }
 
755
 
 
756
                ut_ad(!rec_offs_nth_extern(offsets1, cur_field));
 
757
                ut_ad(!rec_offs_nth_extern(offsets2, cur_field));
 
758
 
 
759
                rec1_b_ptr = rec_get_nth_field(rec1, offsets1,
 
760
                                               cur_field, &rec1_f_len);
 
761
                rec2_b_ptr = rec_get_nth_field(rec2, offsets2,
 
762
                                               cur_field, &rec2_f_len);
 
763
 
 
764
                if (rec1_f_len == UNIV_SQL_NULL
 
765
                    || rec2_f_len == UNIV_SQL_NULL) {
 
766
 
 
767
                        if (rec1_f_len == rec2_f_len) {
 
768
 
 
769
                                goto next_field;
 
770
 
 
771
                        } else if (rec2_f_len == UNIV_SQL_NULL) {
 
772
 
 
773
                                /* We define the SQL null to be the
 
774
                                smallest possible value of a field
 
775
                                in the alphabetical order */
 
776
 
 
777
                                return(1);
 
778
                        } else {
 
779
                                return(-1);
 
780
                        }
 
781
                }
 
782
 
 
783
                if (mtype >= DATA_FLOAT
 
784
                    || (mtype == DATA_BLOB
 
785
                        && 0 == (prtype & DATA_BINARY_TYPE)
 
786
                        && dtype_get_charset_coll(prtype)
 
787
                        != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
 
788
                        int ret = cmp_whole_field(mtype, prtype,
 
789
                                                  rec1_b_ptr,
 
790
                                                  (unsigned) rec1_f_len,
 
791
                                                  rec2_b_ptr,
 
792
                                                  (unsigned) rec2_f_len);
 
793
                        if (ret) {
 
794
                                return(ret);
 
795
                        }
 
796
 
 
797
                        goto next_field;
 
798
                }
 
799
 
 
800
                /* Compare the fields */
 
801
                for (cur_bytes = 0;; cur_bytes++, rec1_b_ptr++, rec2_b_ptr++) {
 
802
                        if (rec2_f_len <= cur_bytes) {
 
803
 
 
804
                                if (rec1_f_len <= cur_bytes) {
 
805
 
 
806
                                        goto next_field;
 
807
                                }
 
808
 
 
809
                                rec2_byte = dtype_get_pad_char(mtype, prtype);
 
810
 
 
811
                                if (rec2_byte == ULINT_UNDEFINED) {
 
812
                                        return(1);
 
813
                                }
 
814
                        } else {
 
815
                                rec2_byte = *rec2_b_ptr;
 
816
                        }
 
817
 
 
818
                        if (rec1_f_len <= cur_bytes) {
 
819
                                rec1_byte = dtype_get_pad_char(mtype, prtype);
 
820
 
 
821
                                if (rec1_byte == ULINT_UNDEFINED) {
 
822
                                        return(-1);
 
823
                                }
 
824
                        } else {
 
825
                                rec1_byte = *rec1_b_ptr;
 
826
                        }
 
827
 
 
828
                        if (rec1_byte == rec2_byte) {
 
829
                                /* If the bytes are equal, they will remain
 
830
                                such even after the collation transformation
 
831
                                below */
 
832
 
 
833
                                continue;
 
834
                        }
 
835
 
 
836
                        if (mtype <= DATA_CHAR
 
837
                            || (mtype == DATA_BLOB
 
838
                                && !(prtype & DATA_BINARY_TYPE))) {
 
839
 
 
840
                                rec1_byte = cmp_collate(rec1_byte);
 
841
                                rec2_byte = cmp_collate(rec2_byte);
 
842
                        }
 
843
 
 
844
                        if (rec1_byte < rec2_byte) {
 
845
                                return(-1);
 
846
                        } else if (rec1_byte > rec2_byte) {
 
847
                                return(1);
 
848
                        }
 
849
                }
 
850
next_field:
 
851
                continue;
 
852
        }
 
853
 
 
854
        /* If we ran out of fields, rec1 was equal to rec2. */
 
855
        return(0);
 
856
}
 
857
#endif /* !UNIV_HOTBACKUP */
 
858
 
707
859
/*****************************************************************
708
860
This function is used to compare two physical records. Only the common
709
861
first fields are compared, and if an externally stored field is
710
862
encountered, then 0 is returned. */
711
 
 
 
863
UNIV_INTERN
712
864
int
713
865
cmp_rec_rec_with_match(
714
866
/*===================*/
715
867
                                /* out: 1, 0 , -1 if rec1 is greater, equal,
716
868
                                less, respectively, than rec2; only the common
717
869
                                first fields are compared */
718
 
        rec_t*          rec1,   /* in: physical record */
719
 
        rec_t*          rec2,   /* in: physical record */
 
870
        const rec_t*    rec1,   /* in: physical record */
 
871
        const rec_t*    rec2,   /* in: physical record */
720
872
        const ulint*    offsets1,/* in: rec_get_offsets(rec1, index) */
721
873
        const ulint*    offsets2,/* in: rec_get_offsets(rec2, index) */
722
874
        dict_index_t*   index,  /* in: data dictionary index */
730
882
                                the value for the current comparison */
731
883
{
732
884
#ifndef UNIV_HOTBACKUP
733
 
        ulint   rec1_n_fields;  /* the number of fields in rec */
734
 
        ulint   rec1_f_len;     /* length of current field in rec */
735
 
        byte*   rec1_b_ptr;     /* pointer to the current byte in rec field */
736
 
        ulint   rec1_byte;      /* value of current byte to be compared in
737
 
                                rec */
738
 
        ulint   rec2_n_fields;  /* the number of fields in rec */
739
 
        ulint   rec2_f_len;     /* length of current field in rec */
740
 
        byte*   rec2_b_ptr;     /* pointer to the current byte in rec field */
741
 
        ulint   rec2_byte;      /* value of current byte to be compared in
742
 
                                rec */
743
 
        ulint   cur_field;      /* current field number */
744
 
        ulint   cur_bytes;      /* number of already matched bytes in current
745
 
                                field */
746
 
        int     ret = 3333;     /* return value */
747
 
        ulint   comp;
 
885
        ulint           rec1_n_fields;  /* the number of fields in rec */
 
886
        ulint           rec1_f_len;     /* length of current field in rec */
 
887
        const byte*     rec1_b_ptr;     /* pointer to the current byte
 
888
                                        in rec field */
 
889
        ulint           rec1_byte;      /* value of current byte to be
 
890
                                        compared in rec */
 
891
        ulint           rec2_n_fields;  /* the number of fields in rec */
 
892
        ulint           rec2_f_len;     /* length of current field in rec */
 
893
        const byte*     rec2_b_ptr;     /* pointer to the current byte
 
894
                                        in rec field */
 
895
        ulint           rec2_byte;      /* value of current byte to be
 
896
                                        compared in rec */
 
897
        ulint           cur_field;      /* current field number */
 
898
        ulint           cur_bytes;      /* number of already matched
 
899
                                        bytes in current field */
 
900
        int             ret = 0;        /* return value */
 
901
        ulint           comp;
748
902
 
749
903
        ut_ad(rec1 && rec2 && index);
750
904
        ut_ad(rec_offs_validate(rec1, index, offsets1));
786
940
                        if (cur_field == 0) {
787
941
                                /* Test if rec is the predefined minimum
788
942
                                record */
789
 
                                if (rec_get_info_bits(rec1, comp)
790
 
                                    & REC_INFO_MIN_REC_FLAG) {
 
943
                                if (UNIV_UNLIKELY(rec_get_info_bits(rec1, comp)
 
944
                                                  & REC_INFO_MIN_REC_FLAG)) {
791
945
 
792
 
                                        if (rec_get_info_bits(rec2, comp)
793
 
                                            & REC_INFO_MIN_REC_FLAG) {
794
 
                                                ret = 0;
795
 
                                        } else {
 
946
                                        if (!(rec_get_info_bits(rec2, comp)
 
947
                                              & REC_INFO_MIN_REC_FLAG)) {
796
948
                                                ret = -1;
797
949
                                        }
798
950
 
799
951
                                        goto order_resolved;
800
952
 
801
 
                                } else if (rec_get_info_bits(rec2, comp)
802
 
                                           & REC_INFO_MIN_REC_FLAG) {
 
953
                                } else if (UNIV_UNLIKELY
 
954
                                           (rec_get_info_bits(rec2, comp)
 
955
                                            & REC_INFO_MIN_REC_FLAG)) {
803
956
 
804
957
                                        ret = 1;
805
958
 
812
965
                                /* We do not compare to an externally
813
966
                                stored field */
814
967
 
815
 
                                ret = 0;
816
 
 
817
968
                                goto order_resolved;
818
969
                        }
819
970
 
843
994
                    || (mtype == DATA_BLOB
844
995
                        && 0 == (prtype & DATA_BINARY_TYPE)
845
996
                        && dtype_get_charset_coll(prtype)
846
 
                        != DATA_DRIZZLE_LATIN1_SWEDISH_CHARSET_COLL)) {
 
997
                        != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
847
998
 
848
999
                        ret = cmp_whole_field(mtype, prtype,
849
1000
                                              rec1_b_ptr,
933
1084
 
934
1085
        ut_ad(cur_bytes == 0);
935
1086
 
936
 
        ret = 0;        /* If we ran out of fields, rec1 was equal to rec2 up
937
 
                        to the common fields */
 
1087
        /* If we ran out of fields, rec1 was equal to rec2 up
 
1088
        to the common fields */
 
1089
        ut_ad(ret == 0);
938
1090
order_resolved:
939
1091
 
940
1092
        ut_ad((ret >= - 1) && (ret <= 1));
966
1118
                                /* out: 1, 0, -1, if dtuple is greater, equal,
967
1119
                                less than rec, respectively, when only the
968
1120
                                common first fields are compared */
969
 
        dtuple_t*       dtuple, /* in: data tuple */
970
 
        rec_t*          rec,    /* in: physical record which differs from
 
1121
        const dtuple_t* dtuple, /* in: data tuple */
 
1122
        const rec_t*    rec,    /* in: physical record which differs from
971
1123
                                dtuple in some of the common fields, or which
972
1124
                                has an equal number or more fields than
973
1125
                                dtuple */
977
1129
                                returns, contains the value for current
978
1130
                                comparison */
979
1131
{
980
 
        dfield_t*       dtuple_field;   /* current field in logical record */
 
1132
        const dfield_t* dtuple_field;   /* current field in logical record */
981
1133
        ulint           dtuple_f_len;   /* the length of the current field
982
1134
                                        in the logical record */
983
 
        byte*           dtuple_f_data;  /* pointer to the current logical
 
1135
        const byte*     dtuple_f_data;  /* pointer to the current logical
984
1136
                                        field data */
985
1137
        ulint           rec_f_len;      /* length of current field in rec */
986
 
        byte*           rec_f_data;     /* pointer to the current rec field */
 
1138
        const byte*     rec_f_data;     /* pointer to the current rec field */
987
1139
        int             ret = 3333;     /* return value */
988
1140
        ulint           cur_field;      /* current field number */
989
1141
 
997
1149
        cur_field = *matched_fields;
998
1150
 
999
1151
        if (cur_field == 0) {
1000
 
                if (rec_get_info_bits(rec, rec_offs_comp(offsets))
1001
 
                    & REC_INFO_MIN_REC_FLAG) {
 
1152
                if (UNIV_UNLIKELY
 
1153
                    (rec_get_info_bits(rec, rec_offs_comp(offsets))
 
1154
                     & REC_INFO_MIN_REC_FLAG)) {
1002
1155
 
1003
1156
                        ret = !(dtuple_get_info_bits(dtuple)
1004
1157
                                & REC_INFO_MIN_REC_FLAG);
1006
1159
                        goto order_resolved;
1007
1160
                }
1008
1161
 
1009
 
                if (dtuple_get_info_bits(dtuple) & REC_INFO_MIN_REC_FLAG) {
 
1162
                if (UNIV_UNLIKELY
 
1163
                    (dtuple_get_info_bits(dtuple) & REC_INFO_MIN_REC_FLAG)) {
1010
1164
                        ret = -1;
1011
1165
 
1012
1166
                        goto order_resolved;