1
/*****************************************************************************
3
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
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.
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.
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
17
*****************************************************************************/
19
/*******************************************************************//**
1
/***********************************************************************
21
2
Comparison services for records
4
(c) 1994-1996 Innobase Oy
23
6
Created 7/1/1994 Heikki Tuuri
24
7
************************************************************************/
51
34
has more fields than the other. */
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. */
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
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
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! */
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,
90
const unsigned char* b, /*!< in: data field */
91
unsigned int b_length); /*!< in: data field length,
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,
76
const unsigned char* b, /* in: data field */
77
unsigned int b_length); /* in: data field length,
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. */
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 */
104
91
return((ulint) srv_latin1_ordering[code]);
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. */
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 */
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);
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 */
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 */
275
#endif /* !UNIV_HOTBACKUP */
286
/*************************************************************//**
277
/*****************************************************************
287
278
This function is used to compare two data fields for which we know the
289
@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
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
298
ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
299
const byte* data2, /*!< in: data field (== a pointer to a memory
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
290
ulint len1, /* in: data field length or UNIV_SQL_NULL */
291
const byte* data2, /* in: data field (== a pointer to a memory
293
ulint len2) /* in: data field length or UNIV_SQL_NULL */
295
#ifndef UNIV_HOTBACKUP
303
296
ulint data1_byte;
304
297
ulint data2_byte;
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. */
393
#endif /* !UNIV_HOTBACKUP */
395
return(0); /* Not reached */
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
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 */
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
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
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 */
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;
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. */
643
#endif /* !UNIV_HOTBACKUP */
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. */
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() */
648
659
ulint matched_fields = 0;
649
660
ulint matched_bytes = 0;
653
664
&matched_fields, &matched_bytes));
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. */
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() */
669
680
ulint matched_fields = 0;
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. */
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 */
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
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
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 */
725
736
n_uniq = dict_index_get_n_unique(index);
846
854
/* If we ran out of fields, rec1 was equal to rec2. */
857
#endif /* !UNIV_HOTBACKUP */
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. */
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
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 */
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;
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. */
1104
#endif /* !UNIV_HOTBACKUP */
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. */
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
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