| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 1994, 2014, Oracle and/or its affiliates. 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., |
| 15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
| 16 | |
| 17 | *****************************************************************************/ |
| 18 | |
| 19 | /*******************************************************************//** |
| 20 | @file include/rem0cmp.ic |
| 21 | Comparison services for records |
| 22 | |
| 23 | Created 7/1/1994 Heikki Tuuri |
| 24 | ************************************************************************/ |
| 25 | |
| 26 | #include <mysql_com.h> |
| 27 | |
| 28 | /** Compare two data fields. |
| 29 | @param[in] dfield1 data field; must have type field set |
| 30 | @param[in] dfield2 data field |
| 31 | @return the comparison result of dfield1 and dfield2 |
| 32 | @retval 0 if dfield1 is equal to dfield2 |
| 33 | @retval negative if dfield1 is less than dfield2 |
| 34 | @retval positive if dfield1 is greater than dfield2 */ |
| 35 | UNIV_INLINE |
| 36 | int |
| 37 | cmp_dfield_dfield( |
| 38 | const dfield_t* dfield1, |
| 39 | const dfield_t* dfield2) |
| 40 | { |
| 41 | const dtype_t* type; |
| 42 | |
| 43 | ut_ad(dfield_check_typed(dfield1)); |
| 44 | |
| 45 | type = dfield_get_type(dfield1); |
| 46 | |
| 47 | return(cmp_data_data(type->mtype, type->prtype, |
| 48 | (const byte*) dfield_get_data(dfield1), |
| 49 | dfield_get_len(dfield1), |
| 50 | (const byte*) dfield_get_data(dfield2), |
| 51 | dfield_get_len(dfield2))); |
| 52 | } |
| 53 | |
| 54 | /** Compare two B-tree records. |
| 55 | Only the common first fields are compared, and externally stored field |
| 56 | are treated as equal. |
| 57 | @param[in] rec1 B-tree record |
| 58 | @param[in] rec2 B-tree record |
| 59 | @param[in] offsets1 rec_get_offsets(rec1, index) |
| 60 | @param[in] offsets2 rec_get_offsets(rec2, index) |
| 61 | @param[out] matched_fields number of completely matched fields |
| 62 | within the first field not completely matched |
| 63 | @return positive, 0, negative if rec1 is greater, equal, less, than rec2, |
| 64 | respectively */ |
| 65 | UNIV_INLINE |
| 66 | int |
| 67 | cmp_rec_rec( |
| 68 | const rec_t* rec1, |
| 69 | const rec_t* rec2, |
| 70 | const ulint* offsets1, |
| 71 | const ulint* offsets2, |
| 72 | const dict_index_t* index, |
| 73 | ulint* matched_fields) |
| 74 | { |
| 75 | ulint match_f; |
| 76 | int ret; |
| 77 | |
| 78 | ret = cmp_rec_rec_with_match( |
| 79 | rec1, rec2, offsets1, offsets2, index, false, &match_f); |
| 80 | |
| 81 | if (matched_fields != NULL) { |
| 82 | *matched_fields = match_f; |
| 83 | } |
| 84 | |
| 85 | return(ret); |
| 86 | } |
| 87 | |
| 88 | /** Compare two data fields. |
| 89 | @param[in] dfield1 data field |
| 90 | @param[in] dfield2 data field |
| 91 | @return the comparison result of dfield1 and dfield2 |
| 92 | @retval 0 if dfield1 is equal to dfield2, or a prefix of dfield1 |
| 93 | @retval negative if dfield1 is less than dfield2 |
| 94 | @retval positive if dfield1 is greater than dfield2 */ |
| 95 | UNIV_INLINE |
| 96 | int |
| 97 | cmp_dfield_dfield_like_prefix( |
| 98 | const dfield_t* dfield1, |
| 99 | const dfield_t* dfield2) |
| 100 | { |
| 101 | const dtype_t* type; |
| 102 | |
| 103 | ut_ad(dfield_check_typed(dfield1)); |
| 104 | ut_ad(dfield_check_typed(dfield2)); |
| 105 | |
| 106 | type = dfield_get_type(dfield1); |
| 107 | |
| 108 | #ifdef UNIV_DEBUG |
| 109 | switch (type->prtype & DATA_MYSQL_TYPE_MASK) { |
| 110 | case MYSQL_TYPE_BIT: |
| 111 | case MYSQL_TYPE_STRING: |
| 112 | case MYSQL_TYPE_VAR_STRING: |
| 113 | case MYSQL_TYPE_TINY_BLOB: |
| 114 | case MYSQL_TYPE_MEDIUM_BLOB: |
| 115 | case MYSQL_TYPE_BLOB: |
| 116 | case MYSQL_TYPE_LONG_BLOB: |
| 117 | case MYSQL_TYPE_VARCHAR: |
| 118 | break; |
| 119 | default: |
| 120 | ut_error; |
| 121 | } |
| 122 | #endif /* UNIV_DEBUG */ |
| 123 | |
| 124 | uint cs_num = (uint) dtype_get_charset_coll(type->prtype); |
| 125 | |
| 126 | if (CHARSET_INFO* cs = get_charset(cs_num, MYF(MY_WME))) { |
| 127 | return(cs->coll->strnncoll( |
| 128 | cs, |
| 129 | static_cast<uchar*>( |
| 130 | dfield_get_data(dfield1)), |
| 131 | dfield_get_len(dfield1), |
| 132 | static_cast<uchar*>( |
| 133 | dfield_get_data(dfield2)), |
| 134 | dfield_get_len(dfield2), |
| 135 | 1)); |
| 136 | } |
| 137 | |
| 138 | ib::fatal() << "Unable to find charset-collation " << cs_num; |
| 139 | return(0); |
| 140 | } |
| 141 | |