1
/************************************************************************
2
SQL data field and tuple
4
(c) 1994-1996 Innobase Oy
6
Created 5/30/1994 Heikki Tuuri
7
*************************************************************************/
12
#include "data0data.ic"
18
byte data_error; /* data pointers of tuple fields are initialized
19
to point here for error checking */
21
ulint data_dummy; /* this is used to fool the compiler in
24
byte data_buf[8192]; /* used in generating test tuples */
25
ulint data_rnd = 756511;
28
/* Some non-inlined functions used in the MySQL interface: */
30
dfield_set_data_noninline(
31
dfield_t* field, /* in: field */
32
void* data, /* in: data */
33
ulint len) /* in: length or UNIV_SQL_NULL */
35
dfield_set_data(field, data, len);
38
dfield_get_data_noninline(
39
dfield_t* field) /* in: field */
41
return(dfield_get_data(field));
44
dfield_get_len_noninline(
45
dfield_t* field) /* in: field */
47
return(dfield_get_len(field));
50
dtuple_get_n_fields_noninline(
51
dtuple_t* tuple) /* in: tuple */
53
return(dtuple_get_n_fields(tuple));
56
dtuple_get_nth_field_noninline(
57
dtuple_t* tuple, /* in: tuple */
58
ulint n) /* in: index of field */
60
return(dtuple_get_nth_field(tuple, n));
63
/*************************************************************************
64
Creates a dtuple for use in MySQL. */
67
dtuple_create_for_mysql(
68
/*====================*/
69
/* out, own created dtuple */
70
void** heap, /* out: created memory heap */
71
ulint n_fields) /* in: number of fields */
73
*heap = (void*)mem_heap_create(500);
75
return(dtuple_create(*((mem_heap_t**)heap), n_fields));
78
/*************************************************************************
79
Frees a dtuple used in MySQL. */
82
dtuple_free_for_mysql(
83
/*==================*/
84
void* heap) /* in: memory heap where tuple was created */
86
mem_heap_free((mem_heap_t*)heap);
89
/*************************************************************************
90
Sets number of fields used in a tuple. Normally this is set in
91
dtuple_create, but if you want later to set it smaller, you can use this. */
96
dtuple_t* tuple, /* in: tuple */
97
ulint n_fields) /* in: number of fields */
101
tuple->n_fields = n_fields;
102
tuple->n_fields_cmp = n_fields;
105
/**************************************************************
106
Checks that a data field is typed. Asserts an error if not. */
111
/* out: TRUE if ok */
112
dfield_t* field) /* in: data field */
114
ut_a(dfield_get_type(field)->mtype <= DATA_SYS);
115
ut_a(dfield_get_type(field)->mtype >= DATA_VARCHAR);
120
/**************************************************************
121
Checks that a data tuple is typed. Asserts an error if not. */
126
/* out: TRUE if ok */
127
dtuple_t* tuple) /* in: tuple */
132
for (i = 0; i < dtuple_get_n_fields(tuple); i++) {
134
field = dtuple_get_nth_field(tuple, i);
136
ut_a(dfield_check_typed(field));
142
/**************************************************************
143
Validates the consistency of a tuple which must be complete, i.e,
144
all fields must have been set. */
149
/* out: TRUE if ok */
150
dtuple_t* tuple) /* in: tuple */
158
ulint sum = 0; /* A dummy variable used
159
to prevent the compiler
160
from erasing the loop below */
161
ut_a(tuple->magic_n = DATA_TUPLE_MAGIC_N);
163
n_fields = dtuple_get_n_fields(tuple);
165
/* We dereference all the data of each field to test
168
for (i = 0; i < n_fields; i++) {
170
field = dtuple_get_nth_field(tuple, i);
171
len = dfield_get_len(field);
173
if (len != UNIV_SQL_NULL) {
177
for (j = 0; j < len; j++) {
179
data_dummy += *data; /* fool the compiler not
187
ut_a(dtuple_check_typed(tuple));
192
/*****************************************************************
193
Pretty prints a dfield value according to its data type. */
198
dfield_t* dfield) /* in: dfield */
205
len = dfield_get_len(dfield);
206
data = dfield_get_data(dfield);
208
if (len == UNIV_SQL_NULL) {
214
mtype = dtype_get_mtype(dfield_get_type(dfield));
216
if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) {
218
for (i = 0; i < len; i++) {
220
if (isprint((char)(*data))) {
221
printf("%c", (char)*data);
228
} else if (mtype == DATA_INT) {
229
ut_a(len == 4); /* only works for 32-bit integers */
230
printf("%li", (int)mach_read_from_4(data));
236
/*****************************************************************
237
Pretty prints a dfield value according to its data type. Also the hex string
238
is printed if a string contains non-printable characters. */
241
dfield_print_also_hex(
242
/*==================*/
243
dfield_t* dfield) /* in: dfield */
249
ibool print_also_hex;
251
len = dfield_get_len(dfield);
252
data = dfield_get_data(dfield);
254
if (len == UNIV_SQL_NULL) {
260
mtype = dtype_get_mtype(dfield_get_type(dfield));
262
if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) {
264
print_also_hex = FALSE;
266
for (i = 0; i < len; i++) {
268
if (isprint((char)(*data))) {
269
printf("%c", (char)*data);
271
print_also_hex = TRUE;
278
if (!print_also_hex) {
285
data = dfield_get_data(dfield);
287
for (i = 0; i < len; i++) {
288
printf("%02x", (ulint)*data);
292
} else if (mtype == DATA_INT) {
293
ut_a(len == 4); /* inly works for 32-bit integers */
294
printf("%li", (int)mach_read_from_4(data));
300
/**************************************************************
301
The following function prints the contents of a tuple. */
306
dtuple_t* tuple) /* in: tuple */
312
n_fields = dtuple_get_n_fields(tuple);
314
printf("DATA TUPLE: %lu fields;\n", n_fields);
316
for (i = 0; i < n_fields; i++) {
319
field = dtuple_get_nth_field(tuple, i);
321
if (field->len != UNIV_SQL_NULL) {
322
ut_print_buf(field->data, field->len);
332
dtuple_validate(tuple);
335
/**************************************************************
336
The following function prints the contents of a tuple to a buffer. */
341
/* out: printed length in bytes */
342
char* buf, /* in: print buffer */
343
ulint buf_len,/* in: buf length in bytes */
344
dtuple_t* tuple) /* in: tuple */
353
n_fields = dtuple_get_n_fields(tuple);
355
for (i = 0; i < n_fields; i++) {
356
if (len + 30 > buf_len) {
361
len += sprintf(buf + len, " %lu:", i);
363
field = dtuple_get_nth_field(tuple, i);
365
if (field->len != UNIV_SQL_NULL) {
366
if (5 * field->len + len + 30 > buf_len) {
371
len += ut_sprintf_buf(buf + len, field->data,
374
len += sprintf(buf + len, " SQL NULL");
377
len += sprintf(buf + len, ";");
383
/******************************************************************
384
Generates random numbers, where 10/16 is uniformly
385
distributed between 0 and n1, 5/16 between 0 and n2,
386
and 1/16 between 0 and n3. */
389
dtuple_gen_rnd_ulint(
390
/*=================*/
391
/* out: random ulint */
399
m = ut_rnd_gen_ulint() % 16;
409
m = ut_rnd_gen_ulint();
414
/***************************************************************
415
Generates a random tuple. */
418
dtuple_gen_rnd_tuple(
419
/*=================*/
420
/* out: pointer to the tuple */
421
mem_heap_t* heap) /* in: memory heap where generated */
431
n_fields = dtuple_gen_rnd_ulint(5, 30, 300) + 1;
433
tuple = dtuple_create(heap, n_fields);
435
for (i = 0; i < n_fields; i++) {
438
len = dtuple_gen_rnd_ulint(5, 30, 400);
440
len = dtuple_gen_rnd_ulint(7, 5, 17);
443
field = dtuple_get_nth_field(tuple, i);
446
dfield_set_data(field, NULL, UNIV_SQL_NULL);
448
ptr = mem_heap_alloc(heap, len);
449
dfield_set_data(field, ptr, len - 1);
451
for (j = 0; j < len; j++) {
453
dtuple_gen_rnd_ulint(22, 22, 22));
458
dtype_set(dfield_get_type(field), DATA_VARCHAR,
459
DATA_ENGLISH, 500, 0);
462
ut_a(dtuple_validate(tuple));
467
/*******************************************************************
468
Generates a test tuple for sort and comparison tests. */
471
dtuple_gen_test_tuple(
472
/*==================*/
473
dtuple_t* tuple, /* in/out: a tuple with 3 fields */
474
ulint i) /* in: a number < 512 */
481
for (j = 0; j < 3; j++) {
484
data = ""; len = 0; break;
486
data = "A"; len = 1; break;
488
data = "AA"; len = 2; break;
490
data = "AB"; len = 2; break;
492
data = "B"; len = 1; break;
494
data = "BA"; len = 2; break;
496
data = "BB"; len = 2; break;
498
len = UNIV_SQL_NULL; break;
501
field = dtuple_get_nth_field(tuple, 2 - j);
503
dfield_set_data(field, data, len);
504
dtype_set(dfield_get_type(field), DATA_VARCHAR,
505
DATA_ENGLISH, 100, 0);
510
ut_ad(dtuple_validate(tuple));
513
/*******************************************************************
514
Generates a test tuple for B-tree speed tests. */
517
dtuple_gen_test_tuple3(
518
/*===================*/
519
dtuple_t* tuple, /* in/out: a tuple with >= 3 fields */
520
ulint i, /* in: a number < 1000000 */
521
ulint type, /* in: DTUPLE_TEST_FIXED30, ... */
522
byte* buf) /* in: a buffer of size >= 16 bytes */
530
field = dtuple_get_nth_field(tuple, 0);
532
ut_strcpy((char*)buf, "0000000");
534
buf[1] = (byte)('0' + (i / 100000) % 10);
535
buf[2] = (byte)('0' + (i / 10000) % 10);
536
buf[3] = (byte)('0' + (i / 1000) % 10);
537
buf[4] = (byte)('0' + (i / 100) % 10);
538
buf[5] = (byte)('0' + (i / 10) % 10);
539
buf[6] = (byte)('0' + (i % 10));
541
dfield_set_data(field, buf, 8);
542
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
544
field = dtuple_get_nth_field(tuple, 1);
546
i = i % 1000; /* ut_rnd_gen_ulint() % 1000000; */
548
ut_strcpy((char*)buf + 8, "0000000");
550
buf[9] = (byte)('0' + (i / 100000) % 10);
551
buf[10] = (byte)('0' + (i / 10000) % 10);
552
buf[11] = (byte)('0' + (i / 1000) % 10);
553
buf[12] = (byte)('0' + (i / 100) % 10);
554
buf[13] = (byte)('0' + (i / 10) % 10);
555
buf[14] = (byte)('0' + (i % 10));
557
dfield_set_data(field, buf + 8, 8);
558
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
560
field = dtuple_get_nth_field(tuple, 2);
564
if (type == DTUPLE_TEST_FIXED30) {
566
} else if (type == DTUPLE_TEST_RND30) {
567
third_size = data_rnd % 30;
568
} else if (type == DTUPLE_TEST_RND3500) {
569
third_size = data_rnd % 3500;
570
} else if (type == DTUPLE_TEST_FIXED2000) {
572
} else if (type == DTUPLE_TEST_FIXED3) {
578
if (type == DTUPLE_TEST_FIXED30) {
579
dfield_set_data(field,
580
"12345678901234567890123456789", third_size);
582
dfield_set_data(field, data_buf, third_size);
585
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
587
ut_ad(dtuple_validate(tuple));
590
/*******************************************************************
591
Generates a test tuple for B-tree speed tests. */
594
dtuple_gen_search_tuple3(
595
/*=====================*/
596
dtuple_t* tuple, /* in/out: a tuple with 1 or 2 fields */
597
ulint i, /* in: a number < 1000000 */
598
byte* buf) /* in: a buffer of size >= 16 bytes */
605
field = dtuple_get_nth_field(tuple, 0);
607
ut_strcpy((char*)buf, "0000000");
609
buf[1] = (byte)('0' + (i / 100000) % 10);
610
buf[2] = (byte)('0' + (i / 10000) % 10);
611
buf[3] = (byte)('0' + (i / 1000) % 10);
612
buf[4] = (byte)('0' + (i / 100) % 10);
613
buf[5] = (byte)('0' + (i / 10) % 10);
614
buf[6] = (byte)('0' + (i % 10));
616
dfield_set_data(field, buf, 8);
617
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
619
if (dtuple_get_n_fields(tuple) == 1) {
624
field = dtuple_get_nth_field(tuple, 1);
626
i = (i * 1000) % 1000000;
628
ut_strcpy((char*)buf + 8, "0000000");
630
buf[9] = (byte)('0' + (i / 100000) % 10);
631
buf[10] = (byte)('0' + (i / 10000) % 10);
632
buf[11] = (byte)('0' + (i / 1000) % 10);
633
buf[12] = (byte)('0' + (i / 100) % 10);
634
buf[13] = (byte)('0' + (i / 10) % 10);
635
buf[14] = (byte)('0' + (i % 10));
637
dfield_set_data(field, buf + 8, 8);
638
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
640
ut_ad(dtuple_validate(tuple));
643
/*******************************************************************
644
Generates a test tuple for TPC-A speed test. */
647
dtuple_gen_test_tuple_TPC_A(
648
/*========================*/
649
dtuple_t* tuple, /* in/out: a tuple with >= 3 fields */
650
ulint i, /* in: a number < 10000 */
651
byte* buf) /* in: a buffer of size >= 16 bytes */
659
field = dtuple_get_nth_field(tuple, 0);
661
ut_strcpy((char*)buf, "0000");
663
buf[0] = (byte)('0' + (i / 1000) % 10);
664
buf[1] = (byte)('0' + (i / 100) % 10);
665
buf[2] = (byte)('0' + (i / 10) % 10);
666
buf[3] = (byte)('0' + (i % 10));
668
dfield_set_data(field, buf, 5);
669
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
671
field = dtuple_get_nth_field(tuple, 1);
673
dfield_set_data(field, buf + 8, 5);
674
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
676
field = dtuple_get_nth_field(tuple, 2);
680
dfield_set_data(field, data_buf, third_size);
681
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
683
ut_ad(dtuple_validate(tuple));
686
/*******************************************************************
687
Generates a test tuple for B-tree speed tests. */
690
dtuple_gen_search_tuple_TPC_A(
691
/*==========================*/
692
dtuple_t* tuple, /* in/out: a tuple with 1 field */
693
ulint i, /* in: a number < 10000 */
694
byte* buf) /* in: a buffer of size >= 16 bytes */
701
field = dtuple_get_nth_field(tuple, 0);
703
ut_strcpy((char*)buf, "0000");
705
buf[0] = (byte)('0' + (i / 1000) % 10);
706
buf[1] = (byte)('0' + (i / 100) % 10);
707
buf[2] = (byte)('0' + (i / 10) % 10);
708
buf[3] = (byte)('0' + (i % 10));
710
dfield_set_data(field, buf, 5);
711
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
713
ut_ad(dtuple_validate(tuple));
716
/*******************************************************************
717
Generates a test tuple for TPC-C speed test. */
720
dtuple_gen_test_tuple_TPC_C(
721
/*========================*/
722
dtuple_t* tuple, /* in/out: a tuple with >= 12 fields */
723
ulint i, /* in: a number < 100000 */
724
byte* buf) /* in: a buffer of size >= 16 bytes */
733
field = dtuple_get_nth_field(tuple, 0);
735
buf[0] = (byte)('0' + (i / 10000) % 10);
736
buf[1] = (byte)('0' + (i / 1000) % 10);
737
buf[2] = (byte)('0' + (i / 100) % 10);
738
buf[3] = (byte)('0' + (i / 10) % 10);
739
buf[4] = (byte)('0' + (i % 10));
741
dfield_set_data(field, buf, 5);
742
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
744
field = dtuple_get_nth_field(tuple, 1);
746
dfield_set_data(field, buf, 5);
747
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
749
for (j = 0; j < 10; j++) {
751
field = dtuple_get_nth_field(tuple, 2 + j);
755
dfield_set_data(field, data_buf, size);
756
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH,
760
ut_ad(dtuple_validate(tuple));
763
/*******************************************************************
764
Generates a test tuple for B-tree speed tests. */
767
dtuple_gen_search_tuple_TPC_C(
768
/*==========================*/
769
dtuple_t* tuple, /* in/out: a tuple with 1 field */
770
ulint i, /* in: a number < 100000 */
771
byte* buf) /* in: a buffer of size >= 16 bytes */
778
field = dtuple_get_nth_field(tuple, 0);
780
buf[0] = (byte)('0' + (i / 10000) % 10);
781
buf[1] = (byte)('0' + (i / 1000) % 10);
782
buf[2] = (byte)('0' + (i / 100) % 10);
783
buf[3] = (byte)('0' + (i / 10) % 10);
784
buf[4] = (byte)('0' + (i % 10));
786
dfield_set_data(field, buf, 5);
787
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
789
ut_ad(dtuple_validate(tuple));