1
/************************************************************************
2
SQL data field and tuple
4
(c) 1994-1996 Innobase Oy
6
Created 5/30/1994 Heikki Tuuri
7
*************************************************************************/
13
extern byte data_error;
15
/*************************************************************************
16
Gets pointer to the type struct of SQL data field. */
21
/* out: pointer to the type struct */
22
const dfield_t* field) /* in: SQL data field */
26
return((dtype_t*) &(field->type));
28
#endif /* UNIV_DEBUG */
30
/*************************************************************************
31
Sets the type struct of SQL data field. */
36
dfield_t* field, /* in: SQL data field */
37
dtype_t* type) /* in: pointer to data type struct */
45
/*************************************************************************
46
Gets pointer to the data in a field. */
51
/* out: pointer to data */
52
const dfield_t* field) /* in: field */
55
ut_ad((field->len == UNIV_SQL_NULL)
56
|| (field->data != &data_error));
58
return((void*) field->data);
60
#endif /* UNIV_DEBUG */
62
/*************************************************************************
63
Gets length of field data. */
68
/* out: length of data; UNIV_SQL_NULL if
70
const dfield_t* field) /* in: field */
73
ut_ad((field->len == UNIV_SQL_NULL)
74
|| (field->data != &data_error));
79
/*************************************************************************
80
Sets length in a field. */
85
dfield_t* field, /* in: field */
86
ulint len) /* in: length or UNIV_SQL_NULL */
89
#ifdef UNIV_VALGRIND_DEBUG
90
if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(field->data, len);
91
#endif /* UNIV_VALGRIND_DEBUG */
97
/*************************************************************************
98
Determines if a field is SQL NULL */
103
/* out: nonzero if SQL null data */
104
const dfield_t* field) /* in: field */
108
return(field->len == UNIV_SQL_NULL);
111
/*************************************************************************
112
Determines if a field is externally stored */
117
/* out: nonzero if externally stored */
118
const dfield_t* field) /* in: field */
122
return(UNIV_UNLIKELY(field->ext));
125
/*************************************************************************
126
Sets the "external storage" flag */
131
dfield_t* field) /* in/out: field */
138
/*************************************************************************
139
Sets pointer to the data and length in a field. */
144
dfield_t* field, /* in: field */
145
const void* data, /* in: data */
146
ulint len) /* in: length or UNIV_SQL_NULL */
150
#ifdef UNIV_VALGRIND_DEBUG
151
if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
152
#endif /* UNIV_VALGRIND_DEBUG */
153
field->data = (void*) data;
158
/*************************************************************************
159
Sets a data field to SQL NULL. */
164
dfield_t* field) /* in/out: field */
166
dfield_set_data(field, NULL, UNIV_SQL_NULL);
169
/*************************************************************************
170
Copies the data and len fields. */
175
dfield_t* field1, /* out: field to copy to */
176
const dfield_t* field2) /* in: field to copy from */
178
ut_ad(field1 && field2);
180
field1->data = field2->data;
181
field1->len = field2->len;
182
field1->ext = field2->ext;
185
/*************************************************************************
186
Copies a data field to another. */
191
dfield_t* field1, /* out: field to copy to */
192
const dfield_t* field2) /* in: field to copy from */
197
/*************************************************************************
198
Copies the data pointed to by a data field. */
203
dfield_t* field, /* in/out: data field */
204
mem_heap_t* heap) /* in: memory heap where allocated */
206
if (!dfield_is_null(field)) {
207
UNIV_MEM_ASSERT_RW(field->data, field->len);
208
field->data = mem_heap_dup(heap, field->data, field->len);
212
/*************************************************************************
213
Tests if data length and content is equal for two dfields. */
216
dfield_datas_are_binary_equal(
217
/*==========================*/
218
/* out: TRUE if equal */
219
const dfield_t* field1, /* in: field */
220
const dfield_t* field2) /* in: field */
226
return(len == field2->len
227
&& (len == UNIV_SQL_NULL
228
|| !memcmp(field1->data, field2->data, len)));
231
/*************************************************************************
232
Gets info bits in a data tuple. */
235
dtuple_get_info_bits(
236
/*=================*/
238
const dtuple_t* tuple) /* in: tuple */
242
return(tuple->info_bits);
245
/*************************************************************************
246
Sets info bits in a data tuple. */
249
dtuple_set_info_bits(
250
/*=================*/
251
dtuple_t* tuple, /* in: tuple */
252
ulint info_bits) /* in: info bits */
256
tuple->info_bits = info_bits;
259
/*************************************************************************
260
Gets number of fields used in record comparisons. */
263
dtuple_get_n_fields_cmp(
264
/*====================*/
265
/* out: number of fields used in comparisons
267
const dtuple_t* tuple) /* in: tuple */
271
return(tuple->n_fields_cmp);
274
/*************************************************************************
275
Sets number of fields used in record comparisons. */
278
dtuple_set_n_fields_cmp(
279
/*====================*/
280
dtuple_t* tuple, /* in: tuple */
281
ulint n_fields_cmp) /* in: number of fields used in
282
comparisons in rem0cmp.* */
285
ut_ad(n_fields_cmp <= tuple->n_fields);
287
tuple->n_fields_cmp = n_fields_cmp;
290
/*************************************************************************
291
Gets number of fields in a data tuple. */
296
/* out: number of fields */
297
const dtuple_t* tuple) /* in: tuple */
301
return(tuple->n_fields);
305
/*************************************************************************
306
Gets nth field of a tuple. */
309
dtuple_get_nth_field(
310
/*=================*/
312
const dtuple_t* tuple, /* in: tuple */
313
ulint n) /* in: index of field */
316
ut_ad(n < tuple->n_fields);
318
return((dfield_t*) tuple->fields + n);
320
#endif /* UNIV_DEBUG */
322
/**************************************************************
323
Creates a data tuple to a memory heap. The default value for number
324
of fields used in record comparisons for this tuple is n_fields. */
329
/* out, own: created tuple */
330
mem_heap_t* heap, /* in: memory heap where the tuple
332
ulint n_fields) /* in: number of fields */
338
tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t)
339
+ n_fields * sizeof(dfield_t));
340
tuple->info_bits = 0;
341
tuple->n_fields = n_fields;
342
tuple->n_fields_cmp = n_fields;
343
tuple->fields = (dfield_t*) &tuple[1];
346
tuple->magic_n = DATA_TUPLE_MAGIC_N;
348
{ /* In the debug version, initialize fields to an error value */
351
for (i = 0; i < n_fields; i++) {
354
field = dtuple_get_nth_field(tuple, i);
356
dfield_set_len(field, UNIV_SQL_NULL);
357
field->data = &data_error;
358
dfield_get_type(field)->mtype = DATA_ERROR;
362
UNIV_MEM_INVALID(tuple->fields, n_fields * sizeof *tuple->fields);
367
/**************************************************************
368
Wrap data fields in a tuple. The default value for number
369
of fields used in record comparisons for this tuple is n_fields. */
374
/* out: data tuple */
375
dtuple_t* tuple, /* in: storage for data tuple */
376
const dfield_t* fields, /* in: fields */
377
ulint n_fields) /* in: number of fields */
379
tuple->info_bits = 0;
380
tuple->n_fields = tuple->n_fields_cmp = n_fields;
381
tuple->fields = (dfield_t*) fields;
382
ut_d(tuple->magic_n = DATA_TUPLE_MAGIC_N);
387
/*************************************************************************
388
Copies a data tuple to another. This is a shallow copy; if a deep copy
389
is desired, dfield_dup() will have to be invoked on each field. */
394
/* out, own: copy of tuple */
395
const dtuple_t* tuple, /* in: tuple to copy from */
396
mem_heap_t* heap) /* in: memory heap
397
where the tuple is created */
399
ulint n_fields = dtuple_get_n_fields(tuple);
400
dtuple_t* new_tuple = dtuple_create(heap, n_fields);
403
for (i = 0; i < n_fields; i++) {
404
dfield_copy(dtuple_get_nth_field(new_tuple, i),
405
dtuple_get_nth_field(tuple, i));
411
/**************************************************************
412
The following function returns the sum of data lengths of a tuple. The space
413
occupied by the field structs or the tuple struct is not counted. Neither
414
is possible space in externally stored parts of the field. */
417
dtuple_get_data_size(
418
/*=================*/
419
/* out: sum of data lengths */
420
const dtuple_t* tuple) /* in: typed data tuple */
422
const dfield_t* field;
429
ut_ad(dtuple_check_typed(tuple));
430
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
432
n_fields = tuple->n_fields;
434
for (i = 0; i < n_fields; i++) {
435
field = dtuple_get_nth_field(tuple, i);
436
len = dfield_get_len(field);
438
if (len == UNIV_SQL_NULL) {
439
len = dtype_get_sql_null_size(dfield_get_type(field));
448
/*************************************************************************
449
Computes the number of externally stored fields in a data tuple. */
454
/* out: number of externally stored fields */
455
const dtuple_t* tuple) /* in: tuple */
458
ulint n_fields = tuple->n_fields;
462
ut_ad(dtuple_check_typed(tuple));
463
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
465
for (i = 0; i < n_fields; i++) {
466
n_ext += dtuple_get_nth_field(tuple, i)->ext;
472
/***********************************************************************
473
Sets types of fields binary in a tuple. */
476
dtuple_set_types_binary(
477
/*====================*/
478
dtuple_t* tuple, /* in: data tuple */
479
ulint n) /* in: number of fields to set */
481
dtype_t* dfield_type;
484
for (i = 0; i < n; i++) {
485
dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
486
dtype_set(dfield_type, DATA_BINARY, 0, 0);
490
/****************************************************************
491
Folds a prefix given as the number of fields of a tuple. */
496
/* out: the folded value */
497
const dtuple_t* tuple, /* in: the tuple */
498
ulint n_fields,/* in: number of complete fields to fold */
499
ulint n_bytes,/* in: number of bytes to fold in an
500
incomplete last field */
501
dulint tree_id)/* in: index tree id */
503
const dfield_t* field;
510
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
511
ut_ad(dtuple_check_typed(tuple));
513
fold = ut_fold_dulint(tree_id);
515
for (i = 0; i < n_fields; i++) {
516
field = dtuple_get_nth_field(tuple, i);
518
data = (const byte*) dfield_get_data(field);
519
len = dfield_get_len(field);
521
if (len != UNIV_SQL_NULL) {
522
fold = ut_fold_ulint_pair(fold,
523
ut_fold_binary(data, len));
528
field = dtuple_get_nth_field(tuple, i);
530
data = (const byte*) dfield_get_data(field);
531
len = dfield_get_len(field);
533
if (len != UNIV_SQL_NULL) {
538
fold = ut_fold_ulint_pair(fold,
539
ut_fold_binary(data, len));
546
/**************************************************************************
547
Writes an SQL null field full of zeros. */
552
byte* data, /* in: pointer to a buffer of size len */
553
ulint len) /* in: SQL null size in bytes */
555
memset(data, 0, len);
558
/**************************************************************************
559
Checks if a dtuple contains an SQL null value. */
562
dtuple_contains_null(
563
/*=================*/
564
/* out: TRUE if some field is SQL null */
565
const dtuple_t* tuple) /* in: dtuple */
570
n = dtuple_get_n_fields(tuple);
572
for (i = 0; i < n; i++) {
573
if (dfield_is_null(dtuple_get_nth_field(tuple, i))) {
582
/******************************************************************
583
Frees the memory in a big rec vector. */
588
big_rec_t* vector) /* in, own: big rec vector; it is
589
freed in this function */
591
mem_heap_free(vector->heap);