~percona-dev/percona-innodb-plugin/percona-innodb-1.0

« back to all changes in this revision

Viewing changes to include/data0data.ic

  • Committer: Vadim Tkachenko
  • Date: 2008-12-01 02:05:57 UTC
  • Revision ID: vadim@percona.com-20081201020557-p7k2m94mjtdg1a83
New rw-locks

Show diffs side-by-side

added added

removed removed

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