1
/*****************************************************************************
3
Copyright (C) 1996, 2010, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
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
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/row0row.h
1
/******************************************************
21
2
General row routines
23
6
Created 4/20/1996 Heikki Tuuri
24
7
*******************************************************/
37
20
#include "row0types.h"
38
21
#include "btr0types.h"
40
/*********************************************************************//**
23
/*************************************************************************
41
24
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 */
25
a clustered index record. */
46
28
row_get_trx_id_offset(
47
29
/*==================*/
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 */
30
/* out: offset of DATA_TRX_ID */
31
const rec_t* rec, /* in: record */
32
dict_index_t* index, /* in: clustered index */
33
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
34
/*************************************************************************
35
Reads the trx id field from a clustered index record. */
56
38
row_get_rec_trx_id(
57
39
/*===============*/
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 */
40
/* out: value of the field */
41
const rec_t* rec, /* in: record */
42
dict_index_t* index, /* in: clustered index */
43
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
44
/*************************************************************************
45
Reads the roll pointer field from a clustered index record. */
66
48
row_get_rec_roll_ptr(
67
49
/*=================*/
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
/*****************************************************************//**
50
/* out: value of the field */
51
const rec_t* rec, /* in: record */
52
dict_index_t* index, /* in: clustered index */
53
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
54
/*********************************************************************
72
55
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 */
56
the entry to be inserted into or purged from an index on the table. */
79
59
row_build_index_entry(
80
60
/*==================*/
81
const dtuple_t* row, /*!< in: row which should be
61
/* out: index entry which should be
62
inserted or purged, or NULL if the
63
externally stored columns in the
64
clustered index record are unavailable
66
const dtuple_t* row, /* in: row which should be
82
67
inserted or purged */
83
row_ext_t* ext, /*!< in: externally stored column prefixes,
68
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
70
dict_index_t* index, /* in: index on the table */
71
mem_heap_t* heap); /* in: memory heap from which the memory for
87
72
the index entry is allocated */
88
/*******************************************************************//**
73
/***********************************************************************
89
74
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! */
75
record in a clustered index. */
96
ulint type, /*!< in: ROW_COPY_POINTERS or
80
/* out, own: row built;
81
see the NOTE below! */
82
ulint type, /* in: ROW_COPY_POINTERS or
97
83
ROW_COPY_DATA; the latter
98
84
copies also the data fields to
99
85
heap while the first only
100
86
places pointers to data fields
101
87
on the index page, and thus is
103
const dict_index_t* index, /*!< in: clustered index */
104
const rec_t* rec, /*!< in: record in the clustered
89
const dict_index_t* index, /* in: clustered index */
90
const rec_t* rec, /* in: record in the clustered
105
91
index; NOTE: in the case
106
92
ROW_COPY_POINTERS the data
107
93
fields in the row will point
122
108
consulted instead; the user
123
109
columns in this table should be
124
110
the same columns as in index->table */
125
row_ext_t** ext, /*!< out, own: cache of
111
row_ext_t** ext, /* out, own: cache of
126
112
externally stored column
127
113
prefixes, or NULL */
128
mem_heap_t* heap); /*!< in: memory heap from which
114
mem_heap_t* heap); /* in: memory heap from which
129
115
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 */
116
/***********************************************************************
117
Converts an index record to a typed data tuple. */
136
120
row_rec_to_index_entry_low(
137
121
/*=======================*/
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
122
/* out: index entry built; does not
123
set info_bits, and the data fields in
124
the entry will point directly to rec */
125
const rec_t* rec, /* in: record in the index */
126
const dict_index_t* index, /* in: index */
127
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
128
ulint* n_ext, /* out: number of externally
142
129
stored columns */
143
mem_heap_t* heap); /*!< in: memory heap from which
130
mem_heap_t* heap); /* in: memory heap from which
144
131
the memory needed is allocated */
145
/*******************************************************************//**
132
/***********************************************************************
146
133
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! */
134
stored (often big) fields are NOT copied to heap. */
151
137
row_rec_to_index_entry(
152
138
/*===================*/
153
ulint type, /*!< in: ROW_COPY_DATA, or
139
/* out, own: index entry
140
built; see the NOTE below! */
141
ulint type, /* in: ROW_COPY_DATA, or
154
142
ROW_COPY_POINTERS: the former
155
143
copies also the data fields to
156
144
heap as the latter only places
157
145
pointers to data fields on the
159
const rec_t* rec, /*!< in: record in the index;
147
const rec_t* rec, /* in: record in the index;
160
148
NOTE: in the case
161
149
ROW_COPY_POINTERS the data
162
150
fields in the row will point
165
153
this record must be at least
166
154
s-latched and the latch held
167
155
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
156
const dict_index_t* index, /* in: index */
157
ulint* offsets,/* in/out: rec_get_offsets(rec) */
158
ulint* n_ext, /* out: number of externally
171
159
stored columns */
172
mem_heap_t* heap); /*!< in: memory heap from which
160
mem_heap_t* heap); /* in: memory heap from which
173
161
the memory needed is allocated */
174
/*******************************************************************//**
162
/***********************************************************************
175
163
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! */
164
search the clustered index record. */
180
167
row_build_row_ref(
181
168
/*==============*/
182
ulint type, /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
169
/* out, own: row reference built; see the
171
ulint type, /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
183
172
the former copies also the data fields to
184
173
heap, whereas the latter only places pointers
185
174
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;
175
dict_index_t* index, /* in: secondary index */
176
const rec_t* rec, /* in: record in the index;
188
177
NOTE: in the case ROW_COPY_POINTERS
189
178
the data fields in the row will point
190
179
directly into this record, therefore,
191
180
the buffer page of this record must be
192
181
at least s-latched and the latch held
193
182
as long as the row reference is used! */
194
mem_heap_t* heap); /*!< in: memory heap from which the memory
183
mem_heap_t* heap); /* in: memory heap from which the memory
195
184
needed is allocated */
196
/*******************************************************************//**
185
/***********************************************************************
197
186
Builds from a secondary index record a row reference with which we can
198
187
search the clustered index record. */
201
190
row_build_row_ref_in_tuple(
202
191
/*=======================*/
203
dtuple_t* ref, /*!< in/out: row reference built;
192
dtuple_t* ref, /* in/out: row reference built;
204
193
see the NOTE below! */
205
const rec_t* rec, /*!< in: record in the index;
194
const rec_t* rec, /* in: record in the index;
206
195
NOTE: the data fields in ref
207
196
will point directly into this
208
197
record, therefore, the buffer
210
199
least s-latched and the latch
211
200
held as long as the row
212
201
reference is used! */
213
const dict_index_t* index, /*!< in: secondary index */
214
ulint* offsets,/*!< in: rec_get_offsets(rec, index)
202
const dict_index_t* index, /* in: secondary index */
203
ulint* offsets,/* in: rec_get_offsets(rec, index)
216
trx_t* trx); /*!< in: transaction */
217
/*******************************************************************//**
205
trx_t* trx); /* in: transaction */
206
/***********************************************************************
207
From a row build a row reference with which we can search the clustered
211
row_build_row_ref_from_row(
212
/*=======================*/
213
dtuple_t* ref, /* in/out: row reference built;
215
ref must have the right number
217
const dict_table_t* table, /* in: table */
218
const dtuple_t* row); /* in: row
219
NOTE: the data fields in ref will point
220
directly into data of this row */
221
/***********************************************************************
218
222
Builds from a secondary index record a row reference with which we can
219
223
search the clustered index record. */
222
226
row_build_row_ref_fast(
223
227
/*===================*/
224
dtuple_t* ref, /*!< in/out: typed data tuple where the
228
dtuple_t* ref, /* in/out: typed data tuple where the
225
229
reference is built */
226
const ulint* map, /*!< in: array of field numbers in rec
230
const ulint* map, /* in: array of field numbers in rec
227
231
telling how ref should be built from
228
232
the fields of rec */
229
const rec_t* rec, /*!< in: record in the index; must be
233
const rec_t* rec, /* in: record in the index; must be
230
234
preserved while ref is used, as we do
231
235
not copy field values to heap */
232
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
233
/***************************************************************//**
236
const ulint* offsets);/* in: array returned by rec_get_offsets() */
237
/*******************************************************************
234
238
Searches the clustered index record for a row, if we have the row
236
@return TRUE if found */
239
242
row_search_on_row_ref(
240
243
/*==================*/
241
btr_pcur_t* pcur, /*!< out: persistent cursor, which must
244
/* out: TRUE if found */
245
btr_pcur_t* pcur, /* out: persistent cursor, which must
242
246
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
/*********************************************************************//**
247
ulint mode, /* in: BTR_MODIFY_LEAF, ... */
248
const dict_table_t* table, /* in: table */
249
const dtuple_t* ref, /* in: row reference */
250
mtr_t* mtr); /* in/out: mtr */
251
/*************************************************************************
248
252
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 */
253
on the secondary index record are preserved. */
253
256
row_get_clust_rec(
254
257
/*==============*/
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 */
258
/* out: record or NULL, if no record found */
259
ulint mode, /* in: BTR_MODIFY_LEAF, ... */
260
const rec_t* rec, /* in: record in a secondary index */
261
dict_index_t* index, /* in: secondary index */
262
dict_index_t** clust_index,/* out: clustered index */
263
mtr_t* mtr); /* in: mtr */
264
/*******************************************************************
265
Searches an index record. */
278
enum row_search_result
279
268
row_search_index_entry(
280
269
/*===================*/
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
270
/* out: TRUE if found */
271
dict_index_t* index, /* in: index */
272
const dtuple_t* entry, /* in: index entry */
273
ulint mode, /* in: BTR_MODIFY_LEAF, ... */
274
btr_pcur_t* pcur, /* in/out: persistent cursor, which must
285
275
be closed by the caller */
286
mtr_t* mtr); /*!< in: mtr */
276
mtr_t* mtr); /* in: mtr */
289
279
#define ROW_COPY_DATA 1
297
287
No new latches may be obtained while the kernel mutex is reserved.
298
288
However, the kernel mutex can be reserved while latches are owned. */
300
/*******************************************************************//**
290
/***********************************************************************
301
291
Formats the raw data in "data" (in InnoDB on-disk format) using
302
292
"dict_field" and writes the result to "buf".
303
293
Not more than "buf_size" bytes are written to "buf".
304
The result is always NUL-terminated (provided buf_size is positive) and the
294
The result is always '\0'-terminated (provided buf_size > 0) and the
305
295
number of bytes that were written to "buf" is returned (including the
307
@return number of bytes that were written */
296
terminating '\0'). */
312
const char* data, /*!< in: raw data */
313
ulint data_len, /*!< in: raw data length
301
/* out: number of bytes
303
const char* data, /* in: raw data */
304
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
306
const dict_field_t* dict_field, /* in: index field */
307
char* buf, /* out: output buffer */
308
ulint buf_size); /* in: output buffer size
320
311
#ifndef UNIV_NONINL