summaryrefslogtreecommitdiff
path: root/storage/innobase/include/rem0cmp.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/rem0cmp.h')
-rw-r--r--storage/innobase/include/rem0cmp.h185
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);
+}