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., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/********************************************************************//**
20
@file data/data0data.c
21
SQL data field and tuple
23
Created 5/30/1994 Heikki Tuuri
24
*************************************************************************/
26
#include "data0data.h"
29
#include "data0data.ic"
32
#ifndef UNIV_HOTBACKUP
35
#include "page0page.h"
37
#include "dict0dict.h"
41
#endif /* !UNIV_HOTBACKUP */
44
/** Dummy variable to catch access to uninitialized fields. In the
45
debug version, dtuple_create() will make all fields of dtuple_t point
47
UNIV_INTERN byte data_error;
49
# ifndef UNIV_DEBUG_VALGRIND
50
/** this is used to fool the compiler in dtuple_validate */
51
UNIV_INTERN ulint data_dummy;
52
# endif /* !UNIV_DEBUG_VALGRIND */
53
#endif /* UNIV_DEBUG */
55
#ifndef UNIV_HOTBACKUP
56
/*********************************************************************//**
57
Tests if dfield data length and content is equal to the given.
58
@return TRUE if equal */
61
dfield_data_is_binary_equal(
62
/*========================*/
63
const dfield_t* field, /*!< in: field */
64
ulint len, /*!< in: data length or UNIV_SQL_NULL */
65
const byte* data) /*!< in: data */
67
if (len != dfield_get_len(field)) {
72
if (len == UNIV_SQL_NULL) {
77
if (0 != memcmp(dfield_get_data(field), data, len)) {
85
/************************************************************//**
86
Compare two data tuples, respecting the collation of character fields.
87
@return 1, 0 , -1 if tuple1 is greater, equal, less, respectively,
93
const dtuple_t* tuple1, /*!< in: tuple 1 */
94
const dtuple_t* tuple2) /*!< in: tuple 2 */
99
ut_ad(tuple1 && tuple2);
100
ut_ad(tuple1->magic_n == DATA_TUPLE_MAGIC_N);
101
ut_ad(tuple2->magic_n == DATA_TUPLE_MAGIC_N);
102
ut_ad(dtuple_check_typed(tuple1));
103
ut_ad(dtuple_check_typed(tuple2));
105
n_fields = dtuple_get_n_fields(tuple1);
107
if (n_fields != dtuple_get_n_fields(tuple2)) {
109
return(n_fields < dtuple_get_n_fields(tuple2) ? -1 : 1);
112
for (i = 0; i < n_fields; i++) {
114
const dfield_t* field1 = dtuple_get_nth_field(tuple1, i);
115
const dfield_t* field2 = dtuple_get_nth_field(tuple2, i);
117
cmp = cmp_dfield_dfield(field1, field2);
127
/*********************************************************************//**
128
Sets number of fields used in a tuple. Normally this is set in
129
dtuple_create, but if you want later to set it smaller, you can use this. */
134
dtuple_t* tuple, /*!< in: tuple */
135
ulint n_fields) /*!< in: number of fields */
139
tuple->n_fields = n_fields;
140
tuple->n_fields_cmp = n_fields;
143
/**********************************************************//**
144
Checks that a data field is typed.
145
@return TRUE if ok */
148
dfield_check_typed_no_assert(
149
/*=========================*/
150
const dfield_t* field) /*!< in: data field */
152
if (dfield_get_type(field)->mtype > DATA_MYSQL
153
|| dfield_get_type(field)->mtype < DATA_VARCHAR) {
156
"InnoDB: Error: data field type %lu, len %lu\n",
157
(ulong) dfield_get_type(field)->mtype,
158
(ulong) dfield_get_len(field));
165
/**********************************************************//**
166
Checks that a data tuple is typed.
167
@return TRUE if ok */
170
dtuple_check_typed_no_assert(
171
/*=========================*/
172
const dtuple_t* tuple) /*!< in: tuple */
174
const dfield_t* field;
177
if (dtuple_get_n_fields(tuple) > REC_MAX_N_FIELDS) {
179
"InnoDB: Error: index entry has %lu fields\n",
180
(ulong) dtuple_get_n_fields(tuple));
182
fputs("InnoDB: Tuple contents: ", stderr);
183
dtuple_print(stderr, tuple);
189
for (i = 0; i < dtuple_get_n_fields(tuple); i++) {
191
field = dtuple_get_nth_field(tuple, i);
193
if (!dfield_check_typed_no_assert(field)) {
200
#endif /* !UNIV_HOTBACKUP */
203
/**********************************************************//**
204
Checks that a data field is typed. Asserts an error if not.
205
@return TRUE if ok */
210
const dfield_t* field) /*!< in: data field */
212
if (dfield_get_type(field)->mtype > DATA_MYSQL
213
|| dfield_get_type(field)->mtype < DATA_VARCHAR) {
216
"InnoDB: Error: data field type %lu, len %lu\n",
217
(ulong) dfield_get_type(field)->mtype,
218
(ulong) dfield_get_len(field));
226
/**********************************************************//**
227
Checks that a data tuple is typed. Asserts an error if not.
228
@return TRUE if ok */
233
const dtuple_t* tuple) /*!< in: tuple */
235
const dfield_t* field;
238
for (i = 0; i < dtuple_get_n_fields(tuple); i++) {
240
field = dtuple_get_nth_field(tuple, i);
242
ut_a(dfield_check_typed(field));
248
/**********************************************************//**
249
Validates the consistency of a tuple which must be complete, i.e,
250
all fields must have been set.
251
@return TRUE if ok */
256
const dtuple_t* tuple) /*!< in: tuple */
258
const dfield_t* field;
263
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
265
n_fields = dtuple_get_n_fields(tuple);
267
/* We dereference all the data of each field to test
270
for (i = 0; i < n_fields; i++) {
272
field = dtuple_get_nth_field(tuple, i);
273
len = dfield_get_len(field);
275
if (!dfield_is_null(field)) {
277
const byte* data = dfield_get_data(field);
278
#ifndef UNIV_DEBUG_VALGRIND
281
for (j = 0; j < len; j++) {
283
data_dummy += *data; /* fool the compiler not
288
#endif /* !UNIV_DEBUG_VALGRIND */
290
UNIV_MEM_ASSERT_RW(data, len);
294
ut_a(dtuple_check_typed(tuple));
298
#endif /* UNIV_DEBUG */
300
#ifndef UNIV_HOTBACKUP
301
/*************************************************************//**
302
Pretty prints a dfield value according to its data type. */
307
const dfield_t* dfield) /*!< in: dfield */
313
len = dfield_get_len(dfield);
314
data = dfield_get_data(dfield);
316
if (dfield_is_null(dfield)) {
317
fputs("NULL", stderr);
322
switch (dtype_get_mtype(dfield_get_type(dfield))) {
325
for (i = 0; i < len; i++) {
327
putc(isprint(c) ? c : ' ', stderr);
330
if (dfield_is_ext(dfield)) {
331
fputs("(external)", stderr);
335
ut_a(len == 4); /* only works for 32-bit integers */
336
fprintf(stderr, "%d", (int)mach_read_from_4(data));
343
/*************************************************************//**
344
Pretty prints a dfield value according to its data type. Also the hex string
345
is printed if a string contains non-printable characters. */
348
dfield_print_also_hex(
349
/*==================*/
350
const dfield_t* dfield) /*!< in: dfield */
356
ibool print_also_hex;
358
len = dfield_get_len(dfield);
359
data = dfield_get_data(dfield);
361
if (dfield_is_null(dfield)) {
362
fputs("NULL", stderr);
367
prtype = dtype_get_prtype(dfield_get_type(dfield));
369
switch (dtype_get_mtype(dfield_get_type(dfield))) {
375
val = mach_read_from_1(data);
377
if (!(prtype & DATA_UNSIGNED)) {
379
fprintf(stderr, "%ld", (long) val);
381
fprintf(stderr, "%lu", (ulong) val);
386
val = mach_read_from_2(data);
388
if (!(prtype & DATA_UNSIGNED)) {
390
fprintf(stderr, "%ld", (long) val);
392
fprintf(stderr, "%lu", (ulong) val);
397
val = mach_read_from_3(data);
399
if (!(prtype & DATA_UNSIGNED)) {
401
fprintf(stderr, "%ld", (long) val);
403
fprintf(stderr, "%lu", (ulong) val);
408
val = mach_read_from_4(data);
410
static const ulint UNSIGNED_MASK= 0x80000000;
412
if (!(prtype & DATA_UNSIGNED)) {
413
val &= ~UNSIGNED_MASK;
414
fprintf(stderr, "%ld", (long) val);
416
fprintf(stderr, "%lu", (ulong) val);
421
id = mach_read_from_6(data);
422
fprintf(stderr, "{%lu %lu}",
423
ut_dulint_get_high(id),
424
ut_dulint_get_low(id));
428
id = mach_read_from_7(data);
429
fprintf(stderr, "{%lu %lu}",
430
ut_dulint_get_high(id),
431
ut_dulint_get_low(id));
434
id = mach_read_from_8(data);
435
fprintf(stderr, "{%lu %lu}",
436
ut_dulint_get_high(id),
437
ut_dulint_get_low(id));
445
switch (prtype & DATA_SYS_PRTYPE_MASK) {
447
id = mach_read_from_6(data);
449
fprintf(stderr, "trx_id " TRX_ID_FMT,
450
TRX_ID_PREP_PRINTF(id));
454
id = mach_read_from_7(data);
456
fprintf(stderr, "roll_ptr {%lu %lu}",
457
ut_dulint_get_high(id), ut_dulint_get_low(id));
461
id = mach_read_from_6(data);
463
fprintf(stderr, "row_id {%lu %lu}",
464
ut_dulint_get_high(id), ut_dulint_get_low(id));
468
id = mach_dulint_read_compressed(data);
470
fprintf(stderr, "mix_id {%lu %lu}",
471
ut_dulint_get_high(id), ut_dulint_get_low(id));
477
print_also_hex = FALSE;
479
for (i = 0; i < len; i++) {
483
print_also_hex = TRUE;
485
fprintf(stderr, "\\x%02x", (unsigned char) c);
491
if (dfield_is_ext(dfield)) {
492
fputs("(external)", stderr);
495
if (!print_also_hex) {
499
data = dfield_get_data(dfield);
505
fputs(" Hex: ",stderr);
507
for (i = 0; i < len; i++) {
508
fprintf(stderr, "%02lx", (ulint) *data++);
511
if (dfield_is_ext(dfield)) {
512
fputs("(external)", stderr);
517
/*************************************************************//**
518
Print a dfield value using ut_print_buf. */
523
FILE* f, /*!< in: output stream */
524
const dfield_t* dfield) /*!< in: dfield */
526
ulint len = dfield_get_len(dfield);
527
if (!dfield_is_null(dfield)) {
528
ulint print_len = ut_min(len, 1000);
529
ut_print_buf(f, dfield_get_data(dfield), print_len);
530
if (len != print_len) {
531
fprintf(f, "(total %lu bytes%s)",
533
dfield_is_ext(dfield) ? ", external" : "");
536
fputs(" SQL NULL", f);
540
/**********************************************************//**
541
The following function prints the contents of a tuple. */
546
FILE* f, /*!< in: output stream */
547
const dtuple_t* tuple) /*!< in: tuple */
552
n_fields = dtuple_get_n_fields(tuple);
554
fprintf(f, "DATA TUPLE: %lu fields;\n", (ulong) n_fields);
556
for (i = 0; i < n_fields; i++) {
557
fprintf(f, " %lu:", (ulong) i);
559
dfield_print_raw(f, dtuple_get_nth_field(tuple, i));
565
ut_ad(dtuple_validate(tuple));
568
/**************************************************************//**
569
Moves parts of long fields in entry to the big record vector so that
570
the size of tuple drops below the maximum record size allowed in the
571
database. Moves data only from those fields which are not necessary
572
to determine uniquely the insertion place of the tuple in the index.
573
@return own: created big record vector, NULL if we are not able to
574
shorten the entry enough, i.e., if there are too many fixed-length or
575
short fields in entry or the index is clustered */
578
dtuple_convert_big_rec(
579
/*===================*/
580
dict_index_t* index, /*!< in: index */
581
dtuple_t* entry, /*!< in/out: index entry */
582
ulint* n_ext) /*!< in/out: number of
583
externally stored columns */
588
dict_field_t* ifield;
592
ulint local_prefix_len;
594
if (UNIV_UNLIKELY(!dict_index_is_clust(index))) {
598
if (dict_table_get_format(index->table) < DICT_TF_FORMAT_ZIP) {
599
/* up to MySQL 5.1: store a 768-byte prefix locally */
600
local_len = BTR_EXTERN_FIELD_REF_SIZE + DICT_MAX_INDEX_COL_LEN;
602
/* new-format table: do not store any BLOB prefix locally */
603
local_len = BTR_EXTERN_FIELD_REF_SIZE;
606
ut_a(dtuple_check_typed_no_assert(entry));
608
size = rec_get_converted_size(index, entry, *n_ext);
610
if (UNIV_UNLIKELY(size > 1000000000)) {
612
"InnoDB: Warning: tuple size very big: %lu\n",
614
fputs("InnoDB: Tuple contents: ", stderr);
615
dtuple_print(stderr, entry);
619
heap = mem_heap_create(size + dtuple_get_n_fields(entry)
620
* sizeof(big_rec_field_t) + 1000);
622
vector = mem_heap_alloc(heap, sizeof(big_rec_t));
625
vector->fields = mem_heap_alloc(heap, dtuple_get_n_fields(entry)
626
* sizeof(big_rec_field_t));
628
/* Decide which fields to shorten: the algorithm is to look for
629
a variable-length field that yields the biggest savings when
634
while (page_zip_rec_needs_ext(rec_get_converted_size(index, entry,
636
dict_table_is_comp(index->table),
637
dict_index_get_n_fields(index),
638
dict_table_zip_size(index->table))) {
641
ulint longest_i = ULINT_MAX;
645
for (i = dict_index_get_n_unique_in_tree(index);
646
i < dtuple_get_n_fields(entry); i++) {
649
dfield = dtuple_get_nth_field(entry, i);
650
ifield = dict_index_get_nth_field(index, i);
652
/* Skip fixed-length, NULL, externally stored,
655
if (ifield->fixed_len
656
|| dfield_is_null(dfield)
657
|| dfield_is_ext(dfield)
658
|| dfield_get_len(dfield) <= local_len
659
|| dfield_get_len(dfield)
660
<= BTR_EXTERN_FIELD_REF_SIZE * 2) {
664
savings = dfield_get_len(dfield) - local_len;
666
/* Check that there would be savings */
667
if (longest >= savings) {
671
/* In DYNAMIC and COMPRESSED format, store
672
locally any non-BLOB columns whose maximum
673
length does not exceed 256 bytes. This is
674
because there is no room for the "external
675
storage" flag when the maximum length is 255
676
bytes or less. This restriction trivially
677
holds in REDUNDANT and COMPACT format, because
678
there we always store locally columns whose
679
length is up to local_len == 788 bytes.
680
@see rec_init_offsets_comp_ordinary */
681
if (ifield->col->mtype != DATA_BLOB
682
&& ifield->col->len < 256) {
686
/* In DYNAMIC and COMPRESSED format, store
687
locally any non-BLOB columns whose maximum
688
length does not exceed 256 bytes. This is
689
because there is no room for the "external
690
storage" flag when the maximum length is 255
691
bytes or less. This restriction trivially
692
holds in REDUNDANT and COMPACT format, because
693
there we always store locally columns whose
694
length is up to local_len == 788 bytes.
695
@see rec_init_offsets_comp_ordinary */
696
if (ifield->col->mtype != DATA_BLOB
697
&& ifield->col->len < 256) {
709
/* Cannot shorten more */
716
/* Move data from field longest_i to big rec vector.
718
We store the first bytes locally to the record. Then
719
we can calculate all ordering fields in all indexes
720
from locally stored data. */
722
dfield = dtuple_get_nth_field(entry, longest_i);
723
ifield = dict_index_get_nth_field(index, longest_i);
724
local_prefix_len = local_len - BTR_EXTERN_FIELD_REF_SIZE;
726
b = &vector->fields[n_fields];
727
b->field_no = longest_i;
728
b->len = dfield_get_len(dfield) - local_prefix_len;
729
b->data = (char*) dfield_get_data(dfield) + local_prefix_len;
731
/* Allocate the locally stored part of the column. */
732
data = mem_heap_alloc(heap, local_len);
734
/* Copy the local prefix. */
735
memcpy(data, dfield_get_data(dfield), local_prefix_len);
736
/* Clear the extern field reference (BLOB pointer). */
737
memset(data + local_prefix_len, 0, BTR_EXTERN_FIELD_REF_SIZE);
739
/* The following would fail the Valgrind checks in
740
page_cur_insert_rec_low() and page_cur_insert_rec_zip().
741
The BLOB pointers in the record will be initialized after
742
the record and the BLOBs have been written. */
743
UNIV_MEM_ALLOC(data + local_prefix_len,
744
BTR_EXTERN_FIELD_REF_SIZE);
747
dfield_set_data(dfield, data, local_len);
748
dfield_set_ext(dfield);
752
ut_ad(n_fields < dtuple_get_n_fields(entry));
755
vector->n_fields = n_fields;
759
/**************************************************************//**
760
Puts back to entry the data stored in vector. Note that to ensure the
761
fields in entry can accommodate the data, vector must have been created
762
from entry with dtuple_convert_big_rec. */
765
dtuple_convert_back_big_rec(
766
/*========================*/
767
dict_index_t* index __attribute__((unused)), /*!< in: index */
768
dtuple_t* entry, /*!< in: entry whose data was put to vector */
769
big_rec_t* vector) /*!< in, own: big rec vector; it is
770
freed in this function */
772
big_rec_field_t* b = vector->fields;
773
const big_rec_field_t* const end = b + vector->n_fields;
775
for (; b < end; b++) {
779
dfield = dtuple_get_nth_field(entry, b->field_no);
780
local_len = dfield_get_len(dfield);
782
ut_ad(dfield_is_ext(dfield));
783
ut_ad(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
785
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
787
ut_ad(local_len <= DICT_MAX_INDEX_COL_LEN);
789
dfield_set_data(dfield,
790
(char*) b->data - local_len,
794
mem_heap_free(vector->heap);
796
#endif /* !UNIV_HOTBACKUP */