summaryrefslogtreecommitdiff
path: root/storage/innobase/include/data0data.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/data0data.h')
-rw-r--r--storage/innobase/include/data0data.h268
1 files changed, 203 insertions, 65 deletions
diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h
index 1d954bfc07c..24b0a791535 100644
--- a/storage/innobase/include/data0data.h
+++ b/storage/innobase/include/data0data.h
@@ -33,14 +33,17 @@ Created 5/30/1994 Heikki Tuuri
#include "mem0mem.h"
#include "dict0types.h"
+#include <ostream>
+
/** Storage for overflow data in a big record, that is, a clustered
index record which needs external storage of data fields */
struct big_rec_t;
+struct upd_t;
#ifdef UNIV_DEBUG
/*********************************************************************//**
Gets pointer to the type struct of SQL data field.
-@return pointer to the type struct */
+@return pointer to the type struct */
UNIV_INLINE
dtype_t*
dfield_get_type(
@@ -49,7 +52,7 @@ dfield_get_type(
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Gets pointer to the data in a field.
-@return pointer to data */
+@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
@@ -71,7 +74,7 @@ dfield_set_type(
MY_ATTRIBUTE((nonnull));
/*********************************************************************//**
Gets length of field data.
-@return length of data; UNIV_SQL_NULL if SQL null data */
+@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
@@ -89,7 +92,7 @@ dfield_set_len(
MY_ATTRIBUTE((nonnull));
/*********************************************************************//**
Determines if a field is SQL NULL
-@return nonzero if SQL null data */
+@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
@@ -98,7 +101,7 @@ dfield_is_null(
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Determines if a field is externally stored
-@return nonzero if externally stored */
+@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
@@ -124,6 +127,15 @@ dfield_set_data(
ulint len) /*!< in: length or UNIV_SQL_NULL */
MY_ATTRIBUTE((nonnull(1)));
/*********************************************************************//**
+Sets pointer to the data and length in a field. */
+UNIV_INLINE
+void
+dfield_write_mbr(
+/*=============*/
+ dfield_t* field, /*!< in: field */
+ const double* mbr) /*!< in: data */
+ __attribute__((nonnull(1)));
+/*********************************************************************//**
Sets a data field to SQL NULL. */
UNIV_INLINE
void
@@ -146,7 +158,7 @@ UNIV_INLINE
void
dfield_copy_data(
/*=============*/
- dfield_t* field1, /*!< out: field to copy to */
+ dfield_t* field1, /*!< out: field to copy to */
const dfield_t* field2) /*!< in: field to copy from */
MY_ATTRIBUTE((nonnull));
/*********************************************************************//**
@@ -172,7 +184,7 @@ dfield_dup(
Tests if two data fields are equal.
If len==0, tests the data length and content for equality.
If len>0, tests the first len bytes of the content for equality.
-@return TRUE if both fields are NULL or if they are equal */
+@return TRUE if both fields are NULL or if they are equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
@@ -184,7 +196,7 @@ dfield_datas_are_binary_equal(
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Tests if dfield data length and content is equal to the given.
-@return TRUE if equal */
+@return TRUE if equal */
UNIV_INLINE
ibool
dfield_data_is_binary_equal(
@@ -196,29 +208,47 @@ dfield_data_is_binary_equal(
#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Gets number of fields in a data tuple.
-@return number of fields */
+@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
const dtuple_t* tuple) /*!< in: tuple */
MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Gets number of virtual fields in a data tuple.
+@param[in] tuple dtuple to check
+@return number of fields */
+UNIV_INLINE
+ulint
+dtuple_get_n_v_fields(
+ const dtuple_t* tuple);
+
#ifdef UNIV_DEBUG
-/*********************************************************************//**
-Gets nth field of a tuple.
-@return nth field */
+/** Gets nth field of a tuple.
+@param[in] tuple tuple
+@param[in] n index of field
+@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
-/*=================*/
- const dtuple_t* tuple, /*!< in: tuple */
- ulint n); /*!< in: index of field */
+ const dtuple_t* tuple,
+ ulint n);
+/** Gets nth virtual field of a tuple.
+@param[in] tuple tuple
+@oaran[in] n the nth field to get
+@return nth field */
+UNIV_INLINE
+dfield_t*
+dtuple_get_nth_v_field(
+ const dtuple_t* tuple,
+ ulint n);
#else /* UNIV_DEBUG */
# define dtuple_get_nth_field(tuple, n) ((tuple)->fields + (n))
+# define dtuple_get_nth_v_field(tuple, n) ((tuple)->fields + (tuple)->n_fields + (n))
#endif /* UNIV_DEBUG */
/*********************************************************************//**
Gets info bits in a data tuple.
-@return info bits */
+@return info bits */
UNIV_INLINE
ulint
dtuple_get_info_bits(
@@ -236,7 +266,7 @@ dtuple_set_info_bits(
MY_ATTRIBUTE((nonnull));
/*********************************************************************//**
Gets number of fields used in record comparisons.
-@return number of fields used in comparisons in rem0cmp.* */
+@return number of fields used in comparisons in rem0cmp.* */
UNIV_INLINE
ulint
dtuple_get_n_fields_cmp(
@@ -259,25 +289,28 @@ creating a new dtuple_t object */
#define DTUPLE_EST_ALLOC(n_fields) \
(sizeof(dtuple_t) + (n_fields) * sizeof(dfield_t))
-/**********************************************************//**
-Creates a data tuple from an already allocated chunk of memory.
+/** Creates a data tuple from an already allocated chunk of memory.
The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields).
The default value for number of fields used in record comparisons
for this tuple is n_fields.
-@return created tuple (inside buf) */
+@param[in,out] buf buffer to use
+@param[in] buf_size buffer size
+@param[in] n_fields number of field
+@param[in] n_v_fields number of fields on virtual columns
+@return created tuple (inside buf) */
UNIV_INLINE
dtuple_t*
dtuple_create_from_mem(
-/*===================*/
- void* buf, /*!< in, out: buffer to use */
- ulint buf_size, /*!< in: buffer size */
- ulint n_fields) /*!< in: number of fields */
+ void* buf,
+ ulint buf_size,
+ ulint n_fields,
+ ulint n_v_fields)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************//**
Creates a data tuple to a memory heap. The default value for number
of fields used in record comparisons for this tuple is n_fields.
-@return own: created tuple */
+@return own: created tuple */
UNIV_INLINE
dtuple_t*
dtuple_create(
@@ -288,20 +321,56 @@ dtuple_create(
ulint n_fields)/*!< in: number of fields */
MY_ATTRIBUTE((nonnull, malloc));
+
+/** Initialize the virtual field data in a dtuple_t
+@param[in,out] vrow dtuple contains the virtual fields */
+UNIV_INLINE
+void
+dtuple_init_v_fld(
+ const dtuple_t* vrow);
+
+/** Duplicate the virtual field data in a dtuple_t
+@param[in,out] vrow dtuple contains the virtual fields
+@param[in] heap heap memory to use */
+UNIV_INLINE
+void
+dtuple_dup_v_fld(
+ const dtuple_t* vrow,
+ mem_heap_t* heap);
+
+/** Creates a data tuple with possible virtual columns to a memory heap.
+@param[in] heap memory heap where the tuple is created
+@param[in] n_fields number of fields
+@param[in] n_v_fields number of fields on virtual col
+@return own: created tuple */
+UNIV_INLINE
+dtuple_t*
+dtuple_create_with_vcol(
+ mem_heap_t* heap,
+ ulint n_fields,
+ ulint n_v_fields);
+
/*********************************************************************//**
Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */
-UNIV_INTERN
void
dtuple_set_n_fields(
/*================*/
dtuple_t* tuple, /*!< in: tuple */
ulint n_fields) /*!< in: number of fields */
MY_ATTRIBUTE((nonnull));
+/** Copies a data tuple's virtaul fields to another. This is a shallow copy;
+@param[in,out] d_tuple destination tuple
+@param[in] s_tuple source tuple */
+UNIV_INLINE
+void
+dtuple_copy_v_fields(
+ dtuple_t* d_tuple,
+ const dtuple_t* s_tuple);
/*********************************************************************//**
Copies a data tuple to another. This is a shallow copy; if a deep copy
is desired, dfield_dup() will have to be invoked on each field.
-@return own: copy of tuple */
+@return own: copy of tuple */
UNIV_INLINE
dtuple_t*
dtuple_copy(
@@ -313,7 +382,7 @@ dtuple_copy(
/**********************************************************//**
The following function returns the sum of data lengths of a tuple. The space
occupied by the field structs or the tuple struct is not counted.
-@return sum of data lens */
+@return sum of data lens */
UNIV_INLINE
ulint
dtuple_get_data_size(
@@ -323,37 +392,37 @@ dtuple_get_data_size(
MY_ATTRIBUTE((nonnull));
/*********************************************************************//**
Computes the number of externally stored fields in a data tuple.
-@return number of fields */
+@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_ext(
/*=============*/
const dtuple_t* tuple) /*!< in: tuple */
MY_ATTRIBUTE((nonnull));
-/************************************************************//**
-Compare two data tuples, respecting the collation of character fields.
-@return 1, 0 , -1 if tuple1 is greater, equal, less, respectively,
-than tuple2 */
-UNIV_INTERN
+/** Compare two data tuples.
+@param[in] tuple1 first data tuple
+@param[in] tuple2 second data tuple
+@return positive, 0, negative if tuple1 is greater, equal, less, than tuple2,
+respectively */
int
dtuple_coll_cmp(
-/*============*/
- const dtuple_t* tuple1, /*!< in: tuple 1 */
- const dtuple_t* tuple2) /*!< in: tuple 2 */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/************************************************************//**
-Folds a prefix given as the number of fields of a tuple.
-@return the folded value */
+ const dtuple_t* tuple1,
+ const dtuple_t* tuple2)
+ __attribute__((warn_unused_result));
+/** Fold a prefix given as the number of fields of a tuple.
+@param[in] tuple index record
+@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
dtuple_fold(
-/*========*/
- const dtuple_t* tuple, /*!< in: the tuple */
- 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 */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ const dtuple_t* tuple,
+ ulint n_fields,
+ ulint n_bytes,
+ index_id_t tree_id)
+ __attribute__((warn_unused_result));
/*******************************************************************//**
Sets types of fields binary in a tuple. */
UNIV_INLINE
@@ -365,7 +434,7 @@ dtuple_set_types_binary(
MY_ATTRIBUTE((nonnull));
/**********************************************************************//**
Checks if a dtuple contains an SQL null value.
-@return TRUE if some field is SQL null */
+@return TRUE if some field is SQL null */
UNIV_INLINE
ibool
dtuple_contains_null(
@@ -374,8 +443,7 @@ dtuple_contains_null(
MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************//**
Checks that a data field is typed. Asserts an error if not.
-@return TRUE if ok */
-UNIV_INTERN
+@return TRUE if ok */
ibool
dfield_check_typed(
/*===============*/
@@ -383,8 +451,7 @@ dfield_check_typed(
MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************//**
Checks that a data tuple is typed. Asserts an error if not.
-@return TRUE if ok */
-UNIV_INTERN
+@return TRUE if ok */
ibool
dtuple_check_typed(
/*===============*/
@@ -392,8 +459,7 @@ dtuple_check_typed(
MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************//**
Checks that a data tuple is typed.
-@return TRUE if ok */
-UNIV_INTERN
+@return TRUE if ok */
ibool
dtuple_check_typed_no_assert(
/*=========================*/
@@ -403,8 +469,7 @@ dtuple_check_typed_no_assert(
/**********************************************************//**
Validates the consistency of a tuple which must be complete, i.e,
all fields must have been set.
-@return TRUE if ok */
-UNIV_INTERN
+@return TRUE if ok */
ibool
dtuple_validate(
/*============*/
@@ -413,7 +478,6 @@ dtuple_validate(
#endif /* UNIV_DEBUG */
/*************************************************************//**
Pretty prints a dfield value according to its data type. */
-UNIV_INTERN
void
dfield_print(
/*=========*/
@@ -422,7 +486,6 @@ dfield_print(
/*************************************************************//**
Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */
-UNIV_INTERN
void
dfield_print_also_hex(
/*==================*/
@@ -430,13 +493,41 @@ dfield_print_also_hex(
MY_ATTRIBUTE((nonnull));
/**********************************************************//**
The following function prints the contents of a tuple. */
-UNIV_INTERN
void
dtuple_print(
/*=========*/
FILE* f, /*!< in: output stream */
const dtuple_t* tuple) /*!< in: tuple */
MY_ATTRIBUTE((nonnull));
+
+/** Print the contents of a tuple.
+@param[out] o output stream
+@param[in] field array of data fields
+@param[in] n number of data fields */
+void
+dfield_print(
+ std::ostream& o,
+ const dfield_t* field,
+ ulint n);
+/** Print the contents of a tuple.
+@param[out] o output stream
+@param[in] tuple data tuple */
+void
+dtuple_print(
+ std::ostream& o,
+ const dtuple_t* tuple);
+
+/** Print the contents of a tuple.
+@param[out] o output stream
+@param[in] tuple data tuple */
+inline
+std::ostream&
+operator<<(std::ostream& o, const dtuple_t& tuple)
+{
+ dtuple_print(o, &tuple);
+ return(o);
+}
+
/**************************************************************//**
Moves parts of long fields in entry to the big record vector so that
the size of tuple drops below the maximum record size allowed in the
@@ -445,20 +536,19 @@ to determine uniquely the insertion place of the tuple in the index.
@return own: created big record vector, NULL if we are not able to
shorten the entry enough, i.e., if there are too many fixed-length or
short fields in entry or the index is clustered */
-UNIV_INTERN
big_rec_t*
dtuple_convert_big_rec(
/*===================*/
dict_index_t* index, /*!< in: index */
+ upd_t* upd, /*!< in/out: update vector */
dtuple_t* entry, /*!< in/out: index entry */
ulint* n_ext) /*!< in/out: number of
externally stored columns */
- MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
+ MY_ATTRIBUTE((nonnull(1,4), malloc, warn_unused_result));
/**************************************************************//**
Puts back to entry the data stored in vector. Note that to ensure the
fields in entry can accommodate the data, vector must have been created
from entry with dtuple_convert_big_rec. */
-UNIV_INTERN
void
dtuple_convert_back_big_rec(
/*========================*/
@@ -482,9 +572,15 @@ dtuple_big_rec_free(
/** Structure for an SQL data field */
struct dfield_t{
void* data; /*!< pointer to data */
- unsigned ext:1; /*!< TRUE=externally stored, FALSE=local */
- unsigned len:32; /*!< data length; UNIV_SQL_NULL if SQL null */
+ unsigned ext; /*!< TRUE=externally stored, FALSE=local */
+ unsigned len; /*!< data length; UNIV_SQL_NULL if SQL null */
dtype_t type; /*!< type of data */
+
+ /** Create a deep copy of this object
+ @param[in] heap the memory heap in which the clone will be
+ created.
+ @return the cloned object. */
+ dfield_t* clone(mem_heap_t* heap);
};
/** Structure for an SQL data tuple of fields (logical record) */
@@ -502,6 +598,8 @@ struct dtuple_t {
default value in dtuple creation is
the same value as n_fields */
dfield_t* fields; /*!< fields */
+ ulint n_v_fields; /*!< number of virtual fields */
+ dfield_t* v_fields; /*!< fields on virtual column */
UT_LIST_NODE_T(dtuple_t) tuple_list;
/*!< data tuples can be linked into a
list using this field */
@@ -513,8 +611,20 @@ struct dtuple_t {
#endif /* UNIV_DEBUG */
};
+
/** A slot for a field in a big rec vector */
struct big_rec_field_t {
+
+ /** Constructor.
+ @param[in] field_no_ the field number
+ @param[in] len_ the data length
+ @param[in] data_ the data */
+ big_rec_field_t(ulint field_no_, ulint len_, const void* data_)
+ : field_no(field_no_),
+ len(len_),
+ data(data_)
+ {}
+
ulint field_no; /*!< field number in record */
ulint len; /*!< stored data length, in bytes */
const void* data; /*!< stored data */
@@ -525,8 +635,36 @@ clustered index record which needs external storage of data fields */
struct big_rec_t {
mem_heap_t* heap; /*!< memory heap from which
allocated */
+ const ulint capacity; /*!< fields array size */
ulint n_fields; /*!< number of stored fields */
big_rec_field_t*fields; /*!< stored fields */
+
+ /** Constructor.
+ @param[in] max the capacity of the array of fields. */
+ explicit big_rec_t(const ulint max)
+ : heap(0),
+ capacity(max),
+ n_fields(0),
+ fields(0)
+ {}
+
+ /** Append one big_rec_field_t object to the end of array of fields */
+ void append(const big_rec_field_t& field)
+ {
+ ut_ad(n_fields < capacity);
+ fields[n_fields] = field;
+ n_fields++;
+ }
+
+ /** Allocate a big_rec_t object in the given memory heap, and for
+ storing n_fld number of fields.
+ @param[in] heap memory heap in which this object is allocated
+ @param[in] n_fld maximum number of fields that can be stored in
+ this object
+ @return the allocated object */
+ static big_rec_t* alloc(
+ mem_heap_t* heap,
+ ulint n_fld);
};
#ifndef UNIV_NONINL