37
36
#include "row0types.h"
38
37
#include "btr0types.h"
40
/*********************************************************************//**
39
/*************************************************************************
41
40
Gets the offset of the trx id field, in bytes relative to the origin of
42
a clustered index record.
43
@return offset of DATA_TRX_ID */
41
a clustered index record. */
46
44
row_get_trx_id_offset(
47
45
/*==================*/
48
const rec_t* rec, /*!< in: record */
49
dict_index_t* index, /*!< in: clustered index */
50
const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
51
/*********************************************************************//**
52
Reads the trx id field from a clustered index record.
53
@return value of the field */
46
/* out: offset of DATA_TRX_ID */
47
const rec_t* rec, /* in: record */
48
dict_index_t* index, /* in: clustered index */
49
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
50
/*************************************************************************
51
Reads the trx id field from a clustered index record. */
56
54
row_get_rec_trx_id(
57
55
/*===============*/
58
const rec_t* rec, /*!< in: record */
59
dict_index_t* index, /*!< in: clustered index */
60
const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
61
/*********************************************************************//**
62
Reads the roll pointer field from a clustered index record.
63
@return value of the field */
56
/* out: value of the field */
57
const rec_t* rec, /* in: record */
58
dict_index_t* index, /* in: clustered index */
59
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
60
/*************************************************************************
61
Reads the roll pointer field from a clustered index record. */
66
64
row_get_rec_roll_ptr(
67
65
/*=================*/
68
const rec_t* rec, /*!< in: record */
69
dict_index_t* index, /*!< in: clustered index */
70
const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
71
/*****************************************************************//**
66
/* out: value of the field */
67
const rec_t* rec, /* in: record */
68
dict_index_t* index, /* in: clustered index */
69
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
70
/*********************************************************************
72
71
When an insert or purge to a table is performed, this function builds
73
the entry to be inserted into or purged from an index on the table.
74
@return index entry which should be inserted or purged, or NULL if the
75
externally stored columns in the clustered index record are
76
unavailable and ext != NULL */
72
the entry to be inserted into or purged from an index on the table. */
79
75
row_build_index_entry(
80
76
/*==================*/
81
const dtuple_t* row, /*!< in: row which should be
77
/* out: index entry which should be
78
inserted or purged, or NULL if the
79
externally stored columns in the
80
clustered index record are unavailable
82
const dtuple_t* row, /* in: row which should be
82
83
inserted or purged */
83
row_ext_t* ext, /*!< in: externally stored column prefixes,
84
row_ext_t* ext, /* in: externally stored column prefixes,
85
dict_index_t* index, /*!< in: index on the table */
86
mem_heap_t* heap); /*!< in: memory heap from which the memory for
86
dict_index_t* index, /* in: index on the table */
87
mem_heap_t* heap); /* in: memory heap from which the memory for
87
88
the index entry is allocated */
88
/*******************************************************************//**
89
/***********************************************************************
89
90
An inverse function to row_build_index_entry. Builds a row from a
90
record in a clustered index.
91
@return own: row built; see the NOTE below! */
91
record in a clustered index. */
96
ulint type, /*!< in: ROW_COPY_POINTERS or
96
/* out, own: row built;
97
see the NOTE below! */
98
ulint type, /* in: ROW_COPY_POINTERS or
97
99
ROW_COPY_DATA; the latter
98
100
copies also the data fields to
99
101
heap while the first only
100
102
places pointers to data fields
101
103
on the index page, and thus is
102
104
more efficient */
103
const dict_index_t* index, /*!< in: clustered index */
104
const rec_t* rec, /*!< in: record in the clustered
105
const dict_index_t* index, /* in: clustered index */
106
const rec_t* rec, /* in: record in the clustered
105
107
index; NOTE: in the case
106
108
ROW_COPY_POINTERS the data
107
109
fields in the row will point
122
124
consulted instead; the user
123
125
columns in this table should be
124
126
the same columns as in index->table */
125
row_ext_t** ext, /*!< out, own: cache of
127
row_ext_t** ext, /* out, own: cache of
126
128
externally stored column
127
129
prefixes, or NULL */
128
mem_heap_t* heap); /*!< in: memory heap from which
130
mem_heap_t* heap); /* in: memory heap from which
129
131
the memory needed is allocated */
130
/*******************************************************************//**
131
Converts an index record to a typed data tuple.
132
@return index entry built; does not set info_bits, and the data fields
133
in the entry will point directly to rec */
132
/***********************************************************************
133
Converts an index record to a typed data tuple. */
136
136
row_rec_to_index_entry_low(
137
137
/*=======================*/
138
const rec_t* rec, /*!< in: record in the index */
139
const dict_index_t* index, /*!< in: index */
140
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
141
ulint* n_ext, /*!< out: number of externally
138
/* out: index entry built; does not
139
set info_bits, and the data fields in
140
the entry will point directly to rec */
141
const rec_t* rec, /* in: record in the index */
142
const dict_index_t* index, /* in: index */
143
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
144
ulint* n_ext, /* out: number of externally
142
145
stored columns */
143
mem_heap_t* heap); /*!< in: memory heap from which
146
mem_heap_t* heap); /* in: memory heap from which
144
147
the memory needed is allocated */
145
/*******************************************************************//**
148
/***********************************************************************
146
149
Converts an index record to a typed data tuple. NOTE that externally
147
stored (often big) fields are NOT copied to heap.
148
@return own: index entry built; see the NOTE below! */
150
stored (often big) fields are NOT copied to heap. */
151
153
row_rec_to_index_entry(
152
154
/*===================*/
153
ulint type, /*!< in: ROW_COPY_DATA, or
155
/* out, own: index entry
156
built; see the NOTE below! */
157
ulint type, /* in: ROW_COPY_DATA, or
154
158
ROW_COPY_POINTERS: the former
155
159
copies also the data fields to
156
160
heap as the latter only places
157
161
pointers to data fields on the
159
const rec_t* rec, /*!< in: record in the index;
163
const rec_t* rec, /* in: record in the index;
160
164
NOTE: in the case
161
165
ROW_COPY_POINTERS the data
162
166
fields in the row will point
165
169
this record must be at least
166
170
s-latched and the latch held
167
171
as long as the dtuple is used! */
168
const dict_index_t* index, /*!< in: index */
169
ulint* offsets,/*!< in/out: rec_get_offsets(rec) */
170
ulint* n_ext, /*!< out: number of externally
172
const dict_index_t* index, /* in: index */
173
ulint* offsets,/* in/out: rec_get_offsets(rec) */
174
ulint* n_ext, /* out: number of externally
171
175
stored columns */
172
mem_heap_t* heap); /*!< in: memory heap from which
176
mem_heap_t* heap); /* in: memory heap from which
173
177
the memory needed is allocated */
174
/*******************************************************************//**
178
/***********************************************************************
175
179
Builds from a secondary index record a row reference with which we can
176
search the clustered index record.
177
@return own: row reference built; see the NOTE below! */
180
search the clustered index record. */
180
183
row_build_row_ref(
181
184
/*==============*/
182
ulint type, /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
185
/* out, own: row reference built; see the
187
ulint type, /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
183
188
the former copies also the data fields to
184
189
heap, whereas the latter only places pointers
185
190
to data fields on the index page */
186
dict_index_t* index, /*!< in: secondary index */
187
const rec_t* rec, /*!< in: record in the index;
191
dict_index_t* index, /* in: secondary index */
192
const rec_t* rec, /* in: record in the index;
188
193
NOTE: in the case ROW_COPY_POINTERS
189
194
the data fields in the row will point
190
195
directly into this record, therefore,
191
196
the buffer page of this record must be
192
197
at least s-latched and the latch held
193
198
as long as the row reference is used! */
194
mem_heap_t* heap); /*!< in: memory heap from which the memory
199
mem_heap_t* heap); /* in: memory heap from which the memory
195
200
needed is allocated */
196
/*******************************************************************//**
201
/***********************************************************************
197
202
Builds from a secondary index record a row reference with which we can
198
203
search the clustered index record. */
201
206
row_build_row_ref_in_tuple(
202
207
/*=======================*/
203
dtuple_t* ref, /*!< in/out: row reference built;
208
dtuple_t* ref, /* in/out: row reference built;
204
209
see the NOTE below! */
205
const rec_t* rec, /*!< in: record in the index;
210
const rec_t* rec, /* in: record in the index;
206
211
NOTE: the data fields in ref
207
212
will point directly into this
208
213
record, therefore, the buffer
210
215
least s-latched and the latch
211
216
held as long as the row
212
217
reference is used! */
213
const dict_index_t* index, /*!< in: secondary index */
214
ulint* offsets,/*!< in: rec_get_offsets(rec, index)
218
const dict_index_t* index, /* in: secondary index */
219
ulint* offsets,/* in: rec_get_offsets(rec, index)
216
trx_t* trx); /*!< in: transaction */
217
/*******************************************************************//**
221
trx_t* trx); /* in: transaction */
222
/***********************************************************************
223
From a row build a row reference with which we can search the clustered
227
row_build_row_ref_from_row(
228
/*=======================*/
229
dtuple_t* ref, /* in/out: row reference built;
231
ref must have the right number
233
const dict_table_t* table, /* in: table */
234
const dtuple_t* row); /* in: row
235
NOTE: the data fields in ref will point
236
directly into data of this row */
237
/***********************************************************************
218
238
Builds from a secondary index record a row reference with which we can
219
239
search the clustered index record. */
222
242
row_build_row_ref_fast(
223
243
/*===================*/
224
dtuple_t* ref, /*!< in/out: typed data tuple where the
244
dtuple_t* ref, /* in/out: typed data tuple where the
225
245
reference is built */
226
const ulint* map, /*!< in: array of field numbers in rec
246
const ulint* map, /* in: array of field numbers in rec
227
247
telling how ref should be built from
228
248
the fields of rec */
229
const rec_t* rec, /*!< in: record in the index; must be
249
const rec_t* rec, /* in: record in the index; must be
230
250
preserved while ref is used, as we do
231
251
not copy field values to heap */
232
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
233
/***************************************************************//**
252
const ulint* offsets);/* in: array returned by rec_get_offsets() */
253
/*******************************************************************
234
254
Searches the clustered index record for a row, if we have the row
236
@return TRUE if found */
239
258
row_search_on_row_ref(
240
259
/*==================*/
241
btr_pcur_t* pcur, /*!< out: persistent cursor, which must
260
/* out: TRUE if found */
261
btr_pcur_t* pcur, /* out: persistent cursor, which must
242
262
be closed by the caller */
243
ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
244
const dict_table_t* table, /*!< in: table */
245
const dtuple_t* ref, /*!< in: row reference */
246
mtr_t* mtr); /*!< in/out: mtr */
247
/*********************************************************************//**
263
ulint mode, /* in: BTR_MODIFY_LEAF, ... */
264
const dict_table_t* table, /* in: table */
265
const dtuple_t* ref, /* in: row reference */
266
mtr_t* mtr); /* in/out: mtr */
267
/*************************************************************************
248
268
Fetches the clustered index record for a secondary index record. The latches
249
on the secondary index record are preserved.
250
@return record or NULL, if no record found */
269
on the secondary index record are preserved. */
253
272
row_get_clust_rec(
254
273
/*==============*/
255
ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
256
const rec_t* rec, /*!< in: record in a secondary index */
257
dict_index_t* index, /*!< in: secondary index */
258
dict_index_t** clust_index,/*!< out: clustered index */
259
mtr_t* mtr); /*!< in: mtr */
261
/** Result of row_search_index_entry */
262
enum row_search_result {
263
ROW_FOUND = 0, /*!< the record was found */
264
ROW_NOT_FOUND, /*!< record not found */
265
ROW_BUFFERED, /*!< one of BTR_INSERT, BTR_DELETE, or
266
BTR_DELETE_MARK was specified, the
267
secondary index leaf page was not in
268
the buffer pool, and the operation was
269
enqueued in the insert/delete buffer */
270
ROW_NOT_DELETED_REF /*!< BTR_DELETE was specified, and
271
row_purge_poss_sec() failed */
274
/***************************************************************//**
275
Searches an index record.
276
@return whether the record was found or buffered */
274
/* out: record or NULL, if no record found */
275
ulint mode, /* in: BTR_MODIFY_LEAF, ... */
276
const rec_t* rec, /* in: record in a secondary index */
277
dict_index_t* index, /* in: secondary index */
278
dict_index_t** clust_index,/* out: clustered index */
279
mtr_t* mtr); /* in: mtr */
280
/*******************************************************************
281
Searches an index record. */
278
enum row_search_result
279
284
row_search_index_entry(
280
285
/*===================*/
281
dict_index_t* index, /*!< in: index */
282
const dtuple_t* entry, /*!< in: index entry */
283
ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
284
btr_pcur_t* pcur, /*!< in/out: persistent cursor, which must
286
/* out: TRUE if found */
287
dict_index_t* index, /* in: index */
288
const dtuple_t* entry, /* in: index entry */
289
ulint mode, /* in: BTR_MODIFY_LEAF, ... */
290
btr_pcur_t* pcur, /* in/out: persistent cursor, which must
285
291
be closed by the caller */
286
mtr_t* mtr); /*!< in: mtr */
292
mtr_t* mtr); /* in: mtr */
289
295
#define ROW_COPY_DATA 1
297
303
No new latches may be obtained while the kernel mutex is reserved.
298
304
However, the kernel mutex can be reserved while latches are owned. */
300
/*******************************************************************//**
306
/***********************************************************************
301
307
Formats the raw data in "data" (in InnoDB on-disk format) using
302
308
"dict_field" and writes the result to "buf".
303
309
Not more than "buf_size" bytes are written to "buf".
304
The result is always NUL-terminated (provided buf_size is positive) and the
310
The result is always '\0'-terminated (provided buf_size > 0) and the
305
311
number of bytes that were written to "buf" is returned (including the
307
@return number of bytes that were written */
312
terminating '\0'). */
312
const char* data, /*!< in: raw data */
313
ulint data_len, /*!< in: raw data length
317
/* out: number of bytes
319
const char* data, /* in: raw data */
320
ulint data_len, /* in: raw data length
315
const dict_field_t* dict_field, /*!< in: index field */
316
char* buf, /*!< out: output buffer */
317
ulint buf_size); /*!< in: output buffer size
322
const dict_field_t* dict_field, /* in: index field */
323
char* buf, /* out: output buffer */
324
ulint buf_size); /* in: output buffer size
320
327
#ifndef UNIV_NONINL