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, "%llu", (ullint) id);
426
id = mach_read_from_7(data);
427
fprintf(stderr, "%llu", (ullint) id);
430
id = mach_read_from_8(data);
431
fprintf(stderr, "%llu", (ullint) id);
439
switch (prtype & DATA_SYS_PRTYPE_MASK) {
441
id = mach_read_from_6(data);
443
fprintf(stderr, "trx_id " TRX_ID_FMT, id);
447
id = mach_read_from_7(data);
449
fprintf(stderr, "roll_ptr " TRX_ID_FMT, id);
453
id = mach_read_from_6(data);
455
fprintf(stderr, "row_id " TRX_ID_FMT, id);
459
id = mach_ull_read_compressed(data);
461
fprintf(stderr, "mix_id " TRX_ID_FMT, id);
467
print_also_hex = FALSE;
469
for (i = 0; i < len; i++) {
473
print_also_hex = TRUE;
475
fprintf(stderr, "\\x%02x", (unsigned char) c);
481
if (dfield_is_ext(dfield)) {
482
fputs("(external)", stderr);
485
if (!print_also_hex) {
489
data = dfield_get_data(dfield);
495
fputs(" Hex: ",stderr);
497
for (i = 0; i < len; i++) {
498
fprintf(stderr, "%02lx", (ulint) *data++);
501
if (dfield_is_ext(dfield)) {
502
fputs("(external)", stderr);
507
/*************************************************************//**
508
Print a dfield value using ut_print_buf. */
513
FILE* f, /*!< in: output stream */
514
const dfield_t* dfield) /*!< in: dfield */
516
ulint len = dfield_get_len(dfield);
517
if (!dfield_is_null(dfield)) {
518
ulint print_len = ut_min(len, 1000);
519
ut_print_buf(f, dfield_get_data(dfield), print_len);
520
if (len != print_len) {
521
fprintf(f, "(total %lu bytes%s)",
523
dfield_is_ext(dfield) ? ", external" : "");
526
fputs(" SQL NULL", f);
530
/**********************************************************//**
531
The following function prints the contents of a tuple. */
536
FILE* f, /*!< in: output stream */
537
const dtuple_t* tuple) /*!< in: tuple */
542
n_fields = dtuple_get_n_fields(tuple);
544
fprintf(f, "DATA TUPLE: %lu fields;\n", (ulong) n_fields);
546
for (i = 0; i < n_fields; i++) {
547
fprintf(f, " %lu:", (ulong) i);
549
dfield_print_raw(f, dtuple_get_nth_field(tuple, i));
555
ut_ad(dtuple_validate(tuple));
558
/**************************************************************//**
559
Moves parts of long fields in entry to the big record vector so that
560
the size of tuple drops below the maximum record size allowed in the
561
database. Moves data only from those fields which are not necessary
562
to determine uniquely the insertion place of the tuple in the index.
563
@return own: created big record vector, NULL if we are not able to
564
shorten the entry enough, i.e., if there are too many fixed-length or
565
short fields in entry or the index is clustered */
568
dtuple_convert_big_rec(
569
/*===================*/
570
dict_index_t* index, /*!< in: index */
571
dtuple_t* entry, /*!< in/out: index entry */
572
ulint* n_ext) /*!< in/out: number of
573
externally stored columns */
578
dict_field_t* ifield;
582
ulint local_prefix_len;
584
if (UNIV_UNLIKELY(!dict_index_is_clust(index))) {
588
if (dict_table_get_format(index->table) < DICT_TF_FORMAT_ZIP) {
589
/* up to MySQL 5.1: store a 768-byte prefix locally */
590
local_len = BTR_EXTERN_FIELD_REF_SIZE + DICT_MAX_INDEX_COL_LEN;
592
/* new-format table: do not store any BLOB prefix locally */
593
local_len = BTR_EXTERN_FIELD_REF_SIZE;
596
ut_a(dtuple_check_typed_no_assert(entry));
598
size = rec_get_converted_size(index, entry, *n_ext);
600
if (UNIV_UNLIKELY(size > 1000000000)) {
602
"InnoDB: Warning: tuple size very big: %lu\n",
604
fputs("InnoDB: Tuple contents: ", stderr);
605
dtuple_print(stderr, entry);
609
heap = mem_heap_create(size + dtuple_get_n_fields(entry)
610
* sizeof(big_rec_field_t) + 1000);
612
vector = mem_heap_alloc(heap, sizeof(big_rec_t));
615
vector->fields = mem_heap_alloc(heap, dtuple_get_n_fields(entry)
616
* sizeof(big_rec_field_t));
618
/* Decide which fields to shorten: the algorithm is to look for
619
a variable-length field that yields the biggest savings when
624
while (page_zip_rec_needs_ext(rec_get_converted_size(index, entry,
626
dict_table_is_comp(index->table),
627
dict_index_get_n_fields(index),
628
dict_table_zip_size(index->table))) {
631
ulint longest_i = ULINT_MAX;
635
for (i = dict_index_get_n_unique_in_tree(index);
636
i < dtuple_get_n_fields(entry); i++) {
639
dfield = dtuple_get_nth_field(entry, i);
640
ifield = dict_index_get_nth_field(index, i);
642
/* Skip fixed-length, NULL, externally stored,
645
if (ifield->fixed_len
646
|| dfield_is_null(dfield)
647
|| dfield_is_ext(dfield)
648
|| dfield_get_len(dfield) <= local_len
649
|| dfield_get_len(dfield)
650
<= BTR_EXTERN_FIELD_REF_SIZE * 2) {
654
savings = dfield_get_len(dfield) - local_len;
656
/* Check that there would be savings */
657
if (longest >= savings) {
661
/* In DYNAMIC and COMPRESSED format, store
662
locally any non-BLOB columns whose maximum
663
length does not exceed 256 bytes. This is
664
because there is no room for the "external
665
storage" flag when the maximum length is 255
666
bytes or less. This restriction trivially
667
holds in REDUNDANT and COMPACT format, because
668
there we always store locally columns whose
669
length is up to local_len == 788 bytes.
670
@see rec_init_offsets_comp_ordinary */
671
if (ifield->col->mtype != DATA_BLOB
672
&& ifield->col->len < 256) {
676
/* In DYNAMIC and COMPRESSED format, store
677
locally any non-BLOB columns whose maximum
678
length does not exceed 256 bytes. This is
679
because there is no room for the "external
680
storage" flag when the maximum length is 255
681
bytes or less. This restriction trivially
682
holds in REDUNDANT and COMPACT format, because
683
there we always store locally columns whose
684
length is up to local_len == 788 bytes.
685
@see rec_init_offsets_comp_ordinary */
686
if (ifield->col->mtype != DATA_BLOB
687
&& ifield->col->len < 256) {
691
/* In DYNAMIC and COMPRESSED format, store
692
locally any non-BLOB columns whose maximum
693
length does not exceed 256 bytes. This is
694
because there is no room for the "external
695
storage" flag when the maximum length is 255
696
bytes or less. This restriction trivially
697
holds in REDUNDANT and COMPACT format, because
698
there we always store locally columns whose
699
length is up to local_len == 788 bytes.
700
@see rec_init_offsets_comp_ordinary */
701
if (ifield->col->mtype != DATA_BLOB
702
&& ifield->col->len < 256) {
714
/* Cannot shorten more */
721
/* Move data from field longest_i to big rec vector.
723
We store the first bytes locally to the record. Then
724
we can calculate all ordering fields in all indexes
725
from locally stored data. */
727
dfield = dtuple_get_nth_field(entry, longest_i);
728
ifield = dict_index_get_nth_field(index, longest_i);
729
local_prefix_len = local_len - BTR_EXTERN_FIELD_REF_SIZE;
731
b = &vector->fields[n_fields];
732
b->field_no = longest_i;
733
b->len = dfield_get_len(dfield) - local_prefix_len;
734
b->data = (char*) dfield_get_data(dfield) + local_prefix_len;
736
/* Allocate the locally stored part of the column. */
737
data = mem_heap_alloc(heap, local_len);
739
/* Copy the local prefix. */
740
memcpy(data, dfield_get_data(dfield), local_prefix_len);
741
/* Clear the extern field reference (BLOB pointer). */
742
memset(data + local_prefix_len, 0, BTR_EXTERN_FIELD_REF_SIZE);
744
/* The following would fail the Valgrind checks in
745
page_cur_insert_rec_low() and page_cur_insert_rec_zip().
746
The BLOB pointers in the record will be initialized after
747
the record and the BLOBs have been written. */
748
UNIV_MEM_ALLOC(data + local_prefix_len,
749
BTR_EXTERN_FIELD_REF_SIZE);
752
dfield_set_data(dfield, data, local_len);
753
dfield_set_ext(dfield);
757
ut_ad(n_fields < dtuple_get_n_fields(entry));
760
vector->n_fields = n_fields;
764
/**************************************************************//**
765
Puts back to entry the data stored in vector. Note that to ensure the
766
fields in entry can accommodate the data, vector must have been created
767
from entry with dtuple_convert_big_rec. */
770
dtuple_convert_back_big_rec(
771
/*========================*/
772
dict_index_t* index __attribute__((unused)), /*!< in: index */
773
dtuple_t* entry, /*!< in: entry whose data was put to vector */
774
big_rec_t* vector) /*!< in, own: big rec vector; it is
775
freed in this function */
777
big_rec_field_t* b = vector->fields;
778
const big_rec_field_t* const end = b + vector->n_fields;
780
for (; b < end; b++) {
784
dfield = dtuple_get_nth_field(entry, b->field_no);
785
local_len = dfield_get_len(dfield);
787
ut_ad(dfield_is_ext(dfield));
788
ut_ad(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
790
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
792
ut_ad(local_len <= DICT_MAX_INDEX_COL_LEN);
794
dfield_set_data(dfield,
795
(char*) b->data - local_len,
799
mem_heap_free(vector->heap);
801
#endif /* !UNIV_HOTBACKUP */