diff options
Diffstat (limited to 'storage/xtradb/include/data0data.ic')
-rw-r--r-- | storage/xtradb/include/data0data.ic | 608 |
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); +} |