~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-01-08 22:38:15 UTC
  • Revision ID: brian@tangent.org-20090108223815-i7p6uaajqxapge8a
func_timestamp now working.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
4
 
 
5
 
This program is free software; you can redistribute it and/or modify it under
6
 
the terms of the GNU General Public License as published by the Free Software
7
 
Foundation; version 2 of the License.
8
 
 
9
 
This program is distributed in the hope that it will be useful, but WITHOUT
10
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
 
 
13
 
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/*******************************************************************//**
20
 
@file rem/rem0cmp.c
 
1
/***********************************************************************
21
2
Comparison services for records
22
3
 
 
4
(c) 1994-1996 Innobase Oy
 
5
 
23
6
Created 7/1/1994 Heikki Tuuri
24
7
************************************************************************/
25
8
 
51
34
has more fields than the other. */
52
35
 
53
36
#ifdef UNIV_DEBUG
54
 
/*************************************************************//**
 
37
/*****************************************************************
55
38
Used in debug checking of cmp_dtuple_... .
56
39
This function is used to compare a data tuple to a physical record. If
57
40
dtuple has n fields then rec must have either m >= n fields, or it must
58
 
differ from dtuple in some of the m fields rec has.
59
 
@return 1, 0, -1, if dtuple is greater, equal, less than rec,
60
 
respectively, when only the common first fields are compared */
 
41
differ from dtuple in some of the m fields rec has. */
61
42
static
62
43
int
63
44
cmp_debug_dtuple_rec_with_match(
64
45
/*============================*/
65
 
        const dtuple_t* dtuple, /*!< in: data tuple */
66
 
        const rec_t*    rec,    /*!< in: physical record which differs from
 
46
                                /* out: 1, 0, -1, if dtuple is greater, equal,
 
47
                                less than rec, respectively, when only the
 
48
                                common first fields are compared */
 
49
        const dtuple_t* dtuple, /* in: data tuple */
 
50
        const rec_t*    rec,    /* in: physical record which differs from
67
51
                                dtuple in some of the common fields, or which
68
52
                                has an equal number or more fields than
69
53
                                dtuple */
70
 
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
71
 
        ulint*          matched_fields);/*!< in/out: number of already
 
54
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
 
55
        ulint*          matched_fields);/* in/out: number of already
72
56
                                completely  matched fields; when function
73
57
                                returns, contains the value for current
74
58
                                comparison */
75
59
#endif /* UNIV_DEBUG */
76
 
/*************************************************************//**
 
60
#ifndef UNIV_HOTBACKUP
 
61
/*****************************************************************
77
62
This function is used to compare two data fields for which the data type
78
63
is such that we must use MySQL code to compare them. The prototype here
79
 
must be a copy of the the one in ha_innobase.cc!
80
 
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
 
64
must be a copy of the the one in ha_innobase.cc! */
81
65
extern
82
66
int
83
67
innobase_mysql_cmp(
84
68
/*===============*/
85
 
        int             mysql_type,     /*!< in: MySQL type */
86
 
        uint            charset_number, /*!< in: number of the charset */
87
 
        const unsigned char* a,         /*!< in: data field */
88
 
        unsigned int    a_length,       /*!< in: data field length,
89
 
                                        not UNIV_SQL_NULL */
90
 
        const unsigned char* b,         /*!< in: data field */
91
 
        unsigned int    b_length);      /*!< in: data field length,
92
 
                                        not UNIV_SQL_NULL */
93
 
/*********************************************************************//**
 
69
                                        /* out: 1, 0, -1, if a is greater,
 
70
                                        equal, less than b, respectively */
 
71
        int             mysql_type,     /* in: MySQL type */
 
72
        uint            charset_number, /* in: number of the charset */
 
73
        const unsigned char* a,         /* in: data field */
 
74
        unsigned int    a_length,       /* in: data field length,
 
75
                                        not UNIV_SQL_NULL */
 
76
        const unsigned char* b,         /* in: data field */
 
77
        unsigned int    b_length);      /* in: data field length,
 
78
                                        not UNIV_SQL_NULL */
 
79
#endif /* !UNIV_HOTBACKUP */
 
80
/*************************************************************************
94
81
Transforms the character code so that it is ordered appropriately for the
95
82
language. This is only used for the latin1 char set. MySQL does the
96
 
comparisons for other char sets.
97
 
@return collation order position */
 
83
comparisons for other char sets. */
98
84
UNIV_INLINE
99
85
ulint
100
86
cmp_collate(
101
87
/*========*/
102
 
        ulint   code)   /*!< in: code of a character stored in database record */
 
88
                        /* out: collation order position */
 
89
        ulint   code)   /* in: code of a character stored in database record */
103
90
{
104
91
        return((ulint) srv_latin1_ordering[code]);
105
92
}
106
93
 
107
 
/*************************************************************//**
108
 
Returns TRUE if two columns are equal for comparison purposes.
109
 
@return TRUE if the columns are considered equal in comparisons */
 
94
/*****************************************************************
 
95
Returns TRUE if two columns are equal for comparison purposes. */
110
96
UNIV_INTERN
111
97
ibool
112
98
cmp_cols_are_equal(
113
99
/*===============*/
114
 
        const dict_col_t*       col1,   /*!< in: column 1 */
115
 
        const dict_col_t*       col2,   /*!< in: column 2 */
 
100
                                        /* out: TRUE if the columns are
 
101
                                        considered equal in comparisons */
 
102
        const dict_col_t*       col1,   /* in: column 1 */
 
103
        const dict_col_t*       col2,   /* in: column 2 */
116
104
        ibool                   check_charsets)
117
 
                                        /*!< in: whether to check charsets */
 
105
                                        /* in: whether to check charsets */
118
106
{
119
107
        if (dtype_is_non_binary_string_type(col1->mtype, col1->prtype)
120
108
            && dtype_is_non_binary_string_type(col2->mtype, col2->prtype)) {
157
145
        return(col1->mtype != DATA_INT || col1->len == col2->len);
158
146
}
159
147
 
160
 
/*************************************************************//**
 
148
#ifndef UNIV_HOTBACKUP
 
149
/*****************************************************************
161
150
Innobase uses this function to compare two data fields for which the data type
162
 
is such that we must compare whole fields or call MySQL to do the comparison
163
 
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
 
151
is such that we must compare whole fields or call MySQL to do the comparison */
164
152
static
165
153
int
166
154
cmp_whole_field(
167
155
/*============*/
168
 
        ulint           mtype,          /*!< in: main type */
169
 
        ulint           prtype,         /*!< in: precise type */
170
 
        const byte*     a,              /*!< in: data field */
171
 
        unsigned int    a_length,       /*!< in: data field length,
 
156
                                        /* out: 1, 0, -1, if a is greater,
 
157
                                        equal, less than b, respectively */
 
158
        ulint           mtype,          /* in: main type */
 
159
        ulint           prtype,         /* in: precise type */
 
160
        const byte*     a,              /* in: data field */
 
161
        unsigned int    a_length,       /* in: data field length,
172
162
                                        not UNIV_SQL_NULL */
173
 
        const byte*     b,              /*!< in: data field */
174
 
        unsigned int    b_length)       /*!< in: data field length,
 
163
        const byte*     b,              /* in: data field */
 
164
        unsigned int    b_length)       /* in: data field length,
175
165
                                        not UNIV_SQL_NULL */
176
166
{
177
167
        float           f_1;
282
272
 
283
273
        return(0);
284
274
}
 
275
#endif /* !UNIV_HOTBACKUP */
285
276
 
286
 
/*************************************************************//**
 
277
/*****************************************************************
287
278
This function is used to compare two data fields for which we know the
288
 
data type.
289
 
@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
 
279
data type. */
290
280
UNIV_INTERN
291
281
int
292
282
cmp_data_data_slow(
293
283
/*===============*/
294
 
        ulint           mtype,  /*!< in: main type */
295
 
        ulint           prtype, /*!< in: precise type */
296
 
        const byte*     data1,  /*!< in: data field (== a pointer to a memory
297
 
                                buffer) */
298
 
        ulint           len1,   /*!< in: data field length or UNIV_SQL_NULL */
299
 
        const byte*     data2,  /*!< in: data field (== a pointer to a memory
300
 
                                buffer) */
301
 
        ulint           len2)   /*!< in: data field length or UNIV_SQL_NULL */
 
284
                                /* out: 1, 0, -1, if data1 is greater, equal,
 
285
                                less than data2, respectively */
 
286
        ulint           mtype,  /* in: main type */
 
287
        ulint           prtype, /* in: precise type */
 
288
        const byte*     data1,  /* in: data field (== a pointer to a memory
 
289
                                buffer) */
 
290
        ulint           len1,   /* in: data field length or UNIV_SQL_NULL */
 
291
        const byte*     data2,  /* in: data field (== a pointer to a memory
 
292
                                buffer) */
 
293
        ulint           len2)   /* in: data field length or UNIV_SQL_NULL */
302
294
{
 
295
#ifndef UNIV_HOTBACKUP
303
296
        ulint   data1_byte;
304
297
        ulint   data2_byte;
305
298
        ulint   cur_bytes;
392
385
                data1++;
393
386
                data2++;
394
387
        }
 
388
#else /* !UNIV_HOTBACKUP */
 
389
        /* This function depends on MySQL code that is not included in
 
390
        InnoDB Hot Backup builds.  Besides, this function should never
 
391
        be called in InnoDB Hot Backup. */
 
392
        ut_error;
 
393
#endif /* !UNIV_HOTBACKUP */
395
394
 
 
395
        return(0);              /* Not reached */
396
396
}
397
397
 
398
 
/*************************************************************//**
 
398
/*****************************************************************
399
399
This function is used to compare a data tuple to a physical record.
400
400
Only dtuple->n_fields_cmp first fields are taken into account for
401
401
the the data tuple! If we denote by n = n_fields_cmp, then rec must
402
402
have either m >= n fields, or it must differ from dtuple in some of
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
 
made.
406
 
@return 1, 0, -1, if dtuple is greater, equal, less than rec,
407
 
respectively, when only the common first fields are compared, or until
408
 
the first externally stored field in rec */
 
405
made. */
409
406
UNIV_INTERN
410
407
int
411
408
cmp_dtuple_rec_with_match(
412
409
/*======================*/
413
 
        const dtuple_t* dtuple, /*!< in: data tuple */
414
 
        const rec_t*    rec,    /*!< in: physical record which differs from
 
410
                                /* out: 1, 0, -1, if dtuple is greater, equal,
 
411
                                less than rec, respectively, when only the
 
412
                                common first fields are compared, or
 
413
                                until the first externally stored field in
 
414
                                rec */
 
415
        const dtuple_t* dtuple, /* in: data tuple */
 
416
        const rec_t*    rec,    /* in: physical record which differs from
415
417
                                dtuple in some of the common fields, or which
416
418
                                has an equal number or more fields than
417
419
                                dtuple */
418
 
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
419
 
        ulint*          matched_fields, /*!< in/out: number of already completely
 
420
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
 
421
        ulint*          matched_fields, /* in/out: number of already completely
420
422
                                matched fields; when function returns,
421
423
                                contains the value for current comparison */
422
 
        ulint*          matched_bytes) /*!< in/out: number of already matched
 
424
        ulint*          matched_bytes) /* in/out: number of already matched
423
425
                                bytes within the first field not completely
424
426
                                matched; when function returns, contains the
425
427
                                value for current comparison */
426
428
{
 
429
#ifndef UNIV_HOTBACKUP
427
430
        const dfield_t* dtuple_field;   /* current field in logical record */
428
431
        ulint           dtuple_f_len;   /* the length of the current field
429
432
                                        in the logical record */
631
634
        *matched_bytes = cur_bytes;
632
635
 
633
636
        return(ret);
 
637
#else /* !UNIV_HOTBACKUP */
 
638
        /* This function depends on MySQL code that is not included in
 
639
        InnoDB Hot Backup builds.  Besides, this function should never
 
640
        be called in InnoDB Hot Backup. */
 
641
        ut_error;
 
642
        return(0);
 
643
#endif /* !UNIV_HOTBACKUP */
634
644
}
635
645
 
636
 
/**************************************************************//**
637
 
Compares a data tuple to a physical record.
638
 
@see cmp_dtuple_rec_with_match
639
 
@return 1, 0, -1, if dtuple is greater, equal, less than rec, respectively */
 
646
/******************************************************************
 
647
Compares a data tuple to a physical record. */
640
648
UNIV_INTERN
641
649
int
642
650
cmp_dtuple_rec(
643
651
/*===========*/
644
 
        const dtuple_t* dtuple, /*!< in: data tuple */
645
 
        const rec_t*    rec,    /*!< in: physical record */
646
 
        const ulint*    offsets)/*!< in: array returned by rec_get_offsets() */
 
652
                                /* out: 1, 0, -1, if dtuple is greater, equal,
 
653
                                less than rec, respectively; see the comments
 
654
                                for cmp_dtuple_rec_with_match */
 
655
        const dtuple_t* dtuple, /* in: data tuple */
 
656
        const rec_t*    rec,    /* in: physical record */
 
657
        const ulint*    offsets)/* in: array returned by rec_get_offsets() */
647
658
{
648
659
        ulint   matched_fields  = 0;
649
660
        ulint   matched_bytes   = 0;
653
664
                                         &matched_fields, &matched_bytes));
654
665
}
655
666
 
656
 
/**************************************************************//**
 
667
/******************************************************************
657
668
Checks if a dtuple is a prefix of a record. The last field in dtuple
658
 
is allowed to be a prefix of the corresponding field in the record.
659
 
@return TRUE if prefix */
 
669
is allowed to be a prefix of the corresponding field in the record. */
660
670
UNIV_INTERN
661
671
ibool
662
672
cmp_dtuple_is_prefix_of_rec(
663
673
/*========================*/
664
 
        const dtuple_t* dtuple, /*!< in: data tuple */
665
 
        const rec_t*    rec,    /*!< in: physical record */
666
 
        const ulint*    offsets)/*!< in: array returned by rec_get_offsets() */
 
674
                                /* out: TRUE if prefix */
 
675
        const dtuple_t* dtuple, /* in: data tuple */
 
676
        const rec_t*    rec,    /* in: physical record */
 
677
        const ulint*    offsets)/* in: array returned by rec_get_offsets() */
667
678
{
668
679
        ulint   n_fields;
669
680
        ulint   matched_fields  = 0;
693
704
        return(FALSE);
694
705
}
695
706
 
696
 
/*************************************************************//**
 
707
#ifndef UNIV_HOTBACKUP
 
708
/*****************************************************************
697
709
Compare two physical records that contain the same number of columns,
698
 
none of which are stored externally.
699
 
@return 1, 0, -1 if rec1 is greater, equal, less, respectively, than rec2 */
 
710
none of which are stored externally. */
700
711
UNIV_INTERN
701
712
int
702
713
cmp_rec_rec_simple(
703
714
/*===============*/
704
 
        const rec_t*            rec1,   /*!< in: physical record */
705
 
        const rec_t*            rec2,   /*!< in: physical record */
706
 
        const ulint*            offsets1,/*!< in: rec_get_offsets(rec1, ...) */
707
 
        const ulint*            offsets2,/*!< in: rec_get_offsets(rec2, ...) */
708
 
        const dict_index_t*     index,  /*!< in: data dictionary index */
709
 
        ibool*                  null_eq)/*!< out: set to TRUE if
710
 
                                        found matching null values */
 
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 */
711
722
{
712
 
        ulint           rec1_f_len;     /*!< length of current field in rec1 */
713
 
        const byte*     rec1_b_ptr;     /*!< pointer to the current byte
 
723
        ulint           rec1_f_len;     /* length of current field in rec1 */
 
724
        const byte*     rec1_b_ptr;     /* pointer to the current byte
714
725
                                        in rec1 field */
715
 
        ulint           rec1_byte;      /*!< value of current byte to be
 
726
        ulint           rec1_byte;      /* value of current byte to be
716
727
                                        compared in rec1 */
717
 
        ulint           rec2_f_len;     /*!< length of current field in rec2 */
718
 
        const byte*     rec2_b_ptr;     /*!< pointer to the current byte
 
728
        ulint           rec2_f_len;     /* length of current field in rec2 */
 
729
        const byte*     rec2_b_ptr;     /* pointer to the current byte
719
730
                                        in rec2 field */
720
 
        ulint           rec2_byte;      /*!< value of current byte to be
 
731
        ulint           rec2_byte;      /* value of current byte to be
721
732
                                        compared in rec2 */
722
 
        ulint           cur_field;      /*!< current field number */
 
733
        ulint           cur_field;      /* current field number */
723
734
        ulint           n_uniq;
724
735
 
725
736
        n_uniq = dict_index_get_n_unique(index);
754
765
                    || rec2_f_len == UNIV_SQL_NULL) {
755
766
 
756
767
                        if (rec1_f_len == rec2_f_len) {
757
 
                                if (null_eq) {
758
 
                                        *null_eq = TRUE;
759
 
                                }
760
768
 
761
769
                                goto next_field;
762
770
 
846
854
        /* If we ran out of fields, rec1 was equal to rec2. */
847
855
        return(0);
848
856
}
 
857
#endif /* !UNIV_HOTBACKUP */
849
858
 
850
 
/*************************************************************//**
 
859
/*****************************************************************
851
860
This function is used to compare two physical records. Only the common
852
861
first fields are compared, and if an externally stored field is
853
 
encountered, then 0 is returned.
854
 
@return 1, 0, -1 if rec1 is greater, equal, less, respectively */
 
862
encountered, then 0 is returned. */
855
863
UNIV_INTERN
856
864
int
857
865
cmp_rec_rec_with_match(
858
866
/*===================*/
859
 
        const rec_t*    rec1,   /*!< in: physical record */
860
 
        const rec_t*    rec2,   /*!< in: physical record */
861
 
        const ulint*    offsets1,/*!< in: rec_get_offsets(rec1, index) */
862
 
        const ulint*    offsets2,/*!< in: rec_get_offsets(rec2, index) */
863
 
        dict_index_t*   index,  /*!< in: data dictionary index */
864
 
        ulint*          matched_fields, /*!< in/out: number of already completely
 
867
                                /* out: 1, 0 , -1 if rec1 is greater, equal,
 
868
                                less, respectively, than rec2; only the common
 
869
                                first fields are compared */
 
870
        const rec_t*    rec1,   /* in: physical record */
 
871
        const rec_t*    rec2,   /* in: physical record */
 
872
        const ulint*    offsets1,/* in: rec_get_offsets(rec1, index) */
 
873
        const ulint*    offsets2,/* in: rec_get_offsets(rec2, index) */
 
874
        dict_index_t*   index,  /* in: data dictionary index */
 
875
        ulint*          matched_fields, /* in/out: number of already completely
865
876
                                matched fields; when the function returns,
866
877
                                contains the value the for current
867
878
                                comparison */
868
 
        ulint*          matched_bytes) /*!< in/out: number of already matched
 
879
        ulint*          matched_bytes) /* in/out: number of already matched
869
880
                                bytes within the first field not completely
870
881
                                matched; when the function returns, contains
871
882
                                the value for the current comparison */
872
883
{
 
884
#ifndef UNIV_HOTBACKUP
873
885
        ulint           rec1_n_fields;  /* the number of fields in rec */
874
886
        ulint           rec1_f_len;     /* length of current field in rec */
875
887
        const byte*     rec1_b_ptr;     /* pointer to the current byte
1083
1095
        *matched_bytes = cur_bytes;
1084
1096
 
1085
1097
        return(ret);
 
1098
#else /* !UNIV_HOTBACKUP */
 
1099
        /* This function depends on MySQL code that is not included in
 
1100
        InnoDB Hot Backup builds.  Besides, this function should never
 
1101
        be called in InnoDB Hot Backup. */
 
1102
        ut_error;
 
1103
        return(0);
 
1104
#endif /* !UNIV_HOTBACKUP */
1086
1105
}
1087
1106
 
1088
1107
#ifdef UNIV_DEBUG
1089
 
/*************************************************************//**
 
1108
/*****************************************************************
1090
1109
Used in debug checking of cmp_dtuple_... .
1091
1110
This function is used to compare a data tuple to a physical record. If
1092
1111
dtuple has n fields then rec must have either m >= n fields, or it must
1093
1112
differ from dtuple in some of the m fields rec has. If encounters an
1094
 
externally stored field, returns 0.
1095
 
@return 1, 0, -1, if dtuple is greater, equal, less than rec,
1096
 
respectively, when only the common first fields are compared */
 
1113
externally stored field, returns 0. */
1097
1114
static
1098
1115
int
1099
1116
cmp_debug_dtuple_rec_with_match(
1100
1117
/*============================*/
1101
 
        const dtuple_t* dtuple, /*!< in: data tuple */
1102
 
        const rec_t*    rec,    /*!< in: physical record which differs from
 
1118
                                /* out: 1, 0, -1, if dtuple is greater, equal,
 
1119
                                less than rec, respectively, when only the
 
1120
                                common first fields are compared */
 
1121
        const dtuple_t* dtuple, /* in: data tuple */
 
1122
        const rec_t*    rec,    /* in: physical record which differs from
1103
1123
                                dtuple in some of the common fields, or which
1104
1124
                                has an equal number or more fields than
1105
1125
                                dtuple */
1106
 
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
1107
 
        ulint*          matched_fields) /*!< in/out: number of already
 
1126
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
 
1127
        ulint*          matched_fields) /* in/out: number of already
1108
1128
                                completely matched fields; when function
1109
1129
                                returns, contains the value for current
1110
1130
                                comparison */