~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Tags: innodb-plugin-1.0.3
InnoDB Plugin 1.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
12
 
13
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
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
16
16
 
17
17
*****************************************************************************/
18
18
 
19
 
/**************************************************//**
20
 
@file row/row0row.c
 
19
/******************************************************
21
20
General row routines
22
21
 
23
22
Created 4/20/1996 Heikki Tuuri
47
46
#include "read0read.h"
48
47
#include "ut0mem.h"
49
48
 
50
 
/*********************************************************************//**
 
49
/*************************************************************************
51
50
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 */
 
51
a clustered index record. */
54
52
UNIV_INTERN
55
53
ulint
56
54
row_get_trx_id_offset(
57
55
/*==================*/
 
56
                                /* out: offset of DATA_TRX_ID */
58
57
        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) */
 
58
                                /* in: record */
 
59
        dict_index_t*   index,  /* in: clustered index */
 
60
        const ulint*    offsets)/* in: rec_get_offsets(rec, index) */
62
61
{
63
62
        ulint   pos;
64
63
        ulint   offset;
76
75
        return(offset);
77
76
}
78
77
 
79
 
/*****************************************************************//**
 
78
/*********************************************************************
80
79
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 */
 
80
the entry to be inserted into or purged from an index on the table. */
85
81
UNIV_INTERN
86
82
dtuple_t*
87
83
row_build_index_entry(
88
84
/*==================*/
89
 
        const dtuple_t* row,    /*!< in: row which should be
 
85
                                /* out: index entry which should be
 
86
                                inserted or purged, or NULL if the
 
87
                                externally stored columns in the
 
88
                                clustered index record are unavailable
 
89
                                and ext != NULL */
 
90
        const dtuple_t* row,    /* in: row which should be
90
91
                                inserted or purged */
91
 
        row_ext_t*      ext,    /*!< in: externally stored column prefixes,
 
92
        row_ext_t*      ext,    /* in: externally stored column prefixes,
92
93
                                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
 
94
        dict_index_t*   index,  /* in: index on the table */
 
95
        mem_heap_t*     heap)   /* in: memory heap from which the memory for
95
96
                                the index entry is allocated */
96
97
{
97
98
        dtuple_t*       entry;
156
157
                }
157
158
 
158
159
                len = dtype_get_at_most_n_mbchars(
159
 
                        col->prtype, col->mbminmaxlen,
 
160
                        col->prtype, col->mbminlen, col->mbmaxlen,
160
161
                        ind_field->prefix_len, len, dfield_get_data(dfield));
161
162
                dfield_set_len(dfield, len);
162
163
        }
166
167
        return(entry);
167
168
}
168
169
 
169
 
/*******************************************************************//**
 
170
/***********************************************************************
170
171
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! */
 
172
record in a clustered index. */
173
173
UNIV_INTERN
174
174
dtuple_t*
175
175
row_build(
176
176
/*======*/
177
 
        ulint                   type,   /*!< in: ROW_COPY_POINTERS or
 
177
                                        /* out, own: row built;
 
178
                                        see the NOTE below! */
 
179
        ulint                   type,   /* in: ROW_COPY_POINTERS or
178
180
                                        ROW_COPY_DATA; the latter
179
181
                                        copies also the data fields to
180
182
                                        heap while the first only
181
183
                                        places pointers to data fields
182
184
                                        on the index page, and thus is
183
185
                                        more efficient */
184
 
        const dict_index_t*     index,  /*!< in: clustered index */
185
 
        const rec_t*            rec,    /*!< in: record in the clustered
 
186
        const dict_index_t*     index,  /* in: clustered index */
 
187
        const rec_t*            rec,    /* in: record in the clustered
186
188
                                        index; NOTE: in the case
187
189
                                        ROW_COPY_POINTERS the data
188
190
                                        fields in the row will point
191
193
                                        this record must be at least
192
194
                                        s-latched and the latch held
193
195
                                        as long as the row dtuple is used! */
194
 
        const ulint*            offsets,/*!< in: rec_get_offsets(rec,index)
 
196
        const ulint*            offsets,/* in: rec_get_offsets(rec,index)
195
197
                                        or NULL, in which case this function
196
198
                                        will invoke rec_get_offsets() */
197
199
        const dict_table_t*     col_table,
198
 
                                        /*!< in: table, to check which
 
200
                                        /* in: table, to check which
199
201
                                        externally stored columns
200
202
                                        occur in the ordering columns
201
203
                                        of an index, or NULL if
202
204
                                        index->table should be
203
205
                                        consulted instead */
204
 
        row_ext_t**             ext,    /*!< out, own: cache of
 
206
        row_ext_t**             ext,    /* out, own: cache of
205
207
                                        externally stored column
206
208
                                        prefixes, or NULL */
207
 
        mem_heap_t*             heap)   /*!< in: memory heap from which
 
209
        mem_heap_t*             heap)   /* in: memory heap from which
208
210
                                        the memory needed is allocated */
209
211
{
210
212
        dtuple_t*               row;
294
296
 
295
297
        ut_ad(dtuple_check_typed(row));
296
298
 
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) {
 
299
        if (j) {
304
300
                *ext = row_ext_create(j, ext_cols, row,
305
301
                                      dict_table_zip_size(index->table),
306
302
                                      heap);
315
311
        return(row);
316
312
}
317
313
 
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 */
 
314
/***********************************************************************
 
315
Converts an index record to a typed data tuple. */
322
316
UNIV_INTERN
323
317
dtuple_t*
324
318
row_rec_to_index_entry_low(
325
319
/*=======================*/
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
 
320
                                        /* out: index entry built; does not
 
321
                                        set info_bits, and the data fields in
 
322
                                        the entry will point directly to rec */
 
323
        const rec_t*            rec,    /* in: record in the index */
 
324
        const dict_index_t*     index,  /* in: index */
 
325
        const ulint*            offsets,/* in: rec_get_offsets(rec, index) */
 
326
        ulint*                  n_ext,  /* out: number of externally
330
327
                                        stored columns */
331
 
        mem_heap_t*             heap)   /*!< in: memory heap from which
 
328
        mem_heap_t*             heap)   /* in: memory heap from which
332
329
                                        the memory needed is allocated */
333
330
{
334
331
        dtuple_t*       entry;
373
370
        return(entry);
374
371
}
375
372
 
376
 
/*******************************************************************//**
 
373
/***********************************************************************
377
374
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! */
 
375
stored (often big) fields are NOT copied to heap. */
380
376
UNIV_INTERN
381
377
dtuple_t*
382
378
row_rec_to_index_entry(
383
379
/*===================*/
384
 
        ulint                   type,   /*!< in: ROW_COPY_DATA, or
 
380
                                        /* out, own: index entry
 
381
                                        built; see the NOTE below! */
 
382
        ulint                   type,   /* in: ROW_COPY_DATA, or
385
383
                                        ROW_COPY_POINTERS: the former
386
384
                                        copies also the data fields to
387
385
                                        heap as the latter only places
388
386
                                        pointers to data fields on the
389
387
                                        index page */
390
 
        const rec_t*            rec,    /*!< in: record in the index;
 
388
        const rec_t*            rec,    /* in: record in the index;
391
389
                                        NOTE: in the case
392
390
                                        ROW_COPY_POINTERS the data
393
391
                                        fields in the row will point
396
394
                                        this record must be at least
397
395
                                        s-latched and the latch held
398
396
                                        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
 
397
        const dict_index_t*     index,  /* in: index */
 
398
        ulint*                  offsets,/* in/out: rec_get_offsets(rec) */
 
399
        ulint*                  n_ext,  /* out: number of externally
402
400
                                        stored columns */
403
 
        mem_heap_t*             heap)   /*!< in: memory heap from which
 
401
        mem_heap_t*             heap)   /* in: memory heap from which
404
402
                                        the memory needed is allocated */
405
403
{
406
404
        dtuple_t*       entry;
425
423
        return(entry);
426
424
}
427
425
 
428
 
/*******************************************************************//**
 
426
/***********************************************************************
429
427
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! */
 
428
search the clustered index record. */
432
429
UNIV_INTERN
433
430
dtuple_t*
434
431
row_build_row_ref(
435
432
/*==============*/
436
 
        ulint           type,   /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
 
433
                                /* out, own: row reference built; see the
 
434
                                NOTE below! */
 
435
        ulint           type,   /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
437
436
                                the former copies also the data fields to
438
437
                                heap, whereas the latter only places pointers
439
438
                                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;
 
439
        dict_index_t*   index,  /* in: secondary index */
 
440
        const rec_t*    rec,    /* in: record in the index;
442
441
                                NOTE: in the case ROW_COPY_POINTERS
443
442
                                the data fields in the row will point
444
443
                                directly into this record, therefore,
445
444
                                the buffer page of this record must be
446
445
                                at least s-latched and the latch held
447
446
                                as long as the row reference is used! */
448
 
        mem_heap_t*     heap)   /*!< in: memory heap from which the memory
 
447
        mem_heap_t*     heap)   /* in: memory heap from which the memory
449
448
                                needed is allocated */
450
449
{
451
450
        dict_table_t*   table;
520
519
                                dfield_set_len(dfield,
521
520
                                               dtype_get_at_most_n_mbchars(
522
521
                                                       dtype->prtype,
523
 
                                                       dtype->mbminmaxlen,
 
522
                                                       dtype->mbminlen,
 
523
                                                       dtype->mbmaxlen,
524
524
                                                       clust_col_prefix_len,
525
525
                                                       len, (char*) field));
526
526
                        }
535
535
        return(ref);
536
536
}
537
537
 
538
 
/*******************************************************************//**
 
538
/***********************************************************************
539
539
Builds from a secondary index record a row reference with which we can
540
540
search the clustered index record. */
541
541
UNIV_INTERN
542
542
void
543
543
row_build_row_ref_in_tuple(
544
544
/*=======================*/
545
 
        dtuple_t*               ref,    /*!< in/out: row reference built;
 
545
        dtuple_t*               ref,    /* in/out: row reference built;
546
546
                                        see the NOTE below! */
547
 
        const rec_t*            rec,    /*!< in: record in the index;
 
547
        const rec_t*            rec,    /* in: record in the index;
548
548
                                        NOTE: the data fields in ref
549
549
                                        will point directly into this
550
550
                                        record, therefore, the buffer
552
552
                                        least s-latched and the latch
553
553
                                        held as long as the row
554
554
                                        reference is used! */
555
 
        const dict_index_t*     index,  /*!< in: secondary index */
556
 
        ulint*                  offsets,/*!< in: rec_get_offsets(rec, index)
 
555
        const dict_index_t*     index,  /* in: secondary index */
 
556
        ulint*                  offsets,/* in: rec_get_offsets(rec, index)
557
557
                                        or NULL */
558
 
        trx_t*                  trx)    /*!< in: transaction */
 
558
        trx_t*                  trx)    /* in: transaction */
559
559
{
560
560
        const dict_index_t*     clust_index;
561
561
        dfield_t*               dfield;
634
634
                                dfield_set_len(dfield,
635
635
                                               dtype_get_at_most_n_mbchars(
636
636
                                                       dtype->prtype,
637
 
                                                       dtype->mbminmaxlen,
 
637
                                                       dtype->mbminlen,
 
638
                                                       dtype->mbmaxlen,
638
639
                                                       clust_col_prefix_len,
639
640
                                                       len, (char*) field));
640
641
                        }
647
648
        }
648
649
}
649
650
 
650
 
/***************************************************************//**
651
 
Searches the clustered index record for a row, if we have the row reference.
652
 
@return TRUE if found */
 
651
/***********************************************************************
 
652
From a row build a row reference with which we can search the clustered
 
653
index record. */
 
654
UNIV_INTERN
 
655
void
 
656
row_build_row_ref_from_row(
 
657
/*=======================*/
 
658
        dtuple_t*               ref,    /* in/out: row reference built;
 
659
                                        see the NOTE below!
 
660
                                        ref must have the right number
 
661
                                        of fields! */
 
662
        const dict_table_t*     table,  /* in: table */
 
663
        const dtuple_t*         row)    /* in: row
 
664
                                        NOTE: the data fields in ref will point
 
665
                                        directly into data of this row */
 
666
{
 
667
        const dict_index_t*     clust_index;
 
668
        ulint                   ref_len;
 
669
        ulint                   i;
 
670
 
 
671
        ut_ad(ref && table && row);
 
672
 
 
673
        clust_index = dict_table_get_first_index(table);
 
674
 
 
675
        ref_len = dict_index_get_n_unique(clust_index);
 
676
 
 
677
        ut_ad(ref_len == dtuple_get_n_fields(ref));
 
678
 
 
679
        for (i = 0; i < ref_len; i++) {
 
680
                const dict_col_t*       col;
 
681
                const dict_field_t*     field;
 
682
                dfield_t*               dfield;
 
683
                const dfield_t*         dfield2;
 
684
 
 
685
                dfield = dtuple_get_nth_field(ref, i);
 
686
 
 
687
                field = dict_index_get_nth_field(clust_index, i);
 
688
 
 
689
                col = dict_field_get_col(field);
 
690
 
 
691
                dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col));
 
692
 
 
693
                dfield_copy(dfield, dfield2);
 
694
                ut_ad(!dfield_is_ext(dfield));
 
695
 
 
696
                if (field->prefix_len > 0 && !dfield_is_null(dfield)) {
 
697
 
 
698
                        ulint   len = dfield_get_len(dfield);
 
699
 
 
700
                        len = dtype_get_at_most_n_mbchars(
 
701
                                col->prtype, col->mbminlen, col->mbmaxlen,
 
702
                                field->prefix_len,
 
703
                                len, dfield_get_data(dfield));
 
704
 
 
705
                        dfield_set_len(dfield, len);
 
706
                }
 
707
        }
 
708
 
 
709
        ut_ad(dtuple_check_typed(ref));
 
710
}
 
711
 
 
712
/*******************************************************************
 
713
Searches the clustered index record for a row, if we have the row reference. */
653
714
UNIV_INTERN
654
715
ibool
655
716
row_search_on_row_ref(
656
717
/*==================*/
657
 
        btr_pcur_t*             pcur,   /*!< out: persistent cursor, which must
 
718
                                        /* out: TRUE if found */
 
719
        btr_pcur_t*             pcur,   /* out: persistent cursor, which must
658
720
                                        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 */
 
721
        ulint                   mode,   /* in: BTR_MODIFY_LEAF, ... */
 
722
        const dict_table_t*     table,  /* in: table */
 
723
        const dtuple_t*         ref,    /* in: row reference */
 
724
        mtr_t*                  mtr)    /* in/out: mtr */
663
725
{
664
726
        ulint           low_match;
665
727
        rec_t*          rec;
690
752
        return(TRUE);
691
753
}
692
754
 
693
 
/*********************************************************************//**
 
755
/*************************************************************************
694
756
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 */
 
757
on the secondary index record are preserved. */
697
758
UNIV_INTERN
698
759
rec_t*
699
760
row_get_clust_rec(
700
761
/*==============*/
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 */
 
762
                                /* out: record or NULL, if no record found */
 
763
        ulint           mode,   /* in: BTR_MODIFY_LEAF, ... */
 
764
        const rec_t*    rec,    /* in: record in a secondary index */
 
765
        dict_index_t*   index,  /* in: secondary index */
 
766
        dict_index_t**  clust_index,/* out: clustered index */
 
767
        mtr_t*          mtr)    /* in: mtr */
706
768
{
707
769
        mem_heap_t*     heap;
708
770
        dtuple_t*       ref;
732
794
        return(clust_rec);
733
795
}
734
796
 
735
 
/***************************************************************//**
736
 
Searches an index record.
737
 
@return whether the record was found or buffered */
 
797
/*******************************************************************
 
798
Searches an index record. */
738
799
UNIV_INTERN
739
 
enum row_search_result
 
800
ibool
740
801
row_search_index_entry(
741
802
/*===================*/
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
 
803
                                /* out: TRUE if found */
 
804
        dict_index_t*   index,  /* in: index */
 
805
        const dtuple_t* entry,  /* in: index entry */
 
806
        ulint           mode,   /* in: BTR_MODIFY_LEAF, ... */
 
807
        btr_pcur_t*     pcur,   /* in/out: persistent cursor, which must
746
808
                                be closed by the caller */
747
 
        mtr_t*          mtr)    /*!< in: mtr */
 
809
        mtr_t*          mtr)    /* in: mtr */
748
810
{
749
811
        ulint   n_fields;
750
812
        ulint   low_match;
753
815
        ut_ad(dtuple_check_typed(entry));
754
816
 
755
817
        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
818
        low_match = btr_pcur_get_low_match(pcur);
774
819
 
775
820
        rec = btr_pcur_get_rec(pcur);
776
821
 
777
822
        n_fields = dtuple_get_n_fields(entry);
778
823
 
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);
 
824
        return(!page_rec_is_infimum(rec) && low_match == n_fields);
788
825
}
789
826
 
790
 
#if !defined(BUILD_DRIZZLE)
791
 
# include "my_sys.h"
792
 
#endif
793
 
 
794
 
 
795
 
/*******************************************************************//**
 
827
#ifndef UNIV_HOTBACKUP
 
828
 
 
829
#include <my_sys.h>
 
830
 
 
831
/***********************************************************************
796
832
Formats the raw data in "data" (in InnoDB on-disk format) that is of
797
833
type DATA_INT using "prtype" and writes the result to "buf".
798
834
If the data is in unknown format, then nothing is written to "buf",
801
837
Not more than "buf_size" bytes are written to "buf".
802
838
The result is always '\0'-terminated (provided buf_size > 0) and the
803
839
number of bytes that were written to "buf" is returned (including the
804
 
terminating '\0').
805
 
@return number of bytes that were written */
 
840
terminating '\0'). */
806
841
static
807
842
ulint
808
843
row_raw_format_int(
809
844
/*===============*/
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
 
845
                                        /* out: number of bytes
 
846
                                        that were written */
 
847
        const char*     data,           /* in: raw data */
 
848
        ulint           data_len,       /* in: raw data length
 
849
                                        in bytes */
 
850
        ulint           prtype,         /* in: precise type */
 
851
        char*           buf,            /* out: output buffer */
 
852
        ulint           buf_size,       /* in: output buffer size
 
853
                                        in bytes */
 
854
        ibool*          format_in_hex)  /* out: should the data be
818
855
                                        formated in hex */
819
856
{
820
857
        ulint   ret;
846
883
        return(ut_min(ret, buf_size));
847
884
}
848
885
 
849
 
/*******************************************************************//**
 
886
/***********************************************************************
850
887
Formats the raw data in "data" (in InnoDB on-disk format) that is of
851
888
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "prtype" and writes the
852
889
result to "buf".
856
893
Not more than "buf_size" bytes are written to "buf".
857
894
The result is always '\0'-terminated (provided buf_size > 0) and the
858
895
number of bytes that were written to "buf" is returned (including the
859
 
terminating '\0').
860
 
@return number of bytes that were written */
 
896
terminating '\0'). */
861
897
static
862
898
ulint
863
899
row_raw_format_str(
864
900
/*===============*/
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
 
901
                                        /* out: number of bytes
 
902
                                        that were written */
 
903
        const char*     data,           /* in: raw data */
 
904
        ulint           data_len,       /* in: raw data length
 
905
                                        in bytes */
 
906
        ulint           prtype,         /* in: precise type */
 
907
        char*           buf,            /* out: output buffer */
 
908
        ulint           buf_size,       /* in: output buffer size
 
909
                                        in bytes */
 
910
        ibool*          format_in_hex)  /* out: should the data be
873
911
                                        formated in hex */
874
912
{
875
913
        ulint   charset_coll;
900
938
                                          buf, buf_size));
901
939
}
902
940
 
903
 
/*******************************************************************//**
 
941
/***********************************************************************
904
942
Formats the raw data in "data" (in InnoDB on-disk format) using
905
943
"dict_field" and writes the result to "buf".
906
944
Not more than "buf_size" bytes are written to "buf".
907
 
The result is always NUL-terminated (provided buf_size is positive) and the
 
945
The result is always '\0'-terminated (provided buf_size > 0) and the
908
946
number of bytes that were written to "buf" is returned (including the
909
 
terminating NUL).
910
 
@return number of bytes that were written */
 
947
terminating '\0'). */
911
948
UNIV_INTERN
912
949
ulint
913
950
row_raw_format(
914
951
/*===========*/
915
 
        const char*             data,           /*!< in: raw data */
916
 
        ulint                   data_len,       /*!< in: raw data length
 
952
                                                /* out: number of bytes
 
953
                                                that were written */
 
954
        const char*             data,           /* in: raw data */
 
955
        ulint                   data_len,       /* in: raw data length
917
956
                                                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
 
957
        const dict_field_t*     dict_field,     /* in: index field */
 
958
        char*                   buf,            /* out: output buffer */
 
959
        ulint                   buf_size)       /* in: output buffer size
921
960
                                                in bytes */
922
961
{
923
962
        ulint   mtype;
924
963
        ulint   prtype;
925
 
        ulint   ret= 0;
 
964
        ulint   ret;
926
965
        ibool   format_in_hex;
927
966
 
928
967
        if (buf_size == 0) {
929
968
 
930
 
                return(ret);
 
969
                return(0);
931
970
        }
932
971
 
933
972
        if (data_len == UNIV_SQL_NULL) {
947
986
 
948
987
                ret = row_raw_format_int(data, data_len, prtype,
949
988
                                         buf, buf_size, &format_in_hex);
950
 
                if (format_in_hex) {
951
 
 
952
 
                        goto format_in_hex;
953
 
                }
954
989
                break;
955
990
        case DATA_CHAR:
956
991
        case DATA_VARCHAR:
959
994
 
960
995
                ret = row_raw_format_str(data, data_len, prtype,
961
996
                                         buf, buf_size, &format_in_hex);
962
 
                if (format_in_hex) {
963
 
 
964
 
                        goto format_in_hex;
965
 
                }
966
 
 
967
997
                break;
968
998
        /* XXX support more data types */
969
999
        default:
970
 
        format_in_hex:
 
1000
 
 
1001
                format_in_hex = TRUE;
 
1002
        }
 
1003
 
 
1004
        if (format_in_hex) {
971
1005
 
972
1006
                if (UNIV_LIKELY(buf_size > 2)) {
973
1007
 
986
1020
        return(ret);
987
1021
}
988
1022
 
 
1023
#endif /* !UNIV_HOTBACKUP */
 
1024
 
989
1025
#ifdef UNIV_COMPILE_TEST_FUNCS
990
1026
 
991
1027
#include "ut0dbg.h"