~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/include/data0data.ic

  • Committer: patrick crews
  • Date: 2010-09-29 15:15:19 UTC
  • mfrom: (1099.4.188 drizzle)
  • Revision ID: gleebix@gmail.com-20100929151519-6mrmzd1ciw2p9nws
Tags: 2010.09.1802
Update translations

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., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 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
 
        index_id_t      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_ull(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
 
}