~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Eric Day
  • Date: 2009-10-31 21:53:33 UTC
  • mfrom: (1200 staging)
  • mto: This revision was merged to the branch mainline in revision 1202.
  • Revision ID: eday@oddments.org-20091031215333-j94bjoanwmi68p6f
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
*****************************************************************************/
18
18
 
19
 
/******************************************************
 
19
/**************************************************//**
 
20
@file row/row0row.c
20
21
General row routines
21
22
 
22
23
Created 4/20/1996 Heikki Tuuri
46
47
#include "read0read.h"
47
48
#include "ut0mem.h"
48
49
 
49
 
/*************************************************************************
 
50
/*********************************************************************//**
50
51
Gets the offset of trx id field, in bytes relative to the origin of
51
 
a clustered index record. */
 
52
a clustered index record.
 
53
@return offset of DATA_TRX_ID */
52
54
UNIV_INTERN
53
55
ulint
54
56
row_get_trx_id_offset(
55
57
/*==================*/
56
 
                                /* out: offset of DATA_TRX_ID */
57
58
        const rec_t*    rec __attribute__((unused)),
58
 
                                /* in: record */
59
 
        dict_index_t*   index,  /* in: clustered index */
60
 
        const ulint*    offsets)/* in: rec_get_offsets(rec, index) */
 
59
                                /*!< in: record */
 
60
        dict_index_t*   index,  /*!< in: clustered index */
 
61
        const ulint*    offsets)/*!< in: rec_get_offsets(rec, index) */
61
62
{
62
63
        ulint   pos;
63
64
        ulint   offset;
75
76
        return(offset);
76
77
}
77
78
 
78
 
/*********************************************************************
 
79
/*****************************************************************//**
79
80
When an insert or purge to a table is performed, this function builds
80
 
the entry to be inserted into or purged from an index on the table. */
 
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 */
81
85
UNIV_INTERN
82
86
dtuple_t*
83
87
row_build_index_entry(
84
88
/*==================*/
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
 
89
        const dtuple_t* row,    /*!< in: row which should be
91
90
                                inserted or purged */
92
 
        row_ext_t*      ext,    /* in: externally stored column prefixes,
 
91
        row_ext_t*      ext,    /*!< in: externally stored column prefixes,
93
92
                                or NULL */
94
 
        dict_index_t*   index,  /* in: index on the table */
95
 
        mem_heap_t*     heap)   /* in: memory heap from which the memory for
 
93
        dict_index_t*   index,  /*!< in: index on the table */
 
94
        mem_heap_t*     heap)   /*!< in: memory heap from which the memory for
96
95
                                the index entry is allocated */
97
96
{
98
97
        dtuple_t*       entry;
167
166
        return(entry);
168
167
}
169
168
 
170
 
/***********************************************************************
 
169
/*******************************************************************//**
171
170
An inverse function to row_build_index_entry. Builds a row from a
172
 
record in a clustered index. */
 
171
record in a clustered index.
 
172
@return own: row built; see the NOTE below! */
173
173
UNIV_INTERN
174
174
dtuple_t*
175
175
row_build(
176
176
/*======*/
177
 
                                        /* out, own: row built;
178
 
                                        see the NOTE below! */
179
 
        ulint                   type,   /* in: ROW_COPY_POINTERS or
 
177
        ulint                   type,   /*!< in: ROW_COPY_POINTERS or
180
178
                                        ROW_COPY_DATA; the latter
181
179
                                        copies also the data fields to
182
180
                                        heap while the first only
183
181
                                        places pointers to data fields
184
182
                                        on the index page, and thus is
185
183
                                        more efficient */
186
 
        const dict_index_t*     index,  /* in: clustered index */
187
 
        const rec_t*            rec,    /* in: record in the clustered
 
184
        const dict_index_t*     index,  /*!< in: clustered index */
 
185
        const rec_t*            rec,    /*!< in: record in the clustered
188
186
                                        index; NOTE: in the case
189
187
                                        ROW_COPY_POINTERS the data
190
188
                                        fields in the row will point
193
191
                                        this record must be at least
194
192
                                        s-latched and the latch held
195
193
                                        as long as the row dtuple is used! */
196
 
        const ulint*            offsets,/* in: rec_get_offsets(rec,index)
 
194
        const ulint*            offsets,/*!< in: rec_get_offsets(rec,index)
197
195
                                        or NULL, in which case this function
198
196
                                        will invoke rec_get_offsets() */
199
197
        const dict_table_t*     col_table,
200
 
                                        /* in: table, to check which
 
198
                                        /*!< in: table, to check which
201
199
                                        externally stored columns
202
200
                                        occur in the ordering columns
203
201
                                        of an index, or NULL if
204
202
                                        index->table should be
205
203
                                        consulted instead */
206
 
        row_ext_t**             ext,    /* out, own: cache of
 
204
        row_ext_t**             ext,    /*!< out, own: cache of
207
205
                                        externally stored column
208
206
                                        prefixes, or NULL */
209
 
        mem_heap_t*             heap)   /* in: memory heap from which
 
207
        mem_heap_t*             heap)   /*!< in: memory heap from which
210
208
                                        the memory needed is allocated */
211
209
{
212
210
        dtuple_t*               row;
311
309
        return(row);
312
310
}
313
311
 
314
 
/***********************************************************************
315
 
Converts an index record to a typed data tuple. */
 
312
/*******************************************************************//**
 
313
Converts an index record to a typed data tuple.
 
314
@return index entry built; does not set info_bits, and the data fields
 
315
in the entry will point directly to rec */
316
316
UNIV_INTERN
317
317
dtuple_t*
318
318
row_rec_to_index_entry_low(
319
319
/*=======================*/
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
 
320
        const rec_t*            rec,    /*!< in: record in the index */
 
321
        const dict_index_t*     index,  /*!< in: index */
 
322
        const ulint*            offsets,/*!< in: rec_get_offsets(rec, index) */
 
323
        ulint*                  n_ext,  /*!< out: number of externally
327
324
                                        stored columns */
328
 
        mem_heap_t*             heap)   /* in: memory heap from which
 
325
        mem_heap_t*             heap)   /*!< in: memory heap from which
329
326
                                        the memory needed is allocated */
330
327
{
331
328
        dtuple_t*       entry;
370
367
        return(entry);
371
368
}
372
369
 
373
 
/***********************************************************************
 
370
/*******************************************************************//**
374
371
Converts an index record to a typed data tuple. NOTE that externally
375
 
stored (often big) fields are NOT copied to heap. */
 
372
stored (often big) fields are NOT copied to heap.
 
373
@return own: index entry built; see the NOTE below! */
376
374
UNIV_INTERN
377
375
dtuple_t*
378
376
row_rec_to_index_entry(
379
377
/*===================*/
380
 
                                        /* out, own: index entry
381
 
                                        built; see the NOTE below! */
382
 
        ulint                   type,   /* in: ROW_COPY_DATA, or
 
378
        ulint                   type,   /*!< in: ROW_COPY_DATA, or
383
379
                                        ROW_COPY_POINTERS: the former
384
380
                                        copies also the data fields to
385
381
                                        heap as the latter only places
386
382
                                        pointers to data fields on the
387
383
                                        index page */
388
 
        const rec_t*            rec,    /* in: record in the index;
 
384
        const rec_t*            rec,    /*!< in: record in the index;
389
385
                                        NOTE: in the case
390
386
                                        ROW_COPY_POINTERS the data
391
387
                                        fields in the row will point
394
390
                                        this record must be at least
395
391
                                        s-latched and the latch held
396
392
                                        as long as the dtuple is used! */
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
 
393
        const dict_index_t*     index,  /*!< in: index */
 
394
        ulint*                  offsets,/*!< in/out: rec_get_offsets(rec) */
 
395
        ulint*                  n_ext,  /*!< out: number of externally
400
396
                                        stored columns */
401
 
        mem_heap_t*             heap)   /* in: memory heap from which
 
397
        mem_heap_t*             heap)   /*!< in: memory heap from which
402
398
                                        the memory needed is allocated */
403
399
{
404
400
        dtuple_t*       entry;
423
419
        return(entry);
424
420
}
425
421
 
426
 
/***********************************************************************
 
422
/*******************************************************************//**
427
423
Builds from a secondary index record a row reference with which we can
428
 
search the clustered index record. */
 
424
search the clustered index record.
 
425
@return own: row reference built; see the NOTE below! */
429
426
UNIV_INTERN
430
427
dtuple_t*
431
428
row_build_row_ref(
432
429
/*==============*/
433
 
                                /* out, own: row reference built; see the
434
 
                                NOTE below! */
435
 
        ulint           type,   /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
 
430
        ulint           type,   /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
436
431
                                the former copies also the data fields to
437
432
                                heap, whereas the latter only places pointers
438
433
                                to data fields on the index page */
439
 
        dict_index_t*   index,  /* in: secondary index */
440
 
        const rec_t*    rec,    /* in: record in the index;
 
434
        dict_index_t*   index,  /*!< in: secondary index */
 
435
        const rec_t*    rec,    /*!< in: record in the index;
441
436
                                NOTE: in the case ROW_COPY_POINTERS
442
437
                                the data fields in the row will point
443
438
                                directly into this record, therefore,
444
439
                                the buffer page of this record must be
445
440
                                at least s-latched and the latch held
446
441
                                as long as the row reference is used! */
447
 
        mem_heap_t*     heap)   /* in: memory heap from which the memory
 
442
        mem_heap_t*     heap)   /*!< in: memory heap from which the memory
448
443
                                needed is allocated */
449
444
{
450
445
        dict_table_t*   table;
535
530
        return(ref);
536
531
}
537
532
 
538
 
/***********************************************************************
 
533
/*******************************************************************//**
539
534
Builds from a secondary index record a row reference with which we can
540
535
search the clustered index record. */
541
536
UNIV_INTERN
542
537
void
543
538
row_build_row_ref_in_tuple(
544
539
/*=======================*/
545
 
        dtuple_t*               ref,    /* in/out: row reference built;
 
540
        dtuple_t*               ref,    /*!< in/out: row reference built;
546
541
                                        see the NOTE below! */
547
 
        const rec_t*            rec,    /* in: record in the index;
 
542
        const rec_t*            rec,    /*!< in: record in the index;
548
543
                                        NOTE: the data fields in ref
549
544
                                        will point directly into this
550
545
                                        record, therefore, the buffer
552
547
                                        least s-latched and the latch
553
548
                                        held as long as the row
554
549
                                        reference is used! */
555
 
        const dict_index_t*     index,  /* in: secondary index */
556
 
        ulint*                  offsets,/* in: rec_get_offsets(rec, index)
 
550
        const dict_index_t*     index,  /*!< in: secondary index */
 
551
        ulint*                  offsets,/*!< in: rec_get_offsets(rec, index)
557
552
                                        or NULL */
558
 
        trx_t*                  trx)    /* in: transaction */
 
553
        trx_t*                  trx)    /*!< in: transaction */
559
554
{
560
555
        const dict_index_t*     clust_index;
561
556
        dfield_t*               dfield;
648
643
        }
649
644
}
650
645
 
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. */
 
646
/***************************************************************//**
 
647
Searches the clustered index record for a row, if we have the row reference.
 
648
@return TRUE if found */
714
649
UNIV_INTERN
715
650
ibool
716
651
row_search_on_row_ref(
717
652
/*==================*/
718
 
                                        /* out: TRUE if found */
719
 
        btr_pcur_t*             pcur,   /* out: persistent cursor, which must
 
653
        btr_pcur_t*             pcur,   /*!< out: persistent cursor, which must
720
654
                                        be closed by the caller */
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 */
 
655
        ulint                   mode,   /*!< in: BTR_MODIFY_LEAF, ... */
 
656
        const dict_table_t*     table,  /*!< in: table */
 
657
        const dtuple_t*         ref,    /*!< in: row reference */
 
658
        mtr_t*                  mtr)    /*!< in/out: mtr */
725
659
{
726
660
        ulint           low_match;
727
661
        rec_t*          rec;
752
686
        return(TRUE);
753
687
}
754
688
 
755
 
/*************************************************************************
 
689
/*********************************************************************//**
756
690
Fetches the clustered index record for a secondary index record. The latches
757
 
on the secondary index record are preserved. */
 
691
on the secondary index record are preserved.
 
692
@return record or NULL, if no record found */
758
693
UNIV_INTERN
759
694
rec_t*
760
695
row_get_clust_rec(
761
696
/*==============*/
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 */
 
697
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF, ... */
 
698
        const rec_t*    rec,    /*!< in: record in a secondary index */
 
699
        dict_index_t*   index,  /*!< in: secondary index */
 
700
        dict_index_t**  clust_index,/*!< out: clustered index */
 
701
        mtr_t*          mtr)    /*!< in: mtr */
768
702
{
769
703
        mem_heap_t*     heap;
770
704
        dtuple_t*       ref;
794
728
        return(clust_rec);
795
729
}
796
730
 
797
 
/*******************************************************************
798
 
Searches an index record. */
 
731
/***************************************************************//**
 
732
Searches an index record.
 
733
@return TRUE if found */
799
734
UNIV_INTERN
800
735
ibool
801
736
row_search_index_entry(
802
737
/*===================*/
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
 
738
        dict_index_t*   index,  /*!< in: index */
 
739
        const dtuple_t* entry,  /*!< in: index entry */
 
740
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF, ... */
 
741
        btr_pcur_t*     pcur,   /*!< in/out: persistent cursor, which must
808
742
                                be closed by the caller */
809
 
        mtr_t*          mtr)    /* in: mtr */
 
743
        mtr_t*          mtr)    /*!< in: mtr */
810
744
{
811
745
        ulint   n_fields;
812
746
        ulint   low_match;
824
758
        return(!page_rec_is_infimum(rec) && low_match == n_fields);
825
759
}
826
760
 
827
 
#ifndef UNIV_HOTBACKUP
828
 
 
829
761
#if defined(BUILD_DRIZZLE)
830
 
# include <mysys/my_sys.h>
 
762
# include "mysys/my_sys.h"
831
763
#else
832
 
# include <my_sys.h>
 
764
# include "my_sys.h"
833
765
#endif
834
766
 
835
 
/***********************************************************************
 
767
 
 
768
/*******************************************************************//**
836
769
Formats the raw data in "data" (in InnoDB on-disk format) that is of
837
770
type DATA_INT using "prtype" and writes the result to "buf".
838
771
If the data is in unknown format, then nothing is written to "buf",
841
774
Not more than "buf_size" bytes are written to "buf".
842
775
The result is always '\0'-terminated (provided buf_size > 0) and the
843
776
number of bytes that were written to "buf" is returned (including the
844
 
terminating '\0'). */
 
777
terminating '\0').
 
778
@return number of bytes that were written */
845
779
static
846
780
ulint
847
781
row_raw_format_int(
848
782
/*===============*/
849
 
                                        /* out: number of bytes
850
 
                                        that were written */
851
 
        const char*     data,           /* in: raw data */
852
 
        ulint           data_len,       /* in: raw data length
853
 
                                        in bytes */
854
 
        ulint           prtype,         /* in: precise type */
855
 
        char*           buf,            /* out: output buffer */
856
 
        ulint           buf_size,       /* in: output buffer size
857
 
                                        in bytes */
858
 
        ibool*          format_in_hex)  /* out: should the data be
 
783
        const char*     data,           /*!< in: raw data */
 
784
        ulint           data_len,       /*!< in: raw data length
 
785
                                        in bytes */
 
786
        ulint           prtype,         /*!< in: precise type */
 
787
        char*           buf,            /*!< out: output buffer */
 
788
        ulint           buf_size,       /*!< in: output buffer size
 
789
                                        in bytes */
 
790
        ibool*          format_in_hex)  /*!< out: should the data be
859
791
                                        formated in hex */
860
792
{
861
793
        ulint   ret;
887
819
        return(ut_min(ret, buf_size));
888
820
}
889
821
 
890
 
/***********************************************************************
 
822
/*******************************************************************//**
891
823
Formats the raw data in "data" (in InnoDB on-disk format) that is of
892
824
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "prtype" and writes the
893
825
result to "buf".
897
829
Not more than "buf_size" bytes are written to "buf".
898
830
The result is always '\0'-terminated (provided buf_size > 0) and the
899
831
number of bytes that were written to "buf" is returned (including the
900
 
terminating '\0'). */
 
832
terminating '\0').
 
833
@return number of bytes that were written */
901
834
static
902
835
ulint
903
836
row_raw_format_str(
904
837
/*===============*/
905
 
                                        /* out: number of bytes
906
 
                                        that were written */
907
 
        const char*     data,           /* in: raw data */
908
 
        ulint           data_len,       /* in: raw data length
909
 
                                        in bytes */
910
 
        ulint           prtype,         /* in: precise type */
911
 
        char*           buf,            /* out: output buffer */
912
 
        ulint           buf_size,       /* in: output buffer size
913
 
                                        in bytes */
914
 
        ibool*          format_in_hex)  /* out: should the data be
 
838
        const char*     data,           /*!< in: raw data */
 
839
        ulint           data_len,       /*!< in: raw data length
 
840
                                        in bytes */
 
841
        ulint           prtype,         /*!< in: precise type */
 
842
        char*           buf,            /*!< out: output buffer */
 
843
        ulint           buf_size,       /*!< in: output buffer size
 
844
                                        in bytes */
 
845
        ibool*          format_in_hex)  /*!< out: should the data be
915
846
                                        formated in hex */
916
847
{
917
848
        ulint   charset_coll;
942
873
                                          buf, buf_size));
943
874
}
944
875
 
945
 
/***********************************************************************
 
876
/*******************************************************************//**
946
877
Formats the raw data in "data" (in InnoDB on-disk format) using
947
878
"dict_field" and writes the result to "buf".
948
879
Not more than "buf_size" bytes are written to "buf".
949
 
The result is always '\0'-terminated (provided buf_size > 0) and the
 
880
The result is always NUL-terminated (provided buf_size is positive) and the
950
881
number of bytes that were written to "buf" is returned (including the
951
 
terminating '\0'). */
 
882
terminating NUL).
 
883
@return number of bytes that were written */
952
884
UNIV_INTERN
953
885
ulint
954
886
row_raw_format(
955
887
/*===========*/
956
 
                                                /* out: number of bytes
957
 
                                                that were written */
958
 
        const char*             data,           /* in: raw data */
959
 
        ulint                   data_len,       /* in: raw data length
 
888
        const char*             data,           /*!< in: raw data */
 
889
        ulint                   data_len,       /*!< in: raw data length
960
890
                                                in bytes */
961
 
        const dict_field_t*     dict_field,     /* in: index field */
962
 
        char*                   buf,            /* out: output buffer */
963
 
        ulint                   buf_size)       /* in: output buffer size
 
891
        const dict_field_t*     dict_field,     /*!< in: index field */
 
892
        char*                   buf,            /*!< out: output buffer */
 
893
        ulint                   buf_size)       /*!< in: output buffer size
964
894
                                                in bytes */
965
895
{
966
896
        ulint   mtype;
967
897
        ulint   prtype;
968
 
        ulint   ret;
 
898
        ulint   ret= 0;
969
899
        ibool   format_in_hex;
970
900
 
971
 
        ret = 0;
972
 
 
973
901
        if (buf_size == 0) {
974
902
 
975
903
                return(ret);
1026
954
        return(ret);
1027
955
}
1028
956
 
1029
 
#endif /* !UNIV_HOTBACKUP */
1030
 
 
1031
957
#ifdef UNIV_COMPILE_TEST_FUNCS
1032
958
 
1033
959
#include "ut0dbg.h"