summaryrefslogtreecommitdiff
path: root/storage/xtradb/include/data0data.ic
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/include/data0data.ic')
-rw-r--r--storage/xtradb/include/data0data.ic608
1 files changed, 608 insertions, 0 deletions
diff --git a/storage/xtradb/include/data0data.ic b/storage/xtradb/include/data0data.ic
new file mode 100644
index 00000000000..f11dbd9fce6
--- /dev/null
+++ b/storage/xtradb/include/data0data.ic
@@ -0,0 +1,608 @@
+/*****************************************************************************
+
+Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+
+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
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+/************************************************************************
+SQL data field and tuple
+
+Created 5/30/1994 Heikki Tuuri
+*************************************************************************/
+
+#include "mem0mem.h"
+#include "ut0rnd.h"
+
+#ifdef UNIV_DEBUG
+extern byte data_error;
+
+/*************************************************************************
+Gets pointer to the type struct of SQL data field. */
+UNIV_INLINE
+dtype_t*
+dfield_get_type(
+/*============*/
+ /* out: pointer to the type struct */
+ const dfield_t* field) /* in: SQL data field */
+{
+ ut_ad(field);
+
+ return((dtype_t*) &(field->type));
+}
+#endif /* UNIV_DEBUG */
+
+/*************************************************************************
+Sets the type struct of SQL data field. */
+UNIV_INLINE
+void
+dfield_set_type(
+/*============*/
+ dfield_t* field, /* in: SQL data field */
+ dtype_t* type) /* in: pointer to data type struct */
+{
+ ut_ad(field && type);
+
+ field->type = *type;
+}
+
+#ifdef UNIV_DEBUG
+/*************************************************************************
+Gets pointer to the data in a field. */
+UNIV_INLINE
+void*
+dfield_get_data(
+/*============*/
+ /* out: pointer to data */
+ const dfield_t* field) /* in: field */
+{
+ ut_ad(field);
+ ut_ad((field->len == UNIV_SQL_NULL)
+ || (field->data != &data_error));
+
+ return((void*) field->data);
+}
+#endif /* UNIV_DEBUG */
+
+/*************************************************************************
+Gets length of field data. */
+UNIV_INLINE
+ulint
+dfield_get_len(
+/*===========*/
+ /* out: length of data; UNIV_SQL_NULL if
+ SQL null data */
+ const dfield_t* field) /* in: field */
+{
+ ut_ad(field);
+ ut_ad((field->len == UNIV_SQL_NULL)
+ || (field->data != &data_error));
+
+ return(field->len);
+}
+
+/*************************************************************************
+Sets length in a field. */
+UNIV_INLINE
+void
+dfield_set_len(
+/*===========*/
+ dfield_t* field, /* in: field */
+ ulint len) /* in: length or UNIV_SQL_NULL */
+{
+ ut_ad(field);
+#ifdef UNIV_VALGRIND_DEBUG
+ if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(field->data, len);
+#endif /* UNIV_VALGRIND_DEBUG */
+
+ field->ext = 0;
+ field->len = len;
+}
+
+/*************************************************************************
+Determines if a field is SQL NULL */
+UNIV_INLINE
+ulint
+dfield_is_null(
+/*===========*/
+ /* out: nonzero if SQL null data */
+ const dfield_t* field) /* in: field */
+{
+ ut_ad(field);
+
+ return(field->len == UNIV_SQL_NULL);
+}
+
+/*************************************************************************
+Determines if a field is externally stored */
+UNIV_INLINE
+ulint
+dfield_is_ext(
+/*==========*/
+ /* out: nonzero if externally stored */
+ const dfield_t* field) /* in: field */
+{
+ ut_ad(field);
+
+ return(UNIV_UNLIKELY(field->ext));
+}
+
+/*************************************************************************
+Sets the "external storage" flag */
+UNIV_INLINE
+void
+dfield_set_ext(
+/*===========*/
+ dfield_t* field) /* in/out: field */
+{
+ ut_ad(field);
+
+ field->ext = 1;
+}
+
+/*************************************************************************
+Sets pointer to the data and length in a field. */
+UNIV_INLINE
+void
+dfield_set_data(
+/*============*/
+ dfield_t* field, /* in: field */
+ const void* data, /* in: data */
+ ulint len) /* in: length or UNIV_SQL_NULL */
+{
+ ut_ad(field);
+
+#ifdef UNIV_VALGRIND_DEBUG
+ if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
+#endif /* UNIV_VALGRIND_DEBUG */
+ field->data = (void*) data;
+ field->ext = 0;
+ field->len = len;
+}
+
+/*************************************************************************
+Sets a data field to SQL NULL. */
+UNIV_INLINE
+void
+dfield_set_null(
+/*============*/
+ dfield_t* field) /* in/out: field */
+{
+ dfield_set_data(field, NULL, UNIV_SQL_NULL);
+}
+
+/*************************************************************************
+Copies the data and len fields. */
+UNIV_INLINE
+void
+dfield_copy_data(
+/*=============*/
+ dfield_t* field1, /* out: field to copy to */
+ const dfield_t* field2) /* in: field to copy from */
+{
+ ut_ad(field1 && field2);
+
+ field1->data = field2->data;
+ field1->len = field2->len;
+ field1->ext = field2->ext;
+}
+
+/*************************************************************************
+Copies a data field to another. */
+UNIV_INLINE
+void
+dfield_copy(
+/*========*/
+ dfield_t* field1, /* out: field to copy to */
+ const dfield_t* field2) /* in: field to copy from */
+{
+ *field1 = *field2;
+}
+
+/*************************************************************************
+Copies the data pointed to by a data field. */
+UNIV_INLINE
+void
+dfield_dup(
+/*=======*/
+ dfield_t* field, /* in/out: data field */
+ mem_heap_t* heap) /* in: memory heap where allocated */
+{
+ if (!dfield_is_null(field)) {
+ UNIV_MEM_ASSERT_RW(field->data, field->len);
+ field->data = mem_heap_dup(heap, field->data, field->len);
+ }
+}
+
+/*************************************************************************
+Tests if data length and content is equal for two dfields. */
+UNIV_INLINE
+ibool
+dfield_datas_are_binary_equal(
+/*==========================*/
+ /* out: TRUE if equal */
+ const dfield_t* field1, /* in: field */
+ const dfield_t* field2) /* in: field */
+{
+ ulint len;
+
+ len = field1->len;
+
+ return(len == field2->len
+ && (len == UNIV_SQL_NULL
+ || !memcmp(field1->data, field2->data, len)));
+}
+
+/*************************************************************************
+Gets info bits in a data tuple. */
+UNIV_INLINE
+ulint
+dtuple_get_info_bits(
+/*=================*/
+ /* out: info bits */
+ const dtuple_t* tuple) /* in: tuple */
+{
+ ut_ad(tuple);
+
+ return(tuple->info_bits);
+}
+
+/*************************************************************************
+Sets info bits in a data tuple. */
+UNIV_INLINE
+void
+dtuple_set_info_bits(
+/*=================*/
+ dtuple_t* tuple, /* in: tuple */
+ ulint info_bits) /* in: info bits */
+{
+ ut_ad(tuple);
+
+ tuple->info_bits = info_bits;
+}
+
+/*************************************************************************
+Gets number of fields used in record comparisons. */
+UNIV_INLINE
+ulint
+dtuple_get_n_fields_cmp(
+/*====================*/
+ /* out: number of fields used in comparisons
+ in rem0cmp.* */
+ const dtuple_t* tuple) /* in: tuple */
+{
+ ut_ad(tuple);
+
+ return(tuple->n_fields_cmp);
+}
+
+/*************************************************************************
+Sets number of fields used in record comparisons. */
+UNIV_INLINE
+void
+dtuple_set_n_fields_cmp(
+/*====================*/
+ dtuple_t* tuple, /* in: tuple */
+ ulint n_fields_cmp) /* in: number of fields used in
+ comparisons in rem0cmp.* */
+{
+ ut_ad(tuple);
+ ut_ad(n_fields_cmp <= tuple->n_fields);
+
+ tuple->n_fields_cmp = n_fields_cmp;
+}
+
+/*************************************************************************
+Gets number of fields in a data tuple. */
+UNIV_INLINE
+ulint
+dtuple_get_n_fields(
+/*================*/
+ /* out: number of fields */
+ const dtuple_t* tuple) /* in: tuple */
+{
+ ut_ad(tuple);
+
+ return(tuple->n_fields);
+}
+
+#ifdef UNIV_DEBUG
+/*************************************************************************
+Gets nth field of a tuple. */
+UNIV_INLINE
+dfield_t*
+dtuple_get_nth_field(
+/*=================*/
+ /* out: nth field */
+ const dtuple_t* tuple, /* in: tuple */
+ ulint n) /* in: index of field */
+{
+ ut_ad(tuple);
+ ut_ad(n < tuple->n_fields);
+
+ return((dfield_t*) tuple->fields + n);
+}
+#endif /* UNIV_DEBUG */
+
+/**************************************************************
+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. */
+UNIV_INLINE
+dtuple_t*
+dtuple_create(
+/*==========*/
+ /* out, own: created tuple */
+ mem_heap_t* heap, /* in: memory heap where the tuple
+ is created */
+ ulint n_fields) /* in: number of fields */
+{
+ dtuple_t* tuple;
+
+ ut_ad(heap);
+
+ tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t)
+ + n_fields * sizeof(dfield_t));
+ tuple->info_bits = 0;
+ tuple->n_fields = n_fields;
+ tuple->n_fields_cmp = n_fields;
+ tuple->fields = (dfield_t*) &tuple[1];
+
+#ifdef UNIV_DEBUG
+ tuple->magic_n = DATA_TUPLE_MAGIC_N;
+
+ { /* In the debug version, initialize fields to an error value */
+ ulint i;
+
+ for (i = 0; i < n_fields; i++) {
+ dfield_t* field;
+
+ field = dtuple_get_nth_field(tuple, i);
+
+ dfield_set_len(field, UNIV_SQL_NULL);
+ field->data = &data_error;
+ dfield_get_type(field)->mtype = DATA_ERROR;
+ }
+ }
+
+ UNIV_MEM_INVALID(tuple->fields, n_fields * sizeof *tuple->fields);
+#endif
+ return(tuple);
+}
+
+/**************************************************************
+Wrap data fields in a tuple. The default value for number
+of fields used in record comparisons for this tuple is n_fields. */
+UNIV_INLINE
+const dtuple_t*
+dtuple_from_fields(
+/*===============*/
+ /* out: data tuple */
+ dtuple_t* tuple, /* in: storage for data tuple */
+ const dfield_t* fields, /* in: fields */
+ ulint n_fields) /* in: number of fields */
+{
+ tuple->info_bits = 0;
+ tuple->n_fields = tuple->n_fields_cmp = n_fields;
+ tuple->fields = (dfield_t*) fields;
+ ut_d(tuple->magic_n = DATA_TUPLE_MAGIC_N);
+
+ return(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. */
+UNIV_INLINE
+dtuple_t*
+dtuple_copy(
+/*========*/
+ /* out, own: copy of tuple */
+ const dtuple_t* tuple, /* in: tuple to copy from */
+ mem_heap_t* heap) /* in: memory heap
+ where the tuple is created */
+{
+ ulint n_fields = dtuple_get_n_fields(tuple);
+ dtuple_t* new_tuple = dtuple_create(heap, n_fields);
+ ulint i;
+
+ for (i = 0; i < n_fields; i++) {
+ dfield_copy(dtuple_get_nth_field(new_tuple, i),
+ dtuple_get_nth_field(tuple, i));
+ }
+
+ return(new_tuple);
+}
+
+/**************************************************************
+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. Neither
+is possible space in externally stored parts of the field. */
+UNIV_INLINE
+ulint
+dtuple_get_data_size(
+/*=================*/
+ /* out: sum of data lengths */
+ const dtuple_t* tuple) /* in: typed data tuple */
+{
+ const dfield_t* field;
+ ulint n_fields;
+ ulint len;
+ ulint i;
+ ulint sum = 0;
+
+ ut_ad(tuple);
+ ut_ad(dtuple_check_typed(tuple));
+ ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
+
+ n_fields = tuple->n_fields;
+
+ for (i = 0; i < n_fields; i++) {
+ field = dtuple_get_nth_field(tuple, i);
+ len = dfield_get_len(field);
+
+ if (len == UNIV_SQL_NULL) {
+ len = dtype_get_sql_null_size(dfield_get_type(field));
+ }
+
+ sum += len;
+ }
+
+ return(sum);
+}
+
+/*************************************************************************
+Computes the number of externally stored fields in a data tuple. */
+UNIV_INLINE
+ulint
+dtuple_get_n_ext(
+/*=============*/
+ /* out: number of externally stored fields */
+ const dtuple_t* tuple) /* in: tuple */
+{
+ ulint n_ext = 0;
+ ulint n_fields = tuple->n_fields;
+ ulint i;
+
+ ut_ad(tuple);
+ ut_ad(dtuple_check_typed(tuple));
+ ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
+
+ for (i = 0; i < n_fields; i++) {
+ n_ext += dtuple_get_nth_field(tuple, i)->ext;
+ }
+
+ return(n_ext);
+}
+
+/***********************************************************************
+Sets types of fields binary in a tuple. */
+UNIV_INLINE
+void
+dtuple_set_types_binary(
+/*====================*/
+ dtuple_t* tuple, /* in: data tuple */
+ ulint n) /* in: number of fields to set */
+{
+ dtype_t* dfield_type;
+ ulint i;
+
+ for (i = 0; i < n; i++) {
+ dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
+ dtype_set(dfield_type, DATA_BINARY, 0, 0);
+ }
+}
+
+/****************************************************************
+Folds a prefix given as the number of fields of a tuple. */
+UNIV_INLINE
+ulint
+dtuple_fold(
+/*========*/
+ /* out: the folded value */
+ 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 */
+ dulint tree_id)/* in: index tree id */
+{
+ const dfield_t* field;
+ ulint i;
+ const byte* data;
+ ulint len;
+ ulint fold;
+
+ ut_ad(tuple);
+ ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
+ ut_ad(dtuple_check_typed(tuple));
+
+ fold = ut_fold_dulint(tree_id);
+
+ for (i = 0; i < n_fields; i++) {
+ field = dtuple_get_nth_field(tuple, i);
+
+ data = (const byte*) dfield_get_data(field);
+ len = dfield_get_len(field);
+
+ if (len != UNIV_SQL_NULL) {
+ fold = ut_fold_ulint_pair(fold,
+ ut_fold_binary(data, len));
+ }
+ }
+
+ if (n_bytes > 0) {
+ field = dtuple_get_nth_field(tuple, i);
+
+ data = (const byte*) dfield_get_data(field);
+ len = dfield_get_len(field);
+
+ if (len != UNIV_SQL_NULL) {
+ if (len > n_bytes) {
+ len = n_bytes;
+ }
+
+ fold = ut_fold_ulint_pair(fold,
+ ut_fold_binary(data, len));
+ }
+ }
+
+ return(fold);
+}
+
+/**************************************************************************
+Writes an SQL null field full of zeros. */
+UNIV_INLINE
+void
+data_write_sql_null(
+/*================*/
+ byte* data, /* in: pointer to a buffer of size len */
+ ulint len) /* in: SQL null size in bytes */
+{
+ memset(data, 0, len);
+}
+
+/**************************************************************************
+Checks if a dtuple contains an SQL null value. */
+UNIV_INLINE
+ibool
+dtuple_contains_null(
+/*=================*/
+ /* out: TRUE if some field is SQL null */
+ const dtuple_t* tuple) /* in: dtuple */
+{
+ ulint n;
+ ulint i;
+
+ n = dtuple_get_n_fields(tuple);
+
+ for (i = 0; i < n; i++) {
+ if (dfield_is_null(dtuple_get_nth_field(tuple, i))) {
+
+ return(TRUE);
+ }
+ }
+
+ return(FALSE);
+}
+
+/******************************************************************
+Frees the memory in a big rec vector. */
+UNIV_INLINE
+void
+dtuple_big_rec_free(
+/*================*/
+ big_rec_t* vector) /* in, own: big rec vector; it is
+ freed in this function */
+{
+ mem_heap_free(vector->heap);
+}