~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/row/row0row.c

  • Committer: Brian Aker
  • Date: 2009-02-21 00:18:15 UTC
  • Revision ID: brian@tangent.org-20090221001815-x20e8h71e984lvs1
Completion (?) of uint conversion.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1996, 2010, 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 row/row0row.c
 
1
/******************************************************
21
2
General row routines
22
3
 
 
4
(c) 1996 Innobase Oy
 
5
 
23
6
Created 4/20/1996 Heikki Tuuri
24
7
*******************************************************/
25
8
 
47
30
#include "read0read.h"
48
31
#include "ut0mem.h"
49
32
 
50
 
/*********************************************************************//**
 
33
/*************************************************************************
51
34
Gets the offset of trx id field, in bytes relative to the origin of
52
 
a clustered index record.
53
 
@return offset of DATA_TRX_ID */
 
35
a clustered index record. */
54
36
UNIV_INTERN
55
37
ulint
56
38
row_get_trx_id_offset(
57
39
/*==================*/
58
 
        const rec_t*    /*rec __attribute__((unused))*/,
59
 
                                /*!< in: record */
60
 
        dict_index_t*   index,  /*!< in: clustered index */
61
 
        const ulint*    offsets)/*!< in: rec_get_offsets(rec, index) */
 
40
                                /* out: offset of DATA_TRX_ID */
 
41
        const rec_t*    rec __attribute__((unused)),
 
42
                                /* in: record */
 
43
        dict_index_t*   index,  /* in: clustered index */
 
44
        const ulint*    offsets)/* in: rec_get_offsets(rec, index) */
62
45
{
63
46
        ulint   pos;
64
47
        ulint   offset;
76
59
        return(offset);
77
60
}
78
61
 
79
 
/*****************************************************************//**
 
62
/*********************************************************************
80
63
When an insert or purge to a table is performed, this function builds
81
 
the entry to be inserted into or purged from an index on the table.
82
 
@return index entry which should be inserted or purged, or NULL if the
83
 
externally stored columns in the clustered index record are
84
 
unavailable and ext != NULL */
 
64
the entry to be inserted into or purged from an index on the table. */
85
65
UNIV_INTERN
86
66
dtuple_t*
87
67
row_build_index_entry(
88
68
/*==================*/
89
 
        const dtuple_t* row,    /*!< in: row which should be
 
69
                                /* out: index entry which should be
 
70
                                inserted or purged, or NULL if the
 
71
                                externally stored columns in the
 
72
                                clustered index record are unavailable
 
73
                                and ext != NULL */
 
74
        const dtuple_t* row,    /* in: row which should be
90
75
                                inserted or purged */
91
 
        row_ext_t*      ext,    /*!< in: externally stored column prefixes,
 
76
        row_ext_t*      ext,    /* in: externally stored column prefixes,
92
77
                                or NULL */
93
 
        dict_index_t*   index,  /*!< in: index on the table */
94
 
        mem_heap_t*     heap)   /*!< in: memory heap from which the memory for
 
78
        dict_index_t*   index,  /* in: index on the table */
 
79
        mem_heap_t*     heap)   /* in: memory heap from which the memory for
95
80
                                the index entry is allocated */
96
81
{
97
82
        dtuple_t*       entry;
156
141
                }
157
142
 
158
143
                len = dtype_get_at_most_n_mbchars(
159
 
                        col->prtype, col->mbminmaxlen,
160
 
                        ind_field->prefix_len, len, static_cast<const char *>(dfield_get_data(dfield)));
 
144
                        col->prtype, col->mbminlen, col->mbmaxlen,
 
145
                        ind_field->prefix_len, len, dfield_get_data(dfield));
161
146
                dfield_set_len(dfield, len);
162
147
        }
163
148
 
166
151
        return(entry);
167
152
}
168
153
 
169
 
/*******************************************************************//**
 
154
/***********************************************************************
170
155
An inverse function to row_build_index_entry. Builds a row from a
171
 
record in a clustered index.
172
 
@return own: row built; see the NOTE below! */
 
156
record in a clustered index. */
173
157
UNIV_INTERN
174
158
dtuple_t*
175
159
row_build(
176
160
/*======*/
177
 
        ulint                   type,   /*!< in: ROW_COPY_POINTERS or
 
161
                                        /* out, own: row built;
 
162
                                        see the NOTE below! */
 
163
        ulint                   type,   /* in: ROW_COPY_POINTERS or
178
164
                                        ROW_COPY_DATA; the latter
179
165
                                        copies also the data fields to
180
166
                                        heap while the first only
181
167
                                        places pointers to data fields
182
168
                                        on the index page, and thus is
183
169
                                        more efficient */
184
 
        const dict_index_t*     index,  /*!< in: clustered index */
185
 
        const rec_t*            rec,    /*!< in: record in the clustered
 
170
        const dict_index_t*     index,  /* in: clustered index */
 
171
        const rec_t*            rec,    /* in: record in the clustered
186
172
                                        index; NOTE: in the case
187
173
                                        ROW_COPY_POINTERS the data
188
174
                                        fields in the row will point
191
177
                                        this record must be at least
192
178
                                        s-latched and the latch held
193
179
                                        as long as the row dtuple is used! */
194
 
        const ulint*            offsets,/*!< in: rec_get_offsets(rec,index)
 
180
        const ulint*            offsets,/* in: rec_get_offsets(rec,index)
195
181
                                        or NULL, in which case this function
196
182
                                        will invoke rec_get_offsets() */
197
183
        const dict_table_t*     col_table,
198
 
                                        /*!< in: table, to check which
 
184
                                        /* in: table, to check which
199
185
                                        externally stored columns
200
186
                                        occur in the ordering columns
201
187
                                        of an index, or NULL if
202
188
                                        index->table should be
203
189
                                        consulted instead */
204
 
        row_ext_t**             ext,    /*!< out, own: cache of
 
190
        row_ext_t**             ext,    /* out, own: cache of
205
191
                                        externally stored column
206
192
                                        prefixes, or NULL */
207
 
        mem_heap_t*             heap)   /*!< in: memory heap from which
 
193
        mem_heap_t*             heap)   /* in: memory heap from which
208
194
                                        the memory needed is allocated */
209
195
{
210
196
        dtuple_t*               row;
233
219
 
234
220
        if (type != ROW_COPY_POINTERS) {
235
221
                /* Take a copy of rec to heap */
236
 
                buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
 
222
                buf = mem_heap_alloc(heap, rec_offs_size(offsets));
237
223
                rec = rec_copy(buf, rec, offsets);
238
224
                /* Avoid a debug assertion in rec_offs_validate(). */
239
225
                rec_offs_make_valid(rec, index, (ulint*) offsets);
252
238
        n_fields = rec_offs_n_fields(offsets);
253
239
        n_ext_cols = rec_offs_n_extern(offsets);
254
240
        if (n_ext_cols) {
255
 
                ext_cols = static_cast<ulint *>(mem_heap_alloc(heap, n_ext_cols * sizeof *ext_cols));
 
241
                ext_cols = mem_heap_alloc(heap, n_ext_cols * sizeof *ext_cols);
256
242
        }
257
243
 
258
244
        for (i = j = 0; i < n_fields; i++) {
294
280
 
295
281
        ut_ad(dtuple_check_typed(row));
296
282
 
297
 
        if (!ext) {
298
 
                /* REDUNDANT and COMPACT formats store a local
299
 
                768-byte prefix of each externally stored
300
 
                column. No cache is needed. */
301
 
                ut_ad(dict_table_get_format(index->table)
302
 
                      < DICT_TF_FORMAT_ZIP);
303
 
        } else if (j) {
 
283
        if (j) {
304
284
                *ext = row_ext_create(j, ext_cols, row,
305
285
                                      dict_table_zip_size(index->table),
306
286
                                      heap);
315
295
        return(row);
316
296
}
317
297
 
318
 
/*******************************************************************//**
319
 
Converts an index record to a typed data tuple.
320
 
@return index entry built; does not set info_bits, and the data fields
321
 
in the entry will point directly to rec */
 
298
/***********************************************************************
 
299
Converts an index record to a typed data tuple. */
322
300
UNIV_INTERN
323
301
dtuple_t*
324
302
row_rec_to_index_entry_low(
325
303
/*=======================*/
326
 
        const rec_t*            rec,    /*!< in: record in the index */
327
 
        const dict_index_t*     index,  /*!< in: index */
328
 
        const ulint*            offsets,/*!< in: rec_get_offsets(rec, index) */
329
 
        ulint*                  n_ext,  /*!< out: number of externally
 
304
                                        /* out: index entry built; does not
 
305
                                        set info_bits, and the data fields in
 
306
                                        the entry will point directly to rec */
 
307
        const rec_t*            rec,    /* in: record in the index */
 
308
        const dict_index_t*     index,  /* in: index */
 
309
        const ulint*            offsets,/* in: rec_get_offsets(rec, index) */
 
310
        ulint*                  n_ext,  /* out: number of externally
330
311
                                        stored columns */
331
 
        mem_heap_t*             heap)   /*!< in: memory heap from which
 
312
        mem_heap_t*             heap)   /* in: memory heap from which
332
313
                                        the memory needed is allocated */
333
314
{
334
315
        dtuple_t*       entry;
373
354
        return(entry);
374
355
}
375
356
 
376
 
/*******************************************************************//**
 
357
/***********************************************************************
377
358
Converts an index record to a typed data tuple. NOTE that externally
378
 
stored (often big) fields are NOT copied to heap.
379
 
@return own: index entry built; see the NOTE below! */
 
359
stored (often big) fields are NOT copied to heap. */
380
360
UNIV_INTERN
381
361
dtuple_t*
382
362
row_rec_to_index_entry(
383
363
/*===================*/
384
 
        ulint                   type,   /*!< in: ROW_COPY_DATA, or
 
364
                                        /* out, own: index entry
 
365
                                        built; see the NOTE below! */
 
366
        ulint                   type,   /* in: ROW_COPY_DATA, or
385
367
                                        ROW_COPY_POINTERS: the former
386
368
                                        copies also the data fields to
387
369
                                        heap as the latter only places
388
370
                                        pointers to data fields on the
389
371
                                        index page */
390
 
        const rec_t*            rec,    /*!< in: record in the index;
 
372
        const rec_t*            rec,    /* in: record in the index;
391
373
                                        NOTE: in the case
392
374
                                        ROW_COPY_POINTERS the data
393
375
                                        fields in the row will point
396
378
                                        this record must be at least
397
379
                                        s-latched and the latch held
398
380
                                        as long as the dtuple is used! */
399
 
        const dict_index_t*     index,  /*!< in: index */
400
 
        ulint*                  offsets,/*!< in/out: rec_get_offsets(rec) */
401
 
        ulint*                  n_ext,  /*!< out: number of externally
 
381
        const dict_index_t*     index,  /* in: index */
 
382
        ulint*                  offsets,/* in/out: rec_get_offsets(rec) */
 
383
        ulint*                  n_ext,  /* out: number of externally
402
384
                                        stored columns */
403
 
        mem_heap_t*             heap)   /*!< in: memory heap from which
 
385
        mem_heap_t*             heap)   /* in: memory heap from which
404
386
                                        the memory needed is allocated */
405
387
{
406
388
        dtuple_t*       entry;
411
393
 
412
394
        if (type == ROW_COPY_DATA) {
413
395
                /* Take a copy of rec to heap */
414
 
                buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
 
396
                buf = mem_heap_alloc(heap, rec_offs_size(offsets));
415
397
                rec = rec_copy(buf, rec, offsets);
416
398
                /* Avoid a debug assertion in rec_offs_validate(). */
417
399
                rec_offs_make_valid(rec, index, offsets);
425
407
        return(entry);
426
408
}
427
409
 
428
 
/*******************************************************************//**
 
410
/***********************************************************************
429
411
Builds from a secondary index record a row reference with which we can
430
 
search the clustered index record.
431
 
@return own: row reference built; see the NOTE below! */
 
412
search the clustered index record. */
432
413
UNIV_INTERN
433
414
dtuple_t*
434
415
row_build_row_ref(
435
416
/*==============*/
436
 
        ulint           type,   /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
 
417
                                /* out, own: row reference built; see the
 
418
                                NOTE below! */
 
419
        ulint           type,   /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
437
420
                                the former copies also the data fields to
438
421
                                heap, whereas the latter only places pointers
439
422
                                to data fields on the index page */
440
 
        dict_index_t*   index,  /*!< in: secondary index */
441
 
        const rec_t*    rec,    /*!< in: record in the index;
 
423
        dict_index_t*   index,  /* in: secondary index */
 
424
        const rec_t*    rec,    /* in: record in the index;
442
425
                                NOTE: in the case ROW_COPY_POINTERS
443
426
                                the data fields in the row will point
444
427
                                directly into this record, therefore,
445
428
                                the buffer page of this record must be
446
429
                                at least s-latched and the latch held
447
430
                                as long as the row reference is used! */
448
 
        mem_heap_t*     heap)   /*!< in: memory heap from which the memory
 
431
        mem_heap_t*     heap)   /* in: memory heap from which the memory
449
432
                                needed is allocated */
450
433
{
451
434
        dict_table_t*   table;
475
458
        if (type == ROW_COPY_DATA) {
476
459
                /* Take a copy of rec to heap */
477
460
 
478
 
                buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
 
461
                buf = mem_heap_alloc(heap, rec_offs_size(offsets));
479
462
 
480
463
                rec = rec_copy(buf, rec, offsets);
481
464
                /* Avoid a debug assertion in rec_offs_validate(). */
520
503
                                dfield_set_len(dfield,
521
504
                                               dtype_get_at_most_n_mbchars(
522
505
                                                       dtype->prtype,
523
 
                                                       dtype->mbminmaxlen,
 
506
                                                       dtype->mbminlen,
 
507
                                                       dtype->mbmaxlen,
524
508
                                                       clust_col_prefix_len,
525
509
                                                       len, (char*) field));
526
510
                        }
535
519
        return(ref);
536
520
}
537
521
 
538
 
/*******************************************************************//**
 
522
/***********************************************************************
539
523
Builds from a secondary index record a row reference with which we can
540
524
search the clustered index record. */
541
525
UNIV_INTERN
542
526
void
543
527
row_build_row_ref_in_tuple(
544
528
/*=======================*/
545
 
        dtuple_t*               ref,    /*!< in/out: row reference built;
 
529
        dtuple_t*               ref,    /* in/out: row reference built;
546
530
                                        see the NOTE below! */
547
 
        const rec_t*            rec,    /*!< in: record in the index;
 
531
        const rec_t*            rec,    /* in: record in the index;
548
532
                                        NOTE: the data fields in ref
549
533
                                        will point directly into this
550
534
                                        record, therefore, the buffer
552
536
                                        least s-latched and the latch
553
537
                                        held as long as the row
554
538
                                        reference is used! */
555
 
        const dict_index_t*     index,  /*!< in: secondary index */
556
 
        ulint*                  offsets,/*!< in: rec_get_offsets(rec, index)
 
539
        const dict_index_t*     index,  /* in: secondary index */
 
540
        ulint*                  offsets,/* in: rec_get_offsets(rec, index)
557
541
                                        or NULL */
558
 
        trx_t*                  trx)    /*!< in: transaction */
 
542
        trx_t*                  trx)    /* in: transaction */
559
543
{
560
544
        const dict_index_t*     clust_index;
561
545
        dfield_t*               dfield;
634
618
                                dfield_set_len(dfield,
635
619
                                               dtype_get_at_most_n_mbchars(
636
620
                                                       dtype->prtype,
637
 
                                                       dtype->mbminmaxlen,
 
621
                                                       dtype->mbminlen,
 
622
                                                       dtype->mbmaxlen,
638
623
                                                       clust_col_prefix_len,
639
624
                                                       len, (char*) field));
640
625
                        }
647
632
        }
648
633
}
649
634
 
650
 
/***************************************************************//**
651
 
Searches the clustered index record for a row, if we have the row reference.
652
 
@return TRUE if found */
 
635
/***********************************************************************
 
636
From a row build a row reference with which we can search the clustered
 
637
index record. */
 
638
UNIV_INTERN
 
639
void
 
640
row_build_row_ref_from_row(
 
641
/*=======================*/
 
642
        dtuple_t*               ref,    /* in/out: row reference built;
 
643
                                        see the NOTE below!
 
644
                                        ref must have the right number
 
645
                                        of fields! */
 
646
        const dict_table_t*     table,  /* in: table */
 
647
        const dtuple_t*         row)    /* in: row
 
648
                                        NOTE: the data fields in ref will point
 
649
                                        directly into data of this row */
 
650
{
 
651
        const dict_index_t*     clust_index;
 
652
        ulint                   ref_len;
 
653
        ulint                   i;
 
654
 
 
655
        ut_ad(ref && table && row);
 
656
 
 
657
        clust_index = dict_table_get_first_index(table);
 
658
 
 
659
        ref_len = dict_index_get_n_unique(clust_index);
 
660
 
 
661
        ut_ad(ref_len == dtuple_get_n_fields(ref));
 
662
 
 
663
        for (i = 0; i < ref_len; i++) {
 
664
                const dict_col_t*       col;
 
665
                const dict_field_t*     field;
 
666
                dfield_t*               dfield;
 
667
                const dfield_t*         dfield2;
 
668
 
 
669
                dfield = dtuple_get_nth_field(ref, i);
 
670
 
 
671
                field = dict_index_get_nth_field(clust_index, i);
 
672
 
 
673
                col = dict_field_get_col(field);
 
674
 
 
675
                dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col));
 
676
 
 
677
                dfield_copy(dfield, dfield2);
 
678
                ut_ad(!dfield_is_ext(dfield));
 
679
 
 
680
                if (field->prefix_len > 0 && !dfield_is_null(dfield)) {
 
681
 
 
682
                        ulint   len = dfield_get_len(dfield);
 
683
 
 
684
                        len = dtype_get_at_most_n_mbchars(
 
685
                                col->prtype, col->mbminlen, col->mbmaxlen,
 
686
                                field->prefix_len,
 
687
                                len, dfield_get_data(dfield));
 
688
 
 
689
                        dfield_set_len(dfield, len);
 
690
                }
 
691
        }
 
692
 
 
693
        ut_ad(dtuple_check_typed(ref));
 
694
}
 
695
 
 
696
/*******************************************************************
 
697
Searches the clustered index record for a row, if we have the row reference. */
653
698
UNIV_INTERN
654
699
ibool
655
700
row_search_on_row_ref(
656
701
/*==================*/
657
 
        btr_pcur_t*             pcur,   /*!< out: persistent cursor, which must
 
702
                                        /* out: TRUE if found */
 
703
        btr_pcur_t*             pcur,   /* out: persistent cursor, which must
658
704
                                        be closed by the caller */
659
 
        ulint                   mode,   /*!< in: BTR_MODIFY_LEAF, ... */
660
 
        const dict_table_t*     table,  /*!< in: table */
661
 
        const dtuple_t*         ref,    /*!< in: row reference */
662
 
        mtr_t*                  mtr)    /*!< in/out: mtr */
 
705
        ulint                   mode,   /* in: BTR_MODIFY_LEAF, ... */
 
706
        const dict_table_t*     table,  /* in: table */
 
707
        const dtuple_t*         ref,    /* in: row reference */
 
708
        mtr_t*                  mtr)    /* in/out: mtr */
663
709
{
664
710
        ulint           low_match;
665
711
        rec_t*          rec;
690
736
        return(TRUE);
691
737
}
692
738
 
693
 
/*********************************************************************//**
 
739
/*************************************************************************
694
740
Fetches the clustered index record for a secondary index record. The latches
695
 
on the secondary index record are preserved.
696
 
@return record or NULL, if no record found */
 
741
on the secondary index record are preserved. */
697
742
UNIV_INTERN
698
743
rec_t*
699
744
row_get_clust_rec(
700
745
/*==============*/
701
 
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF, ... */
702
 
        const rec_t*    rec,    /*!< in: record in a secondary index */
703
 
        dict_index_t*   index,  /*!< in: secondary index */
704
 
        dict_index_t**  clust_index,/*!< out: clustered index */
705
 
        mtr_t*          mtr)    /*!< in: mtr */
 
746
                                /* out: record or NULL, if no record found */
 
747
        ulint           mode,   /* in: BTR_MODIFY_LEAF, ... */
 
748
        const rec_t*    rec,    /* in: record in a secondary index */
 
749
        dict_index_t*   index,  /* in: secondary index */
 
750
        dict_index_t**  clust_index,/* out: clustered index */
 
751
        mtr_t*          mtr)    /* in: mtr */
706
752
{
707
753
        mem_heap_t*     heap;
708
754
        dtuple_t*       ref;
732
778
        return(clust_rec);
733
779
}
734
780
 
735
 
/***************************************************************//**
736
 
Searches an index record.
737
 
@return whether the record was found or buffered */
 
781
/*******************************************************************
 
782
Searches an index record. */
738
783
UNIV_INTERN
739
 
enum row_search_result
 
784
ibool
740
785
row_search_index_entry(
741
786
/*===================*/
742
 
        dict_index_t*   index,  /*!< in: index */
743
 
        const dtuple_t* entry,  /*!< in: index entry */
744
 
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF, ... */
745
 
        btr_pcur_t*     pcur,   /*!< in/out: persistent cursor, which must
 
787
                                /* out: TRUE if found */
 
788
        dict_index_t*   index,  /* in: index */
 
789
        const dtuple_t* entry,  /* in: index entry */
 
790
        ulint           mode,   /* in: BTR_MODIFY_LEAF, ... */
 
791
        btr_pcur_t*     pcur,   /* in/out: persistent cursor, which must
746
792
                                be closed by the caller */
747
 
        mtr_t*          mtr)    /*!< in: mtr */
 
793
        mtr_t*          mtr)    /* in: mtr */
748
794
{
749
795
        ulint   n_fields;
750
796
        ulint   low_match;
753
799
        ut_ad(dtuple_check_typed(entry));
754
800
 
755
801
        btr_pcur_open(index, entry, PAGE_CUR_LE, mode, pcur, mtr);
756
 
 
757
 
        switch (btr_pcur_get_btr_cur(pcur)->flag) {
758
 
        case BTR_CUR_DELETE_REF:
759
 
                ut_a(mode & BTR_DELETE);
760
 
                return(ROW_NOT_DELETED_REF);
761
 
 
762
 
        case BTR_CUR_DEL_MARK_IBUF:
763
 
        case BTR_CUR_DELETE_IBUF:
764
 
        case BTR_CUR_INSERT_TO_IBUF:
765
 
                return(ROW_BUFFERED);
766
 
 
767
 
        case BTR_CUR_HASH:
768
 
        case BTR_CUR_HASH_FAIL:
769
 
        case BTR_CUR_BINARY:
770
 
                break;
771
 
        }
772
 
 
773
802
        low_match = btr_pcur_get_low_match(pcur);
774
803
 
775
804
        rec = btr_pcur_get_rec(pcur);
776
805
 
777
806
        n_fields = dtuple_get_n_fields(entry);
778
807
 
779
 
        if (page_rec_is_infimum(rec)) {
780
 
 
781
 
                return(ROW_NOT_FOUND);
782
 
        } else if (low_match != n_fields) {
783
 
 
784
 
                return(ROW_NOT_FOUND);
785
 
        }
786
 
 
787
 
        return(ROW_FOUND);
 
808
        return(!page_rec_is_infimum(rec) && low_match == n_fields);
788
809
}
789
810
 
790
 
#if !defined(BUILD_DRIZZLE)
791
 
# include "my_sys.h"
 
811
#ifndef UNIV_HOTBACKUP
 
812
 
 
813
#if defined(BUILD_DRIZZLE)
 
814
# include <mysys/my_sys.h>
 
815
#else
 
816
# include <my_sys.h>
792
817
#endif
793
818
 
794
 
 
795
 
/*******************************************************************//**
 
819
/***********************************************************************
796
820
Formats the raw data in "data" (in InnoDB on-disk format) that is of
797
821
type DATA_INT using "prtype" and writes the result to "buf".
798
822
If the data is in unknown format, then nothing is written to "buf",
801
825
Not more than "buf_size" bytes are written to "buf".
802
826
The result is always '\0'-terminated (provided buf_size > 0) and the
803
827
number of bytes that were written to "buf" is returned (including the
804
 
terminating '\0').
805
 
@return number of bytes that were written */
 
828
terminating '\0'). */
806
829
static
807
830
ulint
808
831
row_raw_format_int(
809
832
/*===============*/
810
 
        const char*     data,           /*!< in: raw data */
811
 
        ulint           data_len,       /*!< in: raw data length
812
 
                                        in bytes */
813
 
        ulint           prtype,         /*!< in: precise type */
814
 
        char*           buf,            /*!< out: output buffer */
815
 
        ulint           buf_size,       /*!< in: output buffer size
816
 
                                        in bytes */
817
 
        ibool*          format_in_hex)  /*!< out: should the data be
 
833
                                        /* out: number of bytes
 
834
                                        that were written */
 
835
        const char*     data,           /* in: raw data */
 
836
        ulint           data_len,       /* in: raw data length
 
837
                                        in bytes */
 
838
        ulint           prtype,         /* in: precise type */
 
839
        char*           buf,            /* out: output buffer */
 
840
        ulint           buf_size,       /* in: output buffer size
 
841
                                        in bytes */
 
842
        ibool*          format_in_hex)  /* out: should the data be
818
843
                                        formated in hex */
819
844
{
820
845
        ulint   ret;
846
871
        return(ut_min(ret, buf_size));
847
872
}
848
873
 
849
 
/*******************************************************************//**
 
874
/***********************************************************************
850
875
Formats the raw data in "data" (in InnoDB on-disk format) that is of
851
876
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "prtype" and writes the
852
877
result to "buf".
856
881
Not more than "buf_size" bytes are written to "buf".
857
882
The result is always '\0'-terminated (provided buf_size > 0) and the
858
883
number of bytes that were written to "buf" is returned (including the
859
 
terminating '\0').
860
 
@return number of bytes that were written */
 
884
terminating '\0'). */
861
885
static
862
886
ulint
863
887
row_raw_format_str(
864
888
/*===============*/
865
 
        const char*     data,           /*!< in: raw data */
866
 
        ulint           data_len,       /*!< in: raw data length
867
 
                                        in bytes */
868
 
        ulint           prtype,         /*!< in: precise type */
869
 
        char*           buf,            /*!< out: output buffer */
870
 
        ulint           buf_size,       /*!< in: output buffer size
871
 
                                        in bytes */
872
 
        ibool*          format_in_hex)  /*!< out: should the data be
 
889
                                        /* out: number of bytes
 
890
                                        that were written */
 
891
        const char*     data,           /* in: raw data */
 
892
        ulint           data_len,       /* in: raw data length
 
893
                                        in bytes */
 
894
        ulint           prtype,         /* in: precise type */
 
895
        char*           buf,            /* out: output buffer */
 
896
        ulint           buf_size,       /* in: output buffer size
 
897
                                        in bytes */
 
898
        ibool*          format_in_hex)  /* out: should the data be
873
899
                                        formated in hex */
874
900
{
875
901
        ulint   charset_coll;
900
926
                                          buf, buf_size));
901
927
}
902
928
 
903
 
/*******************************************************************//**
 
929
/***********************************************************************
904
930
Formats the raw data in "data" (in InnoDB on-disk format) using
905
931
"dict_field" and writes the result to "buf".
906
932
Not more than "buf_size" bytes are written to "buf".
907
 
The result is always NUL-terminated (provided buf_size is positive) and the
 
933
The result is always '\0'-terminated (provided buf_size > 0) and the
908
934
number of bytes that were written to "buf" is returned (including the
909
 
terminating NUL).
910
 
@return number of bytes that were written */
 
935
terminating '\0'). */
911
936
UNIV_INTERN
912
937
ulint
913
938
row_raw_format(
914
939
/*===========*/
915
 
        const char*             data,           /*!< in: raw data */
916
 
        ulint                   data_len,       /*!< in: raw data length
 
940
                                                /* out: number of bytes
 
941
                                                that were written */
 
942
        const char*             data,           /* in: raw data */
 
943
        ulint                   data_len,       /* in: raw data length
917
944
                                                in bytes */
918
 
        const dict_field_t*     dict_field,     /*!< in: index field */
919
 
        char*                   buf,            /*!< out: output buffer */
920
 
        ulint                   buf_size)       /*!< in: output buffer size
 
945
        const dict_field_t*     dict_field,     /* in: index field */
 
946
        char*                   buf,            /* out: output buffer */
 
947
        ulint                   buf_size)       /* in: output buffer size
921
948
                                                in bytes */
922
949
{
923
950
        ulint   mtype;
924
951
        ulint   prtype;
925
 
        ulint   ret= 0;
 
952
        ulint   ret;
926
953
        ibool   format_in_hex;
927
954
 
928
955
        if (buf_size == 0) {
929
956
 
930
 
                return(ret);
 
957
                return(0);
931
958
        }
932
959
 
933
960
        if (data_len == UNIV_SQL_NULL) {
947
974
 
948
975
                ret = row_raw_format_int(data, data_len, prtype,
949
976
                                         buf, buf_size, &format_in_hex);
950
 
                if (format_in_hex) {
951
 
 
952
 
                        goto format_in_hex;
953
 
                }
954
977
                break;
955
978
        case DATA_CHAR:
956
979
        case DATA_VARCHAR:
959
982
 
960
983
                ret = row_raw_format_str(data, data_len, prtype,
961
984
                                         buf, buf_size, &format_in_hex);
962
 
                if (format_in_hex) {
963
 
 
964
 
                        goto format_in_hex;
965
 
                }
966
 
 
967
985
                break;
968
986
        /* XXX support more data types */
969
987
        default:
970
 
        format_in_hex:
 
988
 
 
989
                format_in_hex = TRUE;
 
990
        }
 
991
 
 
992
        if (format_in_hex) {
971
993
 
972
994
                if (UNIV_LIKELY(buf_size > 2)) {
973
995
 
986
1008
        return(ret);
987
1009
}
988
1010
 
 
1011
#endif /* !UNIV_HOTBACKUP */
 
1012
 
989
1013
#ifdef UNIV_COMPILE_TEST_FUNCS
990
1014
 
991
1015
#include "ut0dbg.h"