1
/*****************************************************************************
3
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
*****************************************************************************/
19
/************************************************************************
20
SQL data field and tuple
22
Created 5/30/1994 Heikki Tuuri
23
*************************************************************************/
29
extern byte data_error;
31
/*************************************************************************
32
Gets pointer to the type struct of SQL data field. */
37
/* out: pointer to the type struct */
38
const dfield_t* field) /* in: SQL data field */
42
return((dtype_t*) &(field->type));
44
#endif /* UNIV_DEBUG */
46
/*************************************************************************
47
Sets the type struct of SQL data field. */
52
dfield_t* field, /* in: SQL data field */
53
dtype_t* type) /* in: pointer to data type struct */
61
/*************************************************************************
62
Gets pointer to the data in a field. */
67
/* out: pointer to data */
68
const dfield_t* field) /* in: field */
71
ut_ad((field->len == UNIV_SQL_NULL)
72
|| (field->data != &data_error));
74
return((void*) field->data);
76
#endif /* UNIV_DEBUG */
78
/*************************************************************************
79
Gets length of field data. */
84
/* out: length of data; UNIV_SQL_NULL if
86
const dfield_t* field) /* in: field */
89
ut_ad((field->len == UNIV_SQL_NULL)
90
|| (field->data != &data_error));
95
/*************************************************************************
96
Sets length in a field. */
101
dfield_t* field, /* in: field */
102
ulint len) /* in: length or UNIV_SQL_NULL */
105
#ifdef UNIV_VALGRIND_DEBUG
106
if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(field->data, len);
107
#endif /* UNIV_VALGRIND_DEBUG */
113
/*************************************************************************
114
Determines if a field is SQL NULL */
119
/* out: nonzero if SQL null data */
120
const dfield_t* field) /* in: field */
124
return(field->len == UNIV_SQL_NULL);
127
/*************************************************************************
128
Determines if a field is externally stored */
133
/* out: nonzero if externally stored */
134
const dfield_t* field) /* in: field */
138
return(UNIV_UNLIKELY(field->ext));
141
/*************************************************************************
142
Sets the "external storage" flag */
147
dfield_t* field) /* in/out: field */
154
/*************************************************************************
155
Sets pointer to the data and length in a field. */
160
dfield_t* field, /* in: field */
161
const void* data, /* in: data */
162
ulint len) /* in: length or UNIV_SQL_NULL */
166
#ifdef UNIV_VALGRIND_DEBUG
167
if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
168
#endif /* UNIV_VALGRIND_DEBUG */
169
field->data = (void*) data;
174
/*************************************************************************
175
Sets a data field to SQL NULL. */
180
dfield_t* field) /* in/out: field */
182
dfield_set_data(field, NULL, UNIV_SQL_NULL);
185
/*************************************************************************
186
Copies the data and len fields. */
191
dfield_t* field1, /* out: field to copy to */
192
const dfield_t* field2) /* in: field to copy from */
194
ut_ad(field1 && field2);
196
field1->data = field2->data;
197
field1->len = field2->len;
198
field1->ext = field2->ext;
201
/*************************************************************************
202
Copies a data field to another. */
207
dfield_t* field1, /* out: field to copy to */
208
const dfield_t* field2) /* in: field to copy from */
213
/*************************************************************************
214
Copies the data pointed to by a data field. */
219
dfield_t* field, /* in/out: data field */
220
mem_heap_t* heap) /* in: memory heap where allocated */
222
if (!dfield_is_null(field)) {
223
UNIV_MEM_ASSERT_RW(field->data, field->len);
224
field->data = mem_heap_dup(heap, field->data, field->len);
228
/*************************************************************************
229
Tests if data length and content is equal for two dfields. */
232
dfield_datas_are_binary_equal(
233
/*==========================*/
234
/* out: TRUE if equal */
235
const dfield_t* field1, /* in: field */
236
const dfield_t* field2) /* in: field */
242
return(len == field2->len
243
&& (len == UNIV_SQL_NULL
244
|| !memcmp(field1->data, field2->data, len)));
247
/*************************************************************************
248
Gets info bits in a data tuple. */
251
dtuple_get_info_bits(
252
/*=================*/
254
const dtuple_t* tuple) /* in: tuple */
258
return(tuple->info_bits);
261
/*************************************************************************
262
Sets info bits in a data tuple. */
265
dtuple_set_info_bits(
266
/*=================*/
267
dtuple_t* tuple, /* in: tuple */
268
ulint info_bits) /* in: info bits */
272
tuple->info_bits = info_bits;
275
/*************************************************************************
276
Gets number of fields used in record comparisons. */
279
dtuple_get_n_fields_cmp(
280
/*====================*/
281
/* out: number of fields used in comparisons
283
const dtuple_t* tuple) /* in: tuple */
287
return(tuple->n_fields_cmp);
290
/*************************************************************************
291
Sets number of fields used in record comparisons. */
294
dtuple_set_n_fields_cmp(
295
/*====================*/
296
dtuple_t* tuple, /* in: tuple */
297
ulint n_fields_cmp) /* in: number of fields used in
298
comparisons in rem0cmp.* */
301
ut_ad(n_fields_cmp <= tuple->n_fields);
303
tuple->n_fields_cmp = n_fields_cmp;
306
/*************************************************************************
307
Gets number of fields in a data tuple. */
312
/* out: number of fields */
313
const dtuple_t* tuple) /* in: tuple */
317
return(tuple->n_fields);
321
/*************************************************************************
322
Gets nth field of a tuple. */
325
dtuple_get_nth_field(
326
/*=================*/
328
const dtuple_t* tuple, /* in: tuple */
329
ulint n) /* in: index of field */
332
ut_ad(n < tuple->n_fields);
334
return((dfield_t*) tuple->fields + n);
336
#endif /* UNIV_DEBUG */
338
/**************************************************************
339
Creates a data tuple to a memory heap. The default value for number
340
of fields used in record comparisons for this tuple is n_fields. */
345
/* out, own: created tuple */
346
mem_heap_t* heap, /* in: memory heap where the tuple
348
ulint n_fields) /* in: number of fields */
354
tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t)
355
+ n_fields * sizeof(dfield_t));
356
tuple->info_bits = 0;
357
tuple->n_fields = n_fields;
358
tuple->n_fields_cmp = n_fields;
359
tuple->fields = (dfield_t*) &tuple[1];
362
tuple->magic_n = DATA_TUPLE_MAGIC_N;
364
{ /* In the debug version, initialize fields to an error value */
367
for (i = 0; i < n_fields; i++) {
370
field = dtuple_get_nth_field(tuple, i);
372
dfield_set_len(field, UNIV_SQL_NULL);
373
field->data = &data_error;
374
dfield_get_type(field)->mtype = DATA_ERROR;
378
UNIV_MEM_INVALID(tuple->fields, n_fields * sizeof *tuple->fields);
383
/**************************************************************
384
Wrap data fields in a tuple. The default value for number
385
of fields used in record comparisons for this tuple is n_fields. */
390
/* out: data tuple */
391
dtuple_t* tuple, /* in: storage for data tuple */
392
const dfield_t* fields, /* in: fields */
393
ulint n_fields) /* in: number of fields */
395
tuple->info_bits = 0;
396
tuple->n_fields = tuple->n_fields_cmp = n_fields;
397
tuple->fields = (dfield_t*) fields;
398
ut_d(tuple->magic_n = DATA_TUPLE_MAGIC_N);
403
/*************************************************************************
404
Copies a data tuple to another. This is a shallow copy; if a deep copy
405
is desired, dfield_dup() will have to be invoked on each field. */
410
/* out, own: copy of tuple */
411
const dtuple_t* tuple, /* in: tuple to copy from */
412
mem_heap_t* heap) /* in: memory heap
413
where the tuple is created */
415
ulint n_fields = dtuple_get_n_fields(tuple);
416
dtuple_t* new_tuple = dtuple_create(heap, n_fields);
419
for (i = 0; i < n_fields; i++) {
420
dfield_copy(dtuple_get_nth_field(new_tuple, i),
421
dtuple_get_nth_field(tuple, i));
427
/**************************************************************
428
The following function returns the sum of data lengths of a tuple. The space
429
occupied by the field structs or the tuple struct is not counted. Neither
430
is possible space in externally stored parts of the field. */
433
dtuple_get_data_size(
434
/*=================*/
435
/* out: sum of data lengths */
436
const dtuple_t* tuple, /* in: typed data tuple */
437
ulint comp) /* in: nonzero=ROW_FORMAT=COMPACT */
439
const dfield_t* field;
446
ut_ad(dtuple_check_typed(tuple));
447
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
449
n_fields = tuple->n_fields;
451
for (i = 0; i < n_fields; i++) {
452
field = dtuple_get_nth_field(tuple, i);
453
len = dfield_get_len(field);
455
if (len == UNIV_SQL_NULL) {
456
len = dtype_get_sql_null_size(dfield_get_type(field),
466
/*************************************************************************
467
Computes the number of externally stored fields in a data tuple. */
472
/* out: number of externally stored fields */
473
const dtuple_t* tuple) /* in: tuple */
476
ulint n_fields = tuple->n_fields;
480
ut_ad(dtuple_check_typed(tuple));
481
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
483
for (i = 0; i < n_fields; i++) {
484
n_ext += dtuple_get_nth_field(tuple, i)->ext;
490
/***********************************************************************
491
Sets types of fields binary in a tuple. */
494
dtuple_set_types_binary(
495
/*====================*/
496
dtuple_t* tuple, /* in: data tuple */
497
ulint n) /* in: number of fields to set */
499
dtype_t* dfield_type;
502
for (i = 0; i < n; i++) {
503
dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
504
dtype_set(dfield_type, DATA_BINARY, 0, 0);
508
/****************************************************************
509
Folds a prefix given as the number of fields of a tuple. */
514
/* out: the folded value */
515
const dtuple_t* tuple, /* in: the tuple */
516
ulint n_fields,/* in: number of complete fields to fold */
517
ulint n_bytes,/* in: number of bytes to fold in an
518
incomplete last field */
519
dulint tree_id)/* in: index tree id */
521
const dfield_t* field;
528
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
529
ut_ad(dtuple_check_typed(tuple));
531
fold = ut_fold_dulint(tree_id);
533
for (i = 0; i < n_fields; i++) {
534
field = dtuple_get_nth_field(tuple, i);
536
data = (const byte*) dfield_get_data(field);
537
len = dfield_get_len(field);
539
if (len != UNIV_SQL_NULL) {
540
fold = ut_fold_ulint_pair(fold,
541
ut_fold_binary(data, len));
546
field = dtuple_get_nth_field(tuple, i);
548
data = (const byte*) dfield_get_data(field);
549
len = dfield_get_len(field);
551
if (len != UNIV_SQL_NULL) {
556
fold = ut_fold_ulint_pair(fold,
557
ut_fold_binary(data, len));
564
/**************************************************************************
565
Writes an SQL null field full of zeros. */
570
byte* data, /* in: pointer to a buffer of size len */
571
ulint len) /* in: SQL null size in bytes */
573
memset(data, 0, len);
576
/**************************************************************************
577
Checks if a dtuple contains an SQL null value. */
580
dtuple_contains_null(
581
/*=================*/
582
/* out: TRUE if some field is SQL null */
583
const dtuple_t* tuple) /* in: dtuple */
588
n = dtuple_get_n_fields(tuple);
590
for (i = 0; i < n; i++) {
591
if (dfield_is_null(dtuple_get_nth_field(tuple, i))) {
600
/******************************************************************
601
Frees the memory in a big rec vector. */
606
big_rec_t* vector) /* in, own: big rec vector; it is
607
freed in this function */
609
mem_heap_free(vector->heap);