mirror of
https://github.com/MariaDB/server.git
synced 2025-01-26 00:34:18 +01:00
8f18616ef0
and lexer files). From now on, the following Emacs cc-mode settings apply when indenting C function bodies in InnoDB: (setq c-basic-offset 8) (setq c-label-minimum-indentation 0) (add-to-list 'c-offsets-alist '(c . 0)) (add-to-list 'c-offsets-alist '(label . [0])) The indentation rules for function declarations still have not been formalized, and they must be formatted manually. Try to limit all lines to at most 79 characters (assuming TAB stops every 8 characters) by splitting lines before opening parenthesis, or at string constants. Fix some grammar mistakes in diagnostic output: match to, match with -> match found from -> found in trying rename -> trying to rename Fix an error in page_check_dir(): it said "supremum not pointed to" when the infimum was not pointed to. Enclose commented-out code snippets in #if 0 ... #endif instead of /* ... */. Add (void*) casts to some %p parameters in fprintf() calls. Try to split lines before a binary operator, not after one. (These three fixes were not made everywhere.)
436 lines
9.5 KiB
Text
436 lines
9.5 KiB
Text
/************************************************************************
|
|
SQL data field and tuple
|
|
|
|
(c) 1994-1996 Innobase Oy
|
|
|
|
Created 5/30/1994 Heikki Tuuri
|
|
*************************************************************************/
|
|
|
|
#include "mem0mem.h"
|
|
#include "ut0rnd.h"
|
|
|
|
#ifdef UNIV_DEBUG
|
|
extern byte data_error;
|
|
#endif /* UNIV_DEBUG */
|
|
|
|
/*************************************************************************
|
|
Gets pointer to the type struct of SQL data field. */
|
|
UNIV_INLINE
|
|
dtype_t*
|
|
dfield_get_type(
|
|
/*============*/
|
|
/* out: pointer to the type struct */
|
|
dfield_t* field) /* in: SQL data field */
|
|
{
|
|
ut_ad(field);
|
|
|
|
return(&(field->type));
|
|
}
|
|
|
|
/*************************************************************************
|
|
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;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Gets pointer to the data in a field. */
|
|
UNIV_INLINE
|
|
void*
|
|
dfield_get_data(
|
|
/*============*/
|
|
/* out: pointer to data */
|
|
dfield_t* field) /* in: field */
|
|
{
|
|
ut_ad(field);
|
|
ut_ad((field->len == UNIV_SQL_NULL)
|
|
|| (field->data != &data_error));
|
|
|
|
return(field->data);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Gets length of field data. */
|
|
UNIV_INLINE
|
|
ulint
|
|
dfield_get_len(
|
|
/*===========*/
|
|
/* out: length of data; UNIV_SQL_NULL if
|
|
SQL null data */
|
|
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);
|
|
|
|
field->len = len;
|
|
}
|
|
|
|
/*************************************************************************
|
|
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);
|
|
|
|
field->data = (void*) data;
|
|
field->len = len;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Copies the data and len fields. */
|
|
UNIV_INLINE
|
|
void
|
|
dfield_copy_data(
|
|
/*=============*/
|
|
dfield_t* field1, /* in: field to copy to */
|
|
dfield_t* field2) /* in: field to copy from */
|
|
{
|
|
ut_ad(field1 && field2);
|
|
|
|
field1->data = field2->data;
|
|
field1->len = field2->len;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Copies a data field to another. */
|
|
UNIV_INLINE
|
|
void
|
|
dfield_copy(
|
|
/*========*/
|
|
dfield_t* field1, /* in: field to copy to */
|
|
dfield_t* field2) /* in: field to copy from */
|
|
{
|
|
*field1 = *field2;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Tests if data length and content is equal for two dfields. */
|
|
UNIV_INLINE
|
|
ibool
|
|
dfield_datas_are_binary_equal(
|
|
/*==========================*/
|
|
/* out: TRUE if equal */
|
|
dfield_t* field1, /* in: field */
|
|
dfield_t* field2) /* in: field */
|
|
{
|
|
ulint len;
|
|
|
|
len = field1->len;
|
|
|
|
if ((len != field2->len)
|
|
|| ((len != UNIV_SQL_NULL)
|
|
&& (0 != ut_memcmp(field1->data, field2->data,
|
|
len)))) {
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Gets info bits in a data tuple. */
|
|
UNIV_INLINE
|
|
ulint
|
|
dtuple_get_info_bits(
|
|
/*=================*/
|
|
/* out: info bits */
|
|
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.* */
|
|
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 */
|
|
dtuple_t* tuple) /* in: tuple */
|
|
{
|
|
ut_ad(tuple);
|
|
|
|
return(tuple->n_fields);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Gets nth field of a tuple. */
|
|
UNIV_INLINE
|
|
dfield_t*
|
|
dtuple_get_nth_field(
|
|
/*=================*/
|
|
/* out: nth field */
|
|
dtuple_t* tuple, /* in: tuple */
|
|
ulint n) /* in: index of field */
|
|
{
|
|
ut_ad(tuple);
|
|
ut_ad(n < tuple->n_fields);
|
|
|
|
return(tuple->fields + n);
|
|
}
|
|
|
|
/**************************************************************
|
|
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*)(((byte*)tuple) + sizeof(dtuple_t));
|
|
|
|
#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++) {
|
|
(tuple->fields + i)->data = &data_error;
|
|
dfield_get_type(tuple->fields + i)->mtype = DATA_ERROR;
|
|
}
|
|
}
|
|
#endif
|
|
return(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 */
|
|
dtuple_t* tuple) /* in: typed data tuple */
|
|
{
|
|
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);
|
|
}
|
|
|
|
/***********************************************************************
|
|
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, 0);
|
|
}
|
|
}
|
|
|
|
/****************************************************************
|
|
Folds a prefix given as the number of fields of a tuple. */
|
|
UNIV_INLINE
|
|
ulint
|
|
dtuple_fold(
|
|
/*========*/
|
|
/* out: the folded value */
|
|
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 */
|
|
{
|
|
dfield_t* field;
|
|
ulint i;
|
|
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 = (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 = (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 */
|
|
{
|
|
ulint j;
|
|
|
|
for (j = 0; j < len; j++) {
|
|
data[j] = '\0';
|
|
}
|
|
}
|
|
|
|
/**************************************************************************
|
|
Checks if a dtuple contains an SQL null value. */
|
|
UNIV_INLINE
|
|
ibool
|
|
dtuple_contains_null(
|
|
/*=================*/
|
|
/* out: TRUE if some field is SQL null */
|
|
dtuple_t* tuple) /* in: dtuple */
|
|
{
|
|
ulint n;
|
|
ulint i;
|
|
|
|
n = dtuple_get_n_fields(tuple);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
if (dfield_get_len(dtuple_get_nth_field(tuple, i))
|
|
== UNIV_SQL_NULL) {
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|