summaryrefslogtreecommitdiff
path: root/storage/innobase/include/rem0rec.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/rem0rec.h')
-rw-r--r--storage/innobase/include/rem0rec.h209
1 files changed, 115 insertions, 94 deletions
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index 29923839ce1..bd6bb563192 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -61,45 +61,86 @@ The status is stored in the low-order bits. */
/* Length of a B-tree node pointer, in bytes */
#define REC_NODE_PTR_SIZE 4
+#ifndef UNIV_INNOCHECKSUM
/** SQL null flag in a 1-byte offset of ROW_FORMAT=REDUNDANT records */
-#define REC_1BYTE_SQL_NULL_MASK 0x80UL
+static const offset_t REC_1BYTE_SQL_NULL_MASK= 0x80;
/** SQL null flag in a 2-byte offset of ROW_FORMAT=REDUNDANT records */
-#define REC_2BYTE_SQL_NULL_MASK 0x8000UL
+static const offset_t REC_2BYTE_SQL_NULL_MASK= 0x8000;
/** In a 2-byte offset of ROW_FORMAT=REDUNDANT records, the second most
significant bit denotes that the tail of a field is stored off-page. */
-#define REC_2BYTE_EXTERN_MASK 0x4000UL
+static const offset_t REC_2BYTE_EXTERN_MASK= 0x4000;
+
+static const size_t RECORD_OFFSET= 2;
+static const size_t INDEX_OFFSET=
+ RECORD_OFFSET + sizeof(rec_t *) / sizeof(offset_t);
+#endif /* UNIV_INNOCHECKSUM */
-#ifdef UNIV_DEBUG
-/* Length of the rec_get_offsets() header */
-# define REC_OFFS_HEADER_SIZE 4
-#else /* UNIV_DEBUG */
/* Length of the rec_get_offsets() header */
-# define REC_OFFS_HEADER_SIZE 2
+static const size_t REC_OFFS_HEADER_SIZE=
+#ifdef UNIV_DEBUG
+#ifndef UNIV_INNOCHECKSUM
+ sizeof(rec_t *) / sizeof(offset_t) +
+ sizeof(dict_index_t *) / sizeof(offset_t) +
+#endif /* UNIV_INNOCHECKSUM */
#endif /* UNIV_DEBUG */
+ 2;
/* Number of elements that should be initially allocated for the
offsets[] array, first passed to rec_get_offsets() */
-#define REC_OFFS_NORMAL_SIZE OFFS_IN_REC_NORMAL_SIZE
-#define REC_OFFS_SMALL_SIZE 10
+static const size_t REC_OFFS_NORMAL_SIZE= 300;
+static const size_t REC_OFFS_SMALL_SIZE= 18;
+static const size_t REC_OFFS_SEC_INDEX_SIZE=
+ /* PK max key parts */ 16 + /* sec idx max key parts */ 16 +
+ /* child page number for non-leaf pages */ 1;
/** Get the base address of offsets. The extra_size is stored at
this position, and following positions hold the end offsets of
the fields. */
#define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE)
+#ifndef UNIV_INNOCHECKSUM
+/* Offset consists of two parts: 2 upper bits is type and all other bits is
+value */
+
+/** Only 4 different values is possible! */
+enum field_type_t
+{
+ /** normal field */
+ STORED_IN_RECORD= 0 << 14,
+ /** this field is stored off-page */
+ STORED_OFFPAGE= 1 << 14,
+ /** just an SQL NULL */
+ SQL_NULL= 2 << 14,
+ /** instantly added field */
+ DEFAULT= 3 << 14,
+};
+
+/** without 2 upper bits */
+static const offset_t DATA_MASK= 0x3fff;
+/** 2 upper bits */
+static const offset_t TYPE_MASK= ~DATA_MASK;
+inline field_type_t get_type(offset_t n)
+{
+ return static_cast<field_type_t>(n & TYPE_MASK);
+}
+inline void set_type(offset_t &n, field_type_t type)
+{
+ n= (n & DATA_MASK) | static_cast<offset_t>(type);
+}
+inline offset_t get_value(offset_t n) { return n & DATA_MASK; }
+inline offset_t combine(offset_t value, field_type_t type)
+{
+ return get_value(value) | static_cast<offset_t>(type);
+}
+
/** Compact flag ORed to the extra size returned by rec_get_offsets() */
-const ulint REC_OFFS_COMPACT = ~(ulint(~0) >> 1);
-/** SQL NULL flag in offsets returned by rec_get_offsets() */
-const ulint REC_OFFS_SQL_NULL = REC_OFFS_COMPACT;
+const offset_t REC_OFFS_COMPACT= ~(offset_t(~0) >> 1);
/** External flag in offsets returned by rec_get_offsets() */
-const ulint REC_OFFS_EXTERNAL = REC_OFFS_COMPACT >> 1;
+const offset_t REC_OFFS_EXTERNAL= REC_OFFS_COMPACT >> 1;
/** Default value flag in offsets returned by rec_get_offsets() */
-const ulint REC_OFFS_DEFAULT = REC_OFFS_COMPACT >> 2;
-/** Mask for offsets returned by rec_get_offsets() */
-const ulint REC_OFFS_MASK = REC_OFFS_DEFAULT - 1;
-
-#ifndef UNIV_INNOCHECKSUM
+const offset_t REC_OFFS_DEFAULT= REC_OFFS_COMPACT >> 2;
+const offset_t REC_OFFS_MASK= REC_OFFS_DEFAULT - 1;
/******************************************************//**
The following function is used to get the pointer of the next chained record
on the same page.
@@ -452,7 +493,7 @@ 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 */
UNIV_INLINE
-ulint
+uint8_t
rec_1_get_field_end_info(
/*=====================*/
const rec_t* rec, /*!< in: record */
@@ -466,7 +507,7 @@ value.
@return offset of the start of the field, SQL null flag and extern
storage flag ORed */
UNIV_INLINE
-ulint
+uint16_t
rec_2_get_field_end_info(
/*=====================*/
const rec_t* rec, /*!< in: record */
@@ -507,11 +548,11 @@ rec_get_n_extern_new(
(ULINT_UNDEFINED to compute all offsets)
@param[in,out] heap memory heap
@return the new offsets */
-ulint*
+offset_t*
rec_get_offsets_func(
const rec_t* rec,
const dict_index_t* index,
- ulint* offsets,
+ offset_t* offsets,
bool leaf,
ulint n_fields,
#ifdef UNIV_DEBUG
@@ -546,7 +587,7 @@ rec_get_offsets_reverse(
const dict_index_t* index, /*!< in: record descriptor */
ulint node_ptr,/*!< in: nonzero=node pointer,
0=leaf node */
- ulint* offsets)/*!< in/out: array consisting of
+ offset_t* offsets)/*!< in/out: array consisting of
offsets[0] allocated elements */
MY_ATTRIBUTE((nonnull));
#ifdef UNIV_DEBUG
@@ -559,7 +600,7 @@ bool
rec_offs_validate(
const rec_t* rec,
const dict_index_t* index,
- const ulint* offsets)
+ const offset_t* offsets)
MY_ATTRIBUTE((nonnull(3), warn_unused_result));
/** Update debug data in offsets, in order to tame rec_offs_validate().
@param[in] rec record
@@ -571,7 +612,7 @@ rec_offs_make_valid(
const rec_t* rec,
const dict_index_t* index,
bool leaf,
- ulint* offsets)
+ offset_t* offsets)
MY_ATTRIBUTE((nonnull));
#else
# define rec_offs_make_valid(rec, index, leaf, offsets)
@@ -608,17 +649,16 @@ The following function is used to get an offset to the nth
data field in a record.
@return offset from the origin of rec */
UNIV_INLINE
-ulint
+offset_t
rec_get_nth_field_offs(
/*===================*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n, /*!< in: index of the field */
ulint* len) /*!< out: length of the field; UNIV_SQL_NULL
if SQL null */
MY_ATTRIBUTE((nonnull));
#define rec_get_nth_field(rec, offsets, n, len) \
((rec) + rec_get_nth_field_offs(offsets, n, len))
-
/******************************************************//**
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 */
@@ -627,7 +667,7 @@ const byte*
rec_offs_any_null_extern(
/*=====================*/
const rec_t* rec, /*!< in: record */
- const ulint* offsets) /*!< in: rec_get_offsets(rec) */
+ const offset_t* offsets) /*!< in: rec_get_offsets(rec) */
MY_ATTRIBUTE((warn_unused_result));
/** Mark the nth field as externally stored.
@@ -635,7 +675,7 @@ rec_offs_any_null_extern(
@param[in] n nth field */
void
rec_offs_make_nth_extern(
- ulint* offsets,
+ offset_t* offsets,
const ulint n);
/** Determine the number of allocated elements for an array of offsets.
@@ -643,7 +683,7 @@ rec_offs_make_nth_extern(
@return number of elements */
inline
ulint
-rec_offs_get_n_alloc(const ulint* offsets)
+rec_offs_get_n_alloc(const offset_t* offsets)
{
ulint n_alloc;
ut_ad(offsets);
@@ -658,7 +698,7 @@ rec_offs_get_n_alloc(const ulint* offsets)
@return number of fields */
inline
ulint
-rec_offs_n_fields(const ulint* offsets)
+rec_offs_n_fields(const offset_t* offsets)
{
ulint n_fields;
ut_ad(offsets);
@@ -674,19 +714,12 @@ rec_offs_n_fields(const ulint* offsets)
@param[in] offsets rec_get_offsets()
@param[in] n nth field
@param[in] flag flag to extract
-@return the flag of the record field */
-inline
-ulint
-rec_offs_nth_flag(const ulint* offsets, ulint n, ulint flag)
+@return type of the record field */
+inline field_type_t rec_offs_nth_type(const offset_t *offsets, ulint n)
{
- ut_ad(rec_offs_validate(NULL, NULL, offsets));
- ut_ad(n < rec_offs_n_fields(offsets));
- /* The DEFAULT, NULL, EXTERNAL flags are mutually exclusive. */
- ut_ad(ut_is_2pow(rec_offs_base(offsets)[1 + n]
- & (REC_OFFS_DEFAULT
- | REC_OFFS_SQL_NULL
- | REC_OFFS_EXTERNAL)));
- return rec_offs_base(offsets)[1 + n] & flag;
+ ut_ad(rec_offs_validate(NULL, NULL, offsets));
+ ut_ad(n < rec_offs_n_fields(offsets));
+ return get_type(rec_offs_base(offsets)[1 + n]);
}
/** Determine if a record field is missing
@@ -694,11 +727,9 @@ rec_offs_nth_flag(const ulint* offsets, ulint n, ulint flag)
@param[in] offsets rec_get_offsets()
@param[in] n nth field
@return nonzero if default bit is set */
-inline
-ulint
-rec_offs_nth_default(const ulint* offsets, ulint n)
+inline ulint rec_offs_nth_default(const offset_t *offsets, ulint n)
{
- return rec_offs_nth_flag(offsets, n, REC_OFFS_DEFAULT);
+ return rec_offs_nth_type(offsets, n) == DEFAULT;
}
/** Determine if a record field is SQL NULL
@@ -706,11 +737,9 @@ rec_offs_nth_default(const ulint* offsets, ulint n)
@param[in] offsets rec_get_offsets()
@param[in] n nth field
@return nonzero if SQL NULL set */
-inline
-ulint
-rec_offs_nth_sql_null(const ulint* offsets, ulint n)
+inline ulint rec_offs_nth_sql_null(const offset_t *offsets, ulint n)
{
- return rec_offs_nth_flag(offsets, n, REC_OFFS_SQL_NULL);
+ return rec_offs_nth_type(offsets, n) == SQL_NULL;
}
/** Determine if a record field is stored off-page.
@@ -718,54 +747,46 @@ rec_offs_nth_sql_null(const ulint* offsets, ulint n)
@param[in] n nth field
Returns nonzero if the extern bit is set in nth field of rec.
@return nonzero if externally stored */
-inline
-ulint
-rec_offs_nth_extern(const ulint* offsets, ulint n)
+inline ulint rec_offs_nth_extern(const offset_t *offsets, ulint n)
{
- return rec_offs_nth_flag(offsets, n, REC_OFFS_EXTERNAL);
+ return rec_offs_nth_type(offsets, n) == STORED_OFFPAGE;
}
/** Get a global flag of a record.
@param[in] offsets rec_get_offsets()
@param[in] flag flag to extract
@return the flag of the record field */
-inline
-ulint
-rec_offs_any_flag(const ulint* offsets, ulint flag)
+inline ulint rec_offs_any_flag(const offset_t *offsets, ulint flag)
{
- ut_ad(rec_offs_validate(NULL, NULL, offsets));
- return *rec_offs_base(offsets) & flag;
+ ut_ad(rec_offs_validate(NULL, NULL, offsets));
+ return *rec_offs_base(offsets) & flag;
}
/** Determine if the offsets are for a record containing off-page columns.
@param[in] offsets rec_get_offsets()
@return nonzero if any off-page columns exist */
-inline bool rec_offs_any_extern(const ulint* offsets)
+inline bool rec_offs_any_extern(const offset_t *offsets)
{
- return rec_offs_any_flag(offsets, REC_OFFS_EXTERNAL);
+ return rec_offs_any_flag(offsets, REC_OFFS_EXTERNAL);
}
/** Determine if the offsets are for a record that is missing fields.
@param[in] offsets rec_get_offsets()
@return nonzero if any fields need to be replaced with
dict_index_t::instant_field_value() */
-inline
-ulint
-rec_offs_any_default(const ulint* offsets)
+inline ulint rec_offs_any_default(const offset_t *offsets)
{
- return rec_offs_any_flag(offsets, REC_OFFS_DEFAULT);
+ return rec_offs_any_flag(offsets, REC_OFFS_DEFAULT);
}
/** Determine if the offsets are for other than ROW_FORMAT=REDUNDANT.
@param[in] offsets rec_get_offsets()
@return nonzero if ROW_FORMAT is COMPACT,DYNAMIC or COMPRESSED
@retval 0 if ROW_FORMAT=REDUNDANT */
-inline
-ulint
-rec_offs_comp(const ulint* offsets)
+inline ulint rec_offs_comp(const offset_t *offsets)
{
- ut_ad(rec_offs_validate(NULL, NULL, offsets));
- return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);
+ ut_ad(rec_offs_validate(NULL, NULL, offsets));
+ return (*rec_offs_base(offsets) & REC_OFFS_COMPACT);
}
/** Determine if the record is the metadata pseudo-record
@@ -864,7 +885,7 @@ const byte*
rec_get_nth_cfield(
const rec_t* rec,
const dict_index_t* index,
- const ulint* offsets,
+ const offset_t* offsets,
ulint n,
ulint* len)
{
@@ -883,7 +904,7 @@ UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
MY_ATTRIBUTE((warn_unused_result));
@@ -894,7 +915,7 @@ UNIV_INLINE
ulint
rec_offs_n_extern(
/*==============*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/***********************************************************//**
This is used to modify the value of an already existing field in a record.
@@ -907,7 +928,7 @@ void
rec_set_nth_field(
/*==============*/
rec_t* rec, /*!< in: record */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n, /*!< in: index number of the field */
const void* data, /*!< in: pointer to the data if not SQL null */
ulint len) /*!< in: length of the data or UNIV_SQL_NULL.
@@ -935,7 +956,7 @@ UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
- ulint* offsets, /*!< out: array for rec_get_offsets(),
+ offset_t*offsets, /*!< out: array for rec_get_offsets(),
must be allocated */
ulint n_alloc) /*!< in: number of elements */
MY_ATTRIBUTE((nonnull));
@@ -951,7 +972,7 @@ UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns the total size of record minus data size of record.
@@ -962,7 +983,7 @@ UNIV_INLINE
ulint
rec_offs_extra_size(
/*================*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns the total size of a physical record.
@@ -971,7 +992,7 @@ UNIV_INLINE
ulint
rec_offs_size(
/*==========*/
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
#ifdef UNIV_DEBUG
/**********************************************************//**
@@ -982,7 +1003,7 @@ byte*
rec_get_start(
/*==========*/
const rec_t* rec, /*!< in: pointer to record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns a pointer to the end of the record.
@@ -992,7 +1013,7 @@ byte*
rec_get_end(
/*========*/
const rec_t* rec, /*!< in: pointer to record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((warn_unused_result));
#else /* UNIV_DEBUG */
# define rec_get_start(rec, offsets) ((rec) - rec_offs_extra_size(offsets))
@@ -1009,7 +1030,7 @@ rec_t*
rec_copy(
void* buf,
const rec_t* rec,
- const ulint* offsets);
+ const offset_t* offsets);
/** Determine the size of a data tuple prefix in a temporary file.
@param[in] index clustered or secondary index
@@ -1038,7 +1059,7 @@ void
rec_init_offsets_temp(
const rec_t* rec,
const dict_index_t* index,
- ulint* offsets,
+ offset_t* offsets,
ulint n_core,
const dict_col_t::def_t*def_val,
rec_comp_status_t status = REC_STATUS_ORDINARY)
@@ -1052,7 +1073,7 @@ void
rec_init_offsets_temp(
const rec_t* rec,
const dict_index_t* index,
- ulint* offsets)
+ offset_t* offsets)
MY_ATTRIBUTE((nonnull));
/** Convert a data tuple prefix to the temporary file format.
@@ -1172,7 +1193,7 @@ ibool
rec_validate(
/*=========*/
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Prints an old-style physical record. */
@@ -1189,7 +1210,7 @@ rec_print_mbr_rec(
/*==========*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Prints a physical record. */
@@ -1198,7 +1219,7 @@ rec_print_new(
/*==========*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Prints a physical record. */
@@ -1220,7 +1241,7 @@ rec_print(
std::ostream& o,
const rec_t* rec,
ulint info,
- const ulint* offsets);
+ const offset_t* offsets);
/** Wrapper for pretty-printing a record */
struct rec_index_print
@@ -1247,14 +1268,14 @@ operator<<(std::ostream& o, const rec_index_print& r);
struct rec_offsets_print
{
/** Constructor */
- rec_offsets_print(const rec_t* rec, const ulint* offsets) :
+ rec_offsets_print(const rec_t* rec, const offset_t* offsets) :
m_rec(rec), m_offsets(offsets)
{}
/** Record */
const rec_t* m_rec;
/** Offsets to each field */
- const ulint* m_offsets;
+ const offset_t* m_offsets;
};
/** Display a record.
@@ -1271,7 +1292,7 @@ public:
/** Construct a pretty-printed record.
@param rec record with header
@param offsets rec_get_offsets(rec, ...) */
- rec_printer(const rec_t* rec, const ulint* offsets)
+ rec_printer(const rec_t* rec, const offset_t* offsets)
:
std::ostringstream ()
{
@@ -1284,7 +1305,7 @@ public:
@param rec record, possibly lacking header
@param info rec_get_info_bits(rec)
@param offsets rec_get_offsets(rec, ...) */
- rec_printer(const rec_t* rec, ulint info, const ulint* offsets)
+ rec_printer(const rec_t* rec, ulint info, const offset_t* offsets)
:
std::ostringstream ()
{