~stewart/haildb/trunk

« back to all changes in this revision

Viewing changes to include/data0data.ic

  • Committer: Stewart Smith
  • Date: 2010-04-09 07:57:43 UTC
  • Revision ID: stewart@flamingspork.com-20100409075743-jfh1oml3el1uouvh
Embedded InnoDB 1.0.0 released

2009-04-21      The InnoDB Team

        Embedded InnoDB 1.0.0 released

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
 
4
 
 
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.
 
8
 
 
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.
 
12
 
 
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
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/************************************************************************
 
20
SQL data field and tuple
 
21
 
 
22
Created 5/30/1994 Heikki Tuuri
 
23
*************************************************************************/
 
24
 
 
25
#include "mem0mem.h"
 
26
#include "ut0rnd.h"
 
27
 
 
28
#ifdef UNIV_DEBUG
 
29
extern byte data_error;
 
30
 
 
31
/*************************************************************************
 
32
Gets pointer to the type struct of SQL data field. */
 
33
UNIV_INLINE
 
34
dtype_t*
 
35
dfield_get_type(
 
36
/*============*/
 
37
                                /* out: pointer to the type struct */
 
38
        const dfield_t* field)  /* in: SQL data field */
 
39
{
 
40
        ut_ad(field);
 
41
 
 
42
        return((dtype_t*) &(field->type));
 
43
}
 
44
#endif /* UNIV_DEBUG */
 
45
 
 
46
/*************************************************************************
 
47
Sets the type struct of SQL data field. */
 
48
UNIV_INLINE
 
49
void
 
50
dfield_set_type(
 
51
/*============*/
 
52
        dfield_t*       field,  /* in: SQL data field */
 
53
        dtype_t*        type)   /* in: pointer to data type struct */
 
54
{
 
55
        ut_ad(field && type);
 
56
 
 
57
        field->type = *type;
 
58
}
 
59
 
 
60
#ifdef UNIV_DEBUG
 
61
/*************************************************************************
 
62
Gets pointer to the data in a field. */
 
63
UNIV_INLINE
 
64
void*
 
65
dfield_get_data(
 
66
/*============*/
 
67
                                /* out: pointer to data */
 
68
        const dfield_t* field)  /* in: field */
 
69
{
 
70
        ut_ad(field);
 
71
        ut_ad((field->len == UNIV_SQL_NULL)
 
72
              || (field->data != &data_error));
 
73
 
 
74
        return((void*) field->data);
 
75
}
 
76
#endif /* UNIV_DEBUG */
 
77
 
 
78
/*************************************************************************
 
79
Gets length of field data. */
 
80
UNIV_INLINE
 
81
ulint
 
82
dfield_get_len(
 
83
/*===========*/
 
84
                                /* out: length of data; UNIV_SQL_NULL if
 
85
                                SQL null data */
 
86
        const dfield_t* field)  /* in: field */
 
87
{
 
88
        ut_ad(field);
 
89
        ut_ad((field->len == UNIV_SQL_NULL)
 
90
              || (field->data != &data_error));
 
91
 
 
92
        return(field->len);
 
93
}
 
94
 
 
95
/*************************************************************************
 
96
Sets length in a field. */
 
97
UNIV_INLINE
 
98
void
 
99
dfield_set_len(
 
100
/*===========*/
 
101
        dfield_t*       field,  /* in: field */
 
102
        ulint           len)    /* in: length or UNIV_SQL_NULL */
 
103
{
 
104
        ut_ad(field);
 
105
#ifdef UNIV_VALGRIND_DEBUG
 
106
        if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(field->data, len);
 
107
#endif /* UNIV_VALGRIND_DEBUG */
 
108
 
 
109
        field->ext = 0;
 
110
        field->len = len;
 
111
}
 
112
 
 
113
/*************************************************************************
 
114
Determines if a field is SQL NULL */
 
115
UNIV_INLINE
 
116
ulint
 
117
dfield_is_null(
 
118
/*===========*/
 
119
                                /* out: nonzero if SQL null data */
 
120
        const dfield_t* field)  /* in: field */
 
121
{
 
122
        ut_ad(field);
 
123
 
 
124
        return(field->len == UNIV_SQL_NULL);
 
125
}
 
126
 
 
127
/*************************************************************************
 
128
Determines if a field is externally stored */
 
129
UNIV_INLINE
 
130
ulint
 
131
dfield_is_ext(
 
132
/*==========*/
 
133
                                /* out: nonzero if externally stored */
 
134
        const dfield_t* field)  /* in: field */
 
135
{
 
136
        ut_ad(field);
 
137
 
 
138
        return(UNIV_UNLIKELY(field->ext));
 
139
}
 
140
 
 
141
/*************************************************************************
 
142
Sets the "external storage" flag */
 
143
UNIV_INLINE
 
144
void
 
145
dfield_set_ext(
 
146
/*===========*/
 
147
        dfield_t*       field)  /* in/out: field */
 
148
{
 
149
        ut_ad(field);
 
150
 
 
151
        field->ext = 1;
 
152
}
 
153
 
 
154
/*************************************************************************
 
155
Sets pointer to the data and length in a field. */
 
156
UNIV_INLINE
 
157
void
 
158
dfield_set_data(
 
159
/*============*/
 
160
        dfield_t*       field,  /* in: field */
 
161
        const void*     data,   /* in: data */
 
162
        ulint           len)    /* in: length or UNIV_SQL_NULL */
 
163
{
 
164
        ut_ad(field);
 
165
 
 
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;
 
170
        field->ext = 0;
 
171
        field->len = len;
 
172
}
 
173
 
 
174
/*************************************************************************
 
175
Sets a data field to SQL NULL. */
 
176
UNIV_INLINE
 
177
void
 
178
dfield_set_null(
 
179
/*============*/
 
180
        dfield_t*       field)  /* in/out: field */
 
181
{
 
182
        dfield_set_data(field, NULL, UNIV_SQL_NULL);
 
183
}
 
184
 
 
185
/*************************************************************************
 
186
Copies the data and len fields. */
 
187
UNIV_INLINE
 
188
void
 
189
dfield_copy_data(
 
190
/*=============*/
 
191
        dfield_t*       field1, /* out: field to copy to */
 
192
        const dfield_t* field2) /* in: field to copy from */
 
193
{
 
194
        ut_ad(field1 && field2);
 
195
 
 
196
        field1->data = field2->data;
 
197
        field1->len = field2->len;
 
198
        field1->ext = field2->ext;
 
199
}
 
200
 
 
201
/*************************************************************************
 
202
Copies a data field to another. */
 
203
UNIV_INLINE
 
204
void
 
205
dfield_copy(
 
206
/*========*/
 
207
        dfield_t*       field1, /* out: field to copy to */
 
208
        const dfield_t* field2) /* in: field to copy from */
 
209
{
 
210
        *field1 = *field2;
 
211
}
 
212
 
 
213
/*************************************************************************
 
214
Copies the data pointed to by a data field. */
 
215
UNIV_INLINE
 
216
void
 
217
dfield_dup(
 
218
/*=======*/
 
219
        dfield_t*       field,  /* in/out: data field */
 
220
        mem_heap_t*     heap)   /* in: memory heap where allocated */
 
221
{
 
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);
 
225
        }
 
226
}
 
227
 
 
228
/*************************************************************************
 
229
Tests if data length and content is equal for two dfields. */
 
230
UNIV_INLINE
 
231
ibool
 
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 */
 
237
{
 
238
        ulint   len;
 
239
 
 
240
        len = field1->len;
 
241
 
 
242
        return(len == field2->len
 
243
               && (len == UNIV_SQL_NULL
 
244
                   || !memcmp(field1->data, field2->data, len)));
 
245
}
 
246
 
 
247
/*************************************************************************
 
248
Gets info bits in a data tuple. */
 
249
UNIV_INLINE
 
250
ulint
 
251
dtuple_get_info_bits(
 
252
/*=================*/
 
253
                                /* out: info bits */
 
254
        const dtuple_t* tuple)  /* in: tuple */
 
255
{
 
256
        ut_ad(tuple);
 
257
 
 
258
        return(tuple->info_bits);
 
259
}
 
260
 
 
261
/*************************************************************************
 
262
Sets info bits in a data tuple. */
 
263
UNIV_INLINE
 
264
void
 
265
dtuple_set_info_bits(
 
266
/*=================*/
 
267
        dtuple_t*       tuple,          /* in: tuple */
 
268
        ulint           info_bits)      /* in: info bits */
 
269
{
 
270
        ut_ad(tuple);
 
271
 
 
272
        tuple->info_bits = info_bits;
 
273
}
 
274
 
 
275
/*************************************************************************
 
276
Gets number of fields used in record comparisons. */
 
277
UNIV_INLINE
 
278
ulint
 
279
dtuple_get_n_fields_cmp(
 
280
/*====================*/
 
281
                                /* out: number of fields used in comparisons
 
282
                                in rem0cmp.* */
 
283
        const dtuple_t* tuple)  /* in: tuple */
 
284
{
 
285
        ut_ad(tuple);
 
286
 
 
287
        return(tuple->n_fields_cmp);
 
288
}
 
289
 
 
290
/*************************************************************************
 
291
Sets number of fields used in record comparisons. */
 
292
UNIV_INLINE
 
293
void
 
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.* */
 
299
{
 
300
        ut_ad(tuple);
 
301
        ut_ad(n_fields_cmp <= tuple->n_fields);
 
302
 
 
303
        tuple->n_fields_cmp = n_fields_cmp;
 
304
}
 
305
 
 
306
/*************************************************************************
 
307
Gets number of fields in a data tuple. */
 
308
UNIV_INLINE
 
309
ulint
 
310
dtuple_get_n_fields(
 
311
/*================*/
 
312
                                /* out: number of fields */
 
313
        const dtuple_t* tuple)  /* in: tuple */
 
314
{
 
315
        ut_ad(tuple);
 
316
 
 
317
        return(tuple->n_fields);
 
318
}
 
319
 
 
320
#ifdef UNIV_DEBUG
 
321
/*************************************************************************
 
322
Gets nth field of a tuple. */
 
323
UNIV_INLINE
 
324
dfield_t*
 
325
dtuple_get_nth_field(
 
326
/*=================*/
 
327
                                /* out: nth field */
 
328
        const dtuple_t* tuple,  /* in: tuple */
 
329
        ulint           n)      /* in: index of field */
 
330
{
 
331
        ut_ad(tuple);
 
332
        ut_ad(n < tuple->n_fields);
 
333
 
 
334
        return((dfield_t*) tuple->fields + n);
 
335
}
 
336
#endif /* UNIV_DEBUG */
 
337
 
 
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. */
 
341
UNIV_INLINE
 
342
dtuple_t*
 
343
dtuple_create(
 
344
/*==========*/
 
345
                                /* out, own: created tuple */
 
346
        mem_heap_t*     heap,   /* in: memory heap where the tuple
 
347
                                is created */
 
348
        ulint           n_fields) /* in: number of fields */
 
349
{
 
350
        dtuple_t*       tuple;
 
351
 
 
352
        ut_ad(heap);
 
353
 
 
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];
 
360
 
 
361
#ifdef UNIV_DEBUG
 
362
        tuple->magic_n = DATA_TUPLE_MAGIC_N;
 
363
 
 
364
        {       /* In the debug version, initialize fields to an error value */
 
365
                ulint   i;
 
366
 
 
367
                for (i = 0; i < n_fields; i++) {
 
368
                        dfield_t*       field;
 
369
 
 
370
                        field = dtuple_get_nth_field(tuple, i);
 
371
 
 
372
                        dfield_set_len(field, UNIV_SQL_NULL);
 
373
                        field->data = &data_error;
 
374
                        dfield_get_type(field)->mtype = DATA_ERROR;
 
375
                }
 
376
        }
 
377
 
 
378
        UNIV_MEM_INVALID(tuple->fields, n_fields * sizeof *tuple->fields);
 
379
#endif
 
380
        return(tuple);
 
381
}
 
382
 
 
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. */
 
386
UNIV_INLINE
 
387
const dtuple_t*
 
388
dtuple_from_fields(
 
389
/*===============*/
 
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 */
 
394
{
 
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);
 
399
 
 
400
        return(tuple);
 
401
}
 
402
 
 
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. */
 
406
UNIV_INLINE
 
407
dtuple_t*
 
408
dtuple_copy(
 
409
/*========*/
 
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 */
 
414
{
 
415
        ulint           n_fields        = dtuple_get_n_fields(tuple);
 
416
        dtuple_t*       new_tuple       = dtuple_create(heap, n_fields);
 
417
        ulint           i;
 
418
 
 
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));
 
422
        }
 
423
 
 
424
        return(new_tuple);
 
425
}
 
426
 
 
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. */
 
431
UNIV_INLINE
 
432
ulint
 
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  */
 
438
{
 
439
        const dfield_t* field;
 
440
        ulint           n_fields;
 
441
        ulint           len;
 
442
        ulint           i;
 
443
        ulint           sum     = 0;
 
444
 
 
445
        ut_ad(tuple);
 
446
        ut_ad(dtuple_check_typed(tuple));
 
447
        ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
 
448
 
 
449
        n_fields = tuple->n_fields;
 
450
 
 
451
        for (i = 0; i < n_fields; i++) {
 
452
                field = dtuple_get_nth_field(tuple,  i);
 
453
                len = dfield_get_len(field);
 
454
 
 
455
                if (len == UNIV_SQL_NULL) {
 
456
                        len = dtype_get_sql_null_size(dfield_get_type(field),
 
457
                                                      comp);
 
458
                }
 
459
 
 
460
                sum += len;
 
461
        }
 
462
 
 
463
        return(sum);
 
464
}
 
465
 
 
466
/*************************************************************************
 
467
Computes the number of externally stored fields in a data tuple. */
 
468
UNIV_INLINE
 
469
ulint
 
470
dtuple_get_n_ext(
 
471
/*=============*/
 
472
                                /* out: number of externally stored fields */
 
473
        const dtuple_t* tuple)  /* in: tuple */
 
474
{
 
475
        ulint   n_ext           = 0;
 
476
        ulint   n_fields        = tuple->n_fields;
 
477
        ulint   i;
 
478
 
 
479
        ut_ad(tuple);
 
480
        ut_ad(dtuple_check_typed(tuple));
 
481
        ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
 
482
 
 
483
        for (i = 0; i < n_fields; i++) {
 
484
                n_ext += dtuple_get_nth_field(tuple, i)->ext;
 
485
        }
 
486
 
 
487
        return(n_ext);
 
488
}
 
489
 
 
490
/***********************************************************************
 
491
Sets types of fields binary in a tuple. */
 
492
UNIV_INLINE
 
493
void
 
494
dtuple_set_types_binary(
 
495
/*====================*/
 
496
        dtuple_t*       tuple,  /* in: data tuple */
 
497
        ulint           n)      /* in: number of fields to set */
 
498
{
 
499
        dtype_t*        dfield_type;
 
500
        ulint           i;
 
501
 
 
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);
 
505
        }
 
506
}
 
507
 
 
508
/****************************************************************
 
509
Folds a prefix given as the number of fields of a tuple. */
 
510
UNIV_INLINE
 
511
ulint
 
512
dtuple_fold(
 
513
/*========*/
 
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 */
 
520
{
 
521
        const dfield_t* field;
 
522
        ulint           i;
 
523
        const byte*     data;
 
524
        ulint           len;
 
525
        ulint           fold;
 
526
 
 
527
        ut_ad(tuple);
 
528
        ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
 
529
        ut_ad(dtuple_check_typed(tuple));
 
530
 
 
531
        fold = ut_fold_dulint(tree_id);
 
532
 
 
533
        for (i = 0; i < n_fields; i++) {
 
534
                field = dtuple_get_nth_field(tuple, i);
 
535
 
 
536
                data = (const byte*) dfield_get_data(field);
 
537
                len = dfield_get_len(field);
 
538
 
 
539
                if (len != UNIV_SQL_NULL) {
 
540
                        fold = ut_fold_ulint_pair(fold,
 
541
                                                  ut_fold_binary(data, len));
 
542
                }
 
543
        }
 
544
 
 
545
        if (n_bytes > 0) {
 
546
                field = dtuple_get_nth_field(tuple, i);
 
547
 
 
548
                data = (const byte*) dfield_get_data(field);
 
549
                len = dfield_get_len(field);
 
550
 
 
551
                if (len != UNIV_SQL_NULL) {
 
552
                        if (len > n_bytes) {
 
553
                                len = n_bytes;
 
554
                        }
 
555
 
 
556
                        fold = ut_fold_ulint_pair(fold,
 
557
                                                  ut_fold_binary(data, len));
 
558
                }
 
559
        }
 
560
 
 
561
        return(fold);
 
562
}
 
563
 
 
564
/**************************************************************************
 
565
Writes an SQL null field full of zeros. */
 
566
UNIV_INLINE
 
567
void
 
568
data_write_sql_null(
 
569
/*================*/
 
570
        byte*   data,   /* in: pointer to a buffer of size len */
 
571
        ulint   len)    /* in: SQL null size in bytes */
 
572
{
 
573
        memset(data, 0, len);
 
574
}
 
575
 
 
576
/**************************************************************************
 
577
Checks if a dtuple contains an SQL null value. */
 
578
UNIV_INLINE
 
579
ibool
 
580
dtuple_contains_null(
 
581
/*=================*/
 
582
                                /* out: TRUE if some field is SQL null */
 
583
        const dtuple_t* tuple)  /* in: dtuple */
 
584
{
 
585
        ulint   n;
 
586
        ulint   i;
 
587
 
 
588
        n = dtuple_get_n_fields(tuple);
 
589
 
 
590
        for (i = 0; i < n; i++) {
 
591
                if (dfield_is_null(dtuple_get_nth_field(tuple, i))) {
 
592
 
 
593
                        return(TRUE);
 
594
                }
 
595
        }
 
596
 
 
597
        return(FALSE);
 
598
}
 
599
 
 
600
/******************************************************************
 
601
Frees the memory in a big rec vector. */
 
602
UNIV_INLINE
 
603
void
 
604
dtuple_big_rec_free(
 
605
/*================*/
 
606
        big_rec_t*      vector) /* in, own: big rec vector; it is
 
607
                                freed in this function */
 
608
{
 
609
        mem_heap_free(vector->heap);
 
610
}