~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/include/data0data.ic

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

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