46
47
#include "read0read.h"
47
48
#include "ut0mem.h"
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 */
54
56
row_get_trx_id_offset(
55
57
/*==================*/
56
/* out: offset of DATA_TRX_ID */
57
58
const rec_t* rec __attribute__((unused)),
59
dict_index_t* index, /* in: clustered index */
60
const ulint* offsets)/* in: rec_get_offsets(rec, index) */
60
dict_index_t* index, /*!< in: clustered index */
61
const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
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 */
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
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,
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 */
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! */
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 */
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 */
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 */
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! */
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
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 */
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! */
431
428
row_build_row_ref(
432
429
/*==============*/
433
/* out, own: row reference built; see the
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 */
450
445
dict_table_t* table;
538
/***********************************************************************
533
/*******************************************************************//**
539
534
Builds from a secondary index record a row reference with which we can
540
535
search the clustered index record. */
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)
558
trx_t* trx) /* in: transaction */
553
trx_t* trx) /*!< in: transaction */
560
555
const dict_index_t* clust_index;
561
556
dfield_t* dfield;
651
/***********************************************************************
652
From a row build a row reference with which we can search the clustered
656
row_build_row_ref_from_row(
657
/*=======================*/
658
dtuple_t* ref, /* in/out: row reference built;
660
ref must have the right number
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 */
667
const dict_index_t* clust_index;
671
ut_ad(ref && table && row);
673
clust_index = dict_table_get_first_index(table);
675
ref_len = dict_index_get_n_unique(clust_index);
677
ut_ad(ref_len == dtuple_get_n_fields(ref));
679
for (i = 0; i < ref_len; i++) {
680
const dict_col_t* col;
681
const dict_field_t* field;
683
const dfield_t* dfield2;
685
dfield = dtuple_get_nth_field(ref, i);
687
field = dict_index_get_nth_field(clust_index, i);
689
col = dict_field_get_col(field);
691
dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col));
693
dfield_copy(dfield, dfield2);
694
ut_ad(!dfield_is_ext(dfield));
696
if (field->prefix_len > 0 && !dfield_is_null(dfield)) {
698
ulint len = dfield_get_len(dfield);
700
len = dtype_get_at_most_n_mbchars(
701
col->prtype, col->mbminlen, col->mbmaxlen,
703
len, dfield_get_data(dfield));
705
dfield_set_len(dfield, len);
709
ut_ad(dtuple_check_typed(ref));
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 */
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 */
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 */
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 */
769
703
mem_heap_t* heap;
794
728
return(clust_rec);
797
/*******************************************************************
798
Searches an index record. */
731
/***************************************************************//**
732
Searches an index record.
733
@return TRUE if found */
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 */
824
758
return(!page_rec_is_infimum(rec) && low_match == n_fields);
827
#ifndef UNIV_HOTBACKUP
829
761
#if defined(BUILD_DRIZZLE)
830
# include <mysys/my_sys.h>
762
# include "mysys/my_sys.h"
835
/***********************************************************************
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'). */
778
@return number of bytes that were written */
847
781
row_raw_format_int(
848
782
/*===============*/
849
/* out: number of bytes
851
const char* data, /* in: raw data */
852
ulint data_len, /* in: raw data length
854
ulint prtype, /* in: precise type */
855
char* buf, /* out: output buffer */
856
ulint buf_size, /* in: output buffer size
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
786
ulint prtype, /*!< in: precise type */
787
char* buf, /*!< out: output buffer */
788
ulint buf_size, /*!< in: output buffer size
790
ibool* format_in_hex) /*!< out: should the data be
859
791
formated in hex */
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'). */
833
@return number of bytes that were written */
903
836
row_raw_format_str(
904
837
/*===============*/
905
/* out: number of bytes
907
const char* data, /* in: raw data */
908
ulint data_len, /* in: raw data length
910
ulint prtype, /* in: precise type */
911
char* buf, /* out: output buffer */
912
ulint buf_size, /* in: output buffer size
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
841
ulint prtype, /*!< in: precise type */
842
char* buf, /*!< out: output buffer */
843
ulint buf_size, /*!< in: output buffer size
845
ibool* format_in_hex) /*!< out: should the data be
915
846
formated in hex */
917
848
ulint charset_coll;
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'). */
883
@return number of bytes that were written */
956
/* out: number of bytes
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
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
969
899
ibool format_in_hex;
973
901
if (buf_size == 0) {