diff options
Diffstat (limited to 'storage/innobase/include/rem0cmp.h')
-rw-r--r-- | storage/innobase/include/rem0cmp.h | 185 |
1 files changed, 104 insertions, 81 deletions
diff --git a/storage/innobase/include/rem0cmp.h b/storage/innobase/include/rem0cmp.h index 6f2201971d1..3a30f5a92f3 100644 --- a/storage/innobase/include/rem0cmp.h +++ b/storage/innobase/include/rem0cmp.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -24,8 +24,7 @@ Comparison services for records Created 7/1/1994 Heikki Tuuri ************************************************************************/ -#ifndef rem0cmp_h -#define rem0cmp_h +#pragma once #include "data0data.h" #include "data0type.h" @@ -43,39 +42,40 @@ cmp_cols_are_equal( ibool check_charsets); /*!< in: whether to check charsets */ /** Compare two data fields. -@param[in] mtype main type -@param[in] prtype precise type -@param[in] data1 data field -@param[in] len1 length of data1 in bytes, or UNIV_SQL_NULL -@param[in] data2 data field -@param[in] len2 length of data2 in bytes, or UNIV_SQL_NULL +@param mtype main type +@param prtype precise type +@param descending whether to use descending order +@param data1 data field +@param len1 length of data1 in bytes, or UNIV_SQL_NULL +@param data2 data field +@param len2 length of data2 in bytes, or UNIV_SQL_NULL @return the comparison result of data1 and data2 @retval 0 if data1 is equal to data2 @retval negative if data1 is less than data2 @retval positive if data1 is greater than data2 */ -int -cmp_data_data( - ulint mtype, - ulint prtype, - const byte* data1, - ulint len1, - const byte* data2, - ulint len2) - MY_ATTRIBUTE((warn_unused_result)); +int cmp_data(ulint mtype, ulint prtype, bool descending, + const byte *data1, size_t len1, const byte *data2, size_t len2) + MY_ATTRIBUTE((warn_unused_result)); /** Compare two data fields. -@param[in] dfield1 data field; must have type field set -@param[in] dfield2 data field +@param dfield1 data field; must have type field set +@param dfield2 data field +@param descending whether to use descending order @return the comparison result of dfield1 and dfield2 @retval 0 if dfield1 is equal to dfield2 @retval negative if dfield1 is less than dfield2 @retval positive if dfield1 is greater than dfield2 */ -UNIV_INLINE -int -cmp_dfield_dfield( -/*==============*/ - const dfield_t* dfield1,/*!< in: data field; must have type field set */ - const dfield_t* dfield2);/*!< in: data field */ +inline int cmp_dfield_dfield(const dfield_t *dfield1, const dfield_t *dfield2, + bool descending= false) +{ + ut_ad(dfield_check_typed(dfield1)); + const dtype_t *type= dfield_get_type(dfield1); + return cmp_data(type->mtype, type->prtype, descending, + static_cast<const byte*>(dfield_get_data(dfield1)), + dfield_get_len(dfield1), + static_cast<const byte*>(dfield_get_data(dfield2)), + dfield_get_len(dfield2)); +} #ifdef UNIV_DEBUG /** Compare a GIS data tuple to a physical record. @@ -103,15 +103,15 @@ inline int cmp_geometry_field(const void *a, const void *b) double x2= mach_double_read(mbr2); if (x1 > x2) return 1; - if (x2 > x1) + if (x1 < x2) return -1; - double y1= mach_double_read(mbr1 + sizeof(double) * SPDIMS); - double y2= mach_double_read(mbr2 + sizeof(double) * SPDIMS); + x1= mach_double_read(mbr1 + sizeof(double) * SPDIMS); + x2= mach_double_read(mbr2 + sizeof(double) * SPDIMS); - if (y1 > y2) + if (x1 > x2) return 1; - if (y2 > y1) + if (x1 < x2) return -1; /* left lower corner (xmin, ymin) overlaps, now right upper corner */ @@ -120,41 +120,39 @@ inline int cmp_geometry_field(const void *a, const void *b) if (x1 > x2) return 1; - if (x2 > x1) + if (x1 < x2) return -1; - y1= mach_double_read(mbr1 + sizeof(double) * 2 + sizeof(double)); - y2= mach_double_read(mbr2 + sizeof(double) * 2 + sizeof(double)); + x1= mach_double_read(mbr1 + sizeof(double) * 2 + sizeof(double)); + x2= mach_double_read(mbr2 + sizeof(double) * 2 + sizeof(double)); - if (y1 > y2) + if (x1 > x2) return 1; - if (y2 > y1) + if (x1 < x2) return -1; return 0; } /** Compare a data tuple to a physical record. -@param[in] dtuple data tuple -@param[in] rec B-tree record -@param[in] offsets rec_get_offsets(rec) -@param[in] n_cmp number of fields to compare -@param[in,out] matched_fields number of completely matched fields +@param dtuple data tuple +@param rec B-tree index record +@param index B-tree index +@param offsets rec_get_offsets(rec,index) +@param n_cmp number of fields to compare +@param matched_fields number of completely matched fields @return the comparison result of dtuple and rec @retval 0 if dtuple is equal to rec @retval negative if dtuple is less than rec @retval positive if dtuple is greater than rec */ -int -cmp_dtuple_rec_with_match_low( - const dtuple_t* dtuple, - const rec_t* rec, - const rec_offs* offsets, - ulint n_cmp, - ulint* matched_fields) - MY_ATTRIBUTE((nonnull)); -#define cmp_dtuple_rec_with_match(tuple,rec,offsets,fields) \ +int cmp_dtuple_rec_with_match_low(const dtuple_t *dtuple, const rec_t *rec, + const dict_index_t *index, + const rec_offs *offsets, + ulint n_cmp, ulint *matched_fields) + MY_ATTRIBUTE((nonnull)); +#define cmp_dtuple_rec_with_match(tuple,rec,index,offsets,fields) \ cmp_dtuple_rec_with_match_low( \ - tuple,rec,offsets,dtuple_get_n_fields_cmp(tuple),fields) + tuple,rec,index,offsets,dtuple_get_n_fields_cmp(tuple),fields) /** Compare a data tuple to a physical record. @param[in] dtuple data tuple @param[in] rec B-tree or R-tree index record @@ -178,28 +176,32 @@ cmp_dtuple_rec_with_match_bytes( MY_ATTRIBUTE((warn_unused_result)); /** Compare a data tuple to a physical record. @see cmp_dtuple_rec_with_match -@param[in] dtuple data tuple -@param[in] rec B-tree record -@param[in] offsets rec_get_offsets(rec) +@param dtuple data tuple +@param rec index record +@param index index +@param offsets rec_get_offsets(rec, index) @return the comparison result of dtuple and rec @retval 0 if dtuple is equal to rec @retval negative if dtuple is less than rec @retval positive if dtuple is greater than rec */ -int -cmp_dtuple_rec( - const dtuple_t* dtuple, - const rec_t* rec, - const rec_offs* offsets); -/**************************************************************//** -Checks if a dtuple is a prefix of a record. The last field in dtuple -is allowed to be a prefix of the corresponding field in the record. -@return TRUE if prefix */ -ibool -cmp_dtuple_is_prefix_of_rec( -/*========================*/ - const dtuple_t* dtuple, /*!< in: data tuple */ - const rec_t* rec, /*!< in: physical record */ - const rec_offs* offsets);/*!< in: array returned by rec_get_offsets() */ +inline int cmp_dtuple_rec(const dtuple_t *dtuple, const rec_t *rec, + const dict_index_t *index, const rec_offs *offsets) +{ + ulint matched= 0; + return cmp_dtuple_rec_with_match(dtuple, rec, index, offsets, &matched); +} + +/** Check if a dtuple is a prefix of a record. +@param dtuple data tuple +@param rec index record +@param index index +@param offsets rec_get_offsets(rec) +@return whether dtuple is a prefix of rec */ +bool cmp_dtuple_is_prefix_of_rec(const dtuple_t *dtuple, const rec_t *rec, + const dict_index_t *index, + const rec_offs *offsets) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + /** Compare two physical records that contain the same number of columns, none of which are stored externally. @retval positive if rec1 (including non-ordering columns) is greater than rec2 @@ -246,18 +248,39 @@ cmp_rec_rec( MY_ATTRIBUTE((nonnull(1,2,3,4,5))); /** Compare two data fields. -@param[in] dfield1 data field -@param[in] dfield2 data field +@param dfield1 data field +@param dfield2 data field @return the comparison result of dfield1 and dfield2 -@retval 0 if dfield1 is equal to dfield2, or a prefix of dfield1 -@retval negative if dfield1 is less than dfield2 -@retval positive if dfield1 is greater than dfield2 */ -UNIV_INLINE -int -cmp_dfield_dfield_like_prefix( - const dfield_t* dfield1, - const dfield_t* dfield2); +@retval true if dfield1 is equal to dfield2, or a prefix of dfield1 +@retval false otherwise */ +inline bool cmp_dfield_dfield_eq_prefix(const dfield_t *dfield1, + const dfield_t *dfield2) +{ + ut_ad(dfield_check_typed(dfield1)); + ut_ad(dfield_check_typed(dfield2)); + const dtype_t *type= dfield_get_type(dfield1); -#include "rem0cmp.inl" +#ifdef UNIV_DEBUG + switch (type->prtype & DATA_MYSQL_TYPE_MASK) { + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_VARCHAR: + break; + default: + ut_error; + } +#endif /* UNIV_DEBUG */ -#endif + uint cs_num= dtype_get_charset_coll(type->prtype); + CHARSET_INFO *cs= get_charset(cs_num, MYF(MY_WME)); + ut_a(cs); + return !cs->strnncoll(static_cast<const uchar*>(dfield_get_data(dfield1)), + dfield_get_len(dfield1), + static_cast<const uchar*>(dfield_get_data(dfield2)), + dfield_get_len(dfield2), 1); +} |