summaryrefslogtreecommitdiff
path: root/storage/innobase/include/rem0rec.ic
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2016-08-12 11:17:45 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2016-09-02 13:22:28 +0300
commit2e814d4702d71a04388386a9f591d14a35980bfe (patch)
treef3f9b48d116a3738c5e71f3a360ca61f16cfb632 /storage/innobase/include/rem0rec.ic
parent848d211c5c4df00b819cd84d7530cf7d29bb0524 (diff)
downloadmariadb-git-2e814d4702d71a04388386a9f591d14a35980bfe.tar.gz
Merge InnoDB 5.7 from mysql-5.7.9.
Contains also MDEV-10547: Test multi_update_innodb fails with InnoDB 5.7 The failure happened because 5.7 has changed the signature of the bool handler::primary_key_is_clustered() const virtual function ("const" was added). InnoDB was using the old signature which caused the function not to be used. MDEV-10550: Parallel replication lock waits/deadlock handling does not work with InnoDB 5.7 Fixed mutexing problem on lock_trx_handle_wait. Note that rpl_parallel and rpl_optimistic_parallel tests still fail. MDEV-10156 : Group commit tests fail on 10.2 InnoDB (branch bb-10.2-jan) Reason: incorrect merge MDEV-10550: Parallel replication can't sync with master in InnoDB 5.7 (branch bb-10.2-jan) Reason: incorrect merge
Diffstat (limited to 'storage/innobase/include/rem0rec.ic')
-rw-r--r--storage/innobase/include/rem0rec.ic191
1 files changed, 118 insertions, 73 deletions
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 5811a77a48b..4d2cbcb4944 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -26,6 +26,7 @@ Created 5/30/1994 Heikki Tuuri
#include "mach0data.h"
#include "ut0byte.h"
#include "dict0dict.h"
+#include "dict0boot.h"
#include "btr0types.h"
/* Compact flag ORed to the extra size returned by rec_get_offsets() */
@@ -136,7 +137,6 @@ and the shift needed to obtain each bit-field of the record. */
/***********************************************************//**
Sets the value of the ith field SQL null bit of an old-style record. */
-UNIV_INTERN
void
rec_set_nth_field_null_bit(
/*=======================*/
@@ -146,7 +146,6 @@ rec_set_nth_field_null_bit(
/***********************************************************//**
Sets an old-style record field to SQL null.
The physical size of the field is not changed. */
-UNIV_INTERN
void
rec_set_nth_field_sql_null(
/*=======================*/
@@ -238,7 +237,7 @@ rec_set_bit_field_2(
/******************************************************//**
The following function is used to get the pointer of the next chained record
on the same page.
-@return pointer to the next chained record, or NULL if none */
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
const rec_t*
rec_get_next_ptr_const(
@@ -294,7 +293,7 @@ rec_get_next_ptr_const(
/******************************************************//**
The following function is used to get the pointer of the next chained record
on the same page.
-@return pointer to the next chained record, or NULL if none */
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
rec_t*
rec_get_next_ptr(
@@ -308,7 +307,7 @@ rec_get_next_ptr(
/******************************************************//**
The following function is used to get the offset of the next chained record
on the same page.
-@return the page offset of the next chained record, or 0 if none */
+@return the page offset of the next chained record, or 0 if none */
UNIV_INLINE
ulint
rec_get_next_offs(
@@ -418,7 +417,7 @@ rec_set_next_offs_new(
/******************************************************//**
The following function is used to get the number of fields
in an old-style record.
-@return number of data fields */
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields_old(
@@ -458,7 +457,7 @@ rec_set_n_fields_old(
/******************************************************//**
The following function retrieves the status bits of a new-style record.
-@return status bits */
+@return status bits */
UNIV_INLINE
ulint
rec_get_status(
@@ -479,7 +478,7 @@ rec_get_status(
/******************************************************//**
The following function is used to get the number of fields
in a record.
-@return number of data fields */
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields(
@@ -508,10 +507,32 @@ rec_get_n_fields(
}
}
+/** Confirms the n_fields of the entry is sane with comparing the other
+record in the same page specified
+@param[in] index index
+@param[in] rec record of the same page
+@param[in] entry index entry
+@return true if n_fields is sane */
+UNIV_INLINE
+bool
+rec_n_fields_is_sane(
+ dict_index_t* index,
+ const rec_t* rec,
+ const dtuple_t* entry)
+{
+ return(rec_get_n_fields(rec, index)
+ == dtuple_get_n_fields(entry)
+ /* a record for older SYS_INDEXES table
+ (missing merge_threshold column) is acceptable. */
+ || (index->table->id == DICT_INDEXES_ID
+ && rec_get_n_fields(rec, index)
+ == dtuple_get_n_fields(entry) - 1));
+}
+
/******************************************************//**
The following function is used to get the number of records owned by the
previous directory record.
-@return number of owned records */
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_old(
@@ -538,7 +559,7 @@ rec_set_n_owned_old(
/******************************************************//**
The following function is used to get the number of records owned by the
previous directory record.
-@return number of owned records */
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_new(
@@ -566,9 +587,22 @@ rec_set_n_owned_new(
}
}
+#ifdef UNIV_DEBUG
+/** Check if the info bits are valid.
+@param[in] bits info bits to check
+@return true if valid */
+inline
+bool
+rec_info_bits_valid(
+ ulint bits)
+{
+ return(0 == (bits & ~(REC_INFO_DELETED_FLAG | REC_INFO_MIN_REC_FLAG)));
+}
+#endif /* UNIV_DEBUG */
+
/******************************************************//**
The following function is used to retrieve the info bits of a record.
-@return info bits */
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_bits(
@@ -576,9 +610,11 @@ rec_get_info_bits(
const rec_t* rec, /*!< in: physical record */
ulint comp) /*!< in: nonzero=compact page format */
{
- return(rec_get_bit_field_1(
- rec, comp ? REC_NEW_INFO_BITS : REC_OLD_INFO_BITS,
- REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT));
+ const ulint val = rec_get_bit_field_1(
+ rec, comp ? REC_NEW_INFO_BITS : REC_OLD_INFO_BITS,
+ REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
+ ut_ad(rec_info_bits_valid(val));
+ return(val);
}
/******************************************************//**
@@ -590,6 +626,7 @@ rec_set_info_bits_old(
rec_t* rec, /*!< in: old-style physical record */
ulint bits) /*!< in: info bits */
{
+ ut_ad(rec_info_bits_valid(bits));
rec_set_bit_field_1(rec, bits, REC_OLD_INFO_BITS,
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
}
@@ -602,6 +639,7 @@ rec_set_info_bits_new(
rec_t* rec, /*!< in/out: new-style physical record */
ulint bits) /*!< in: info bits */
{
+ ut_ad(rec_info_bits_valid(bits));
rec_set_bit_field_1(rec, bits, REC_NEW_INFO_BITS,
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
}
@@ -622,7 +660,7 @@ rec_set_status(
/******************************************************//**
The following function is used to retrieve the info and status
bits of a record. (Only compact records have status bits.)
-@return info bits */
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_and_status_bits(
@@ -663,7 +701,7 @@ rec_set_info_and_status_bits(
/******************************************************//**
The following function tells if record is delete marked.
-@return nonzero if delete marked */
+@return nonzero if delete marked */
UNIV_INLINE
ulint
rec_get_deleted_flag(
@@ -733,7 +771,7 @@ rec_set_deleted_flag_new(
/******************************************************//**
The following function tells if a new-style record is a node pointer.
-@return TRUE if node pointer */
+@return TRUE if node pointer */
UNIV_INLINE
ibool
rec_get_node_ptr_flag(
@@ -746,7 +784,7 @@ rec_get_node_ptr_flag(
/******************************************************//**
The following function is used to get the order number
of an old-style record in the heap of the index page.
-@return heap order number */
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_old(
@@ -774,7 +812,7 @@ rec_set_heap_no_old(
/******************************************************//**
The following function is used to get the order number
of a new-style record in the heap of the index page.
-@return heap order number */
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_new(
@@ -802,7 +840,7 @@ rec_set_heap_no_new(
/******************************************************//**
The following function is used to test whether the data offsets in the record
are stored in one-byte or two-byte format.
-@return TRUE if 1-byte form */
+@return TRUE if 1-byte form */
UNIV_INLINE
ibool
rec_get_1byte_offs_flag(
@@ -839,7 +877,7 @@ rec_set_1byte_offs_flag(
Returns the offset of nth field end if the record is stored in the 1-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
value.
-@return offset of the start of the field, SQL null flag ORed */
+@return offset of the start of the field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_1_get_field_end_info(
@@ -894,7 +932,7 @@ the fields. */
/**********************************************************//**
The following function returns the number of allocated elements
for an array of offsets.
-@return number of elements */
+@return number of elements */
UNIV_INLINE
ulint
rec_offs_get_n_alloc(
@@ -928,7 +966,7 @@ rec_offs_set_n_alloc(
/**********************************************************//**
The following function returns the number of fields in a record.
-@return number of fields */
+@return number of fields */
UNIV_INLINE
ulint
rec_offs_n_fields(
@@ -947,7 +985,7 @@ rec_offs_n_fields(
/************************************************************//**
Validates offsets returned by rec_get_offsets().
-@return TRUE if valid */
+@return TRUE if valid */
UNIV_INLINE
ibool
rec_offs_validate(
@@ -1025,7 +1063,7 @@ rec_offs_make_valid(
/************************************************************//**
The following function is used to get an offset to the nth
data field in a record.
-@return offset from the origin of rec */
+@return offset from the origin of rec */
UNIV_INLINE
ulint
rec_get_nth_field_offs(
@@ -1062,7 +1100,7 @@ rec_get_nth_field_offs(
/******************************************************//**
Determine if the offsets are for a record in the new
compact format.
-@return nonzero if compact format */
+@return nonzero if compact format */
UNIV_INLINE
ulint
rec_offs_comp(
@@ -1076,7 +1114,7 @@ rec_offs_comp(
/******************************************************//**
Determine if the offsets are for a record containing
externally stored columns.
-@return nonzero if externally stored */
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_any_extern(
@@ -1089,7 +1127,7 @@ rec_offs_any_extern(
/******************************************************//**
Determine if the offsets are for a record containing null BLOB pointers.
-@return first field containing a null BLOB pointer, or NULL if none found */
+@return first field containing a null BLOB pointer, or NULL if none found */
UNIV_INLINE
const byte*
rec_offs_any_null_extern(
@@ -1125,7 +1163,7 @@ rec_offs_any_null_extern(
/******************************************************//**
Returns nonzero if the extern bit is set in nth field of rec.
-@return nonzero if externally stored */
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_nth_extern(
@@ -1140,7 +1178,7 @@ rec_offs_nth_extern(
/******************************************************//**
Returns nonzero if the SQL NULL bit is set in nth field of rec.
-@return nonzero if SQL NULL */
+@return nonzero if SQL NULL */
UNIV_INLINE
ulint
rec_offs_nth_sql_null(
@@ -1155,7 +1193,7 @@ rec_offs_nth_sql_null(
/******************************************************//**
Gets the physical size of a field.
-@return length of field */
+@return length of field */
UNIV_INLINE
ulint
rec_offs_nth_size(
@@ -1174,7 +1212,7 @@ rec_offs_nth_size(
/******************************************************//**
Returns the number of extern bits set in a record.
-@return number of externally stored fields */
+@return number of externally stored fields */
UNIV_INLINE
ulint
rec_offs_n_extern(
@@ -1202,7 +1240,7 @@ offsets form. If the field is SQL null, the flag is ORed in the returned
value. This function and the 2-byte counterpart are defined here because the
C-compiler was not able to sum negative and positive constant offsets, and
warned of constant arithmetic overflow within the compiler.
-@return offset of the start of the PREVIOUS field, SQL null flag ORed */
+@return offset of the start of the PREVIOUS field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_1_get_prev_field_end_info(
@@ -1220,7 +1258,7 @@ rec_1_get_prev_field_end_info(
Returns the offset of n - 1th field end if the record is stored in the 2-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
value.
-@return offset of the start of the PREVIOUS field, SQL null flag ORed */
+@return offset of the start of the PREVIOUS field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_2_get_prev_field_end_info(
@@ -1271,7 +1309,7 @@ rec_2_set_field_end_info(
/******************************************************//**
Returns the offset of nth field start if the record is stored in the 1-byte
offsets form.
-@return offset of the start of the field */
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_1_get_field_start_offs(
@@ -1294,7 +1332,7 @@ rec_1_get_field_start_offs(
/******************************************************//**
Returns the offset of nth field start if the record is stored in the 2-byte
offsets form.
-@return offset of the start of the field */
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_2_get_field_start_offs(
@@ -1319,7 +1357,7 @@ The following function is used to read the offset of the start of a data field
in the record. The start of an SQL null field is the end offset of the
previous non-null field, or 0, if none exists. If n is the number of the last
field + 1, then the end offset of the last field is returned.
-@return offset of the start of the field */
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_get_field_start_offs(
@@ -1347,7 +1385,7 @@ rec_get_field_start_offs(
Gets the physical size of an old-style field.
Also an SQL null may have a field of size > 0,
if the data type is of a fixed size.
-@return field size in bytes */
+@return field size in bytes */
UNIV_INLINE
ulint
rec_get_nth_field_size(
@@ -1415,7 +1453,7 @@ The following function returns the data size of an old-style physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
is the distance from record origin to record end in bytes.
-@return size */
+@return size */
UNIV_INLINE
ulint
rec_get_data_size_old(
@@ -1450,7 +1488,7 @@ The following function returns the data size of a physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
is the distance from record origin to record end in bytes.
-@return size */
+@return size */
UNIV_INLINE
ulint
rec_offs_data_size(
@@ -1470,7 +1508,7 @@ rec_offs_data_size(
Returns the total size of record minus data size of record. The value
returned by the function is the distance from record start to record origin
in bytes.
-@return size */
+@return size */
UNIV_INLINE
ulint
rec_offs_extra_size(
@@ -1486,7 +1524,7 @@ rec_offs_extra_size(
/**********************************************************//**
Returns the total size of a physical record.
-@return size */
+@return size */
UNIV_INLINE
ulint
rec_offs_size(
@@ -1499,7 +1537,7 @@ rec_offs_size(
#ifdef UNIV_DEBUG
/**********************************************************//**
Returns a pointer to the end of the record.
-@return pointer to end */
+@return pointer to end */
UNIV_INLINE
byte*
rec_get_end(
@@ -1513,7 +1551,7 @@ rec_get_end(
/**********************************************************//**
Returns a pointer to the start of the record.
-@return pointer to start */
+@return pointer to start */
UNIV_INLINE
byte*
rec_get_start(
@@ -1526,16 +1564,17 @@ rec_get_start(
}
#endif /* UNIV_DEBUG */
-/***************************************************************//**
-Copies a physical record to a buffer.
-@return pointer to the origin of the copy */
+/** Copy a physical record to a buffer.
+@param[in] buf buffer
+@param[in] rec physical record
+@param[in] offsets array returned by rec_get_offsets()
+@return pointer to the origin of the copy */
UNIV_INLINE
rec_t*
rec_copy(
-/*=====*/
- void* buf, /*!< in: buffer */
- const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ void* buf,
+ const rec_t* rec,
+ const ulint* offsets)
{
ulint extra_len;
ulint data_len;
@@ -1556,7 +1595,7 @@ rec_copy(
/**********************************************************//**
Returns the extra size of an old-style physical record if we know its
data size and number of fields.
-@return extra size */
+@return extra size */
UNIV_INLINE
ulint
rec_get_converted_extra_size(
@@ -1576,7 +1615,7 @@ rec_get_converted_extra_size(
/**********************************************************//**
The following function returns the size of a data tuple when converted to
a physical record.
-@return size */
+@return size */
UNIV_INLINE
ulint
rec_get_converted_size(
@@ -1592,12 +1631,19 @@ rec_get_converted_size(
ut_ad(dtuple);
ut_ad(dtuple_check_typed(dtuple));
- ut_ad(dict_index_is_univ(index)
+ ut_ad(dict_index_is_ibuf(index)
+
|| dtuple_get_n_fields(dtuple)
- == (((dtuple_get_info_bits(dtuple) & REC_NEW_STATUS_MASK)
- == REC_STATUS_NODE_PTR)
- ? dict_index_get_n_unique_in_tree(index) + 1
- : dict_index_get_n_fields(index)));
+ == (((dtuple_get_info_bits(dtuple) & REC_NEW_STATUS_MASK)
+ == REC_STATUS_NODE_PTR)
+ ? dict_index_get_n_unique_in_tree_nonleaf(index) + 1
+ : dict_index_get_n_fields(index))
+
+ /* a record for older SYS_INDEXES table
+ (missing merge_threshold column) is acceptable. */
+ || (index->table->id == DICT_INDEXES_ID
+ && dtuple_get_n_fields(dtuple)
+ == dict_index_get_n_fields(index) - 1));
if (dict_table_is_comp(index->table)) {
return(rec_get_converted_size_comp(index,
@@ -1622,7 +1668,7 @@ rec_get_converted_size(
support multiple page sizes. At that time, we will need
to consider the node pointer on these universal btrees. */
- if (dict_index_is_univ(index)) {
+ if (dict_index_is_ibuf(index)) {
/* This is for the insert buffer B-tree.
All fields in the leaf tuple ascend to the
parent node plus the child page pointer. */
@@ -1651,22 +1697,21 @@ rec_get_converted_size(
}
#ifndef UNIV_HOTBACKUP
-/************************************************************//**
-Folds a prefix of a physical record to a ulint. Folds only existing fields,
-that is, checks that we do not run out of the record.
-@return the folded value */
+/** Fold a prefix of a physical record.
+@param[in] rec index record
+@param[in] offsets return value of rec_get_offsets()
+@param[in] n_fields number of complete fields to fold
+@param[in] n_bytes number of bytes to fold in the last field
+@param[in] index_id index tree ID
+@return the folded value */
UNIV_INLINE
ulint
rec_fold(
-/*=====*/
- const rec_t* rec, /*!< in: the physical record */
- const ulint* offsets, /*!< in: array returned by
- rec_get_offsets() */
- ulint n_fields, /*!< in: number of complete
- fields to fold */
- ulint n_bytes, /*!< in: number of bytes to fold
- in an incomplete last field */
- index_id_t tree_id) /*!< in: index tree id */
+ const rec_t* rec,
+ const ulint* offsets,
+ ulint n_fields,
+ ulint n_bytes,
+ index_id_t tree_id)
{
ulint i;
const byte* data;
@@ -1676,7 +1721,7 @@ rec_fold(
ut_ad(rec_offs_validate(rec, NULL, offsets));
ut_ad(rec_validate(rec, offsets));
- ut_ad(n_fields + n_bytes > 0);
+ ut_ad(n_fields > 0 || n_bytes > 0);
n_fields_rec = rec_offs_n_fields(offsets);
ut_ad(n_fields <= n_fields_rec);