1
/*****************************************************************************
3
Copyright (c) 1994, 2009, 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/page0cur.ic
23
Created 10/4/1994 Heikki Tuuri
24
*************************************************************************/
26
#include "page0page.h"
27
#include "buf0types.h"
30
/*********************************************************//**
31
Gets pointer to the page frame where the cursor is positioned.
37
page_cur_t* cur) /*!< in: page cursor */
40
ut_ad(page_align(cur->rec) == cur->block->frame);
42
return(page_align(cur->rec));
45
/*********************************************************//**
46
Gets pointer to the buffer block where the cursor is positioned.
52
page_cur_t* cur) /*!< in: page cursor */
55
ut_ad(page_align(cur->rec) == cur->block->frame);
59
/*********************************************************//**
60
Gets pointer to the page frame where the cursor is positioned.
64
page_cur_get_page_zip(
65
/*==================*/
66
page_cur_t* cur) /*!< in: page cursor */
68
return(buf_block_get_page_zip(page_cur_get_block(cur)));
71
/*********************************************************//**
72
Gets the record where the cursor is positioned.
78
page_cur_t* cur) /*!< in: page cursor */
81
ut_ad(page_align(cur->rec) == cur->block->frame);
85
#endif /* UNIV_DEBUG */
87
/*********************************************************//**
88
Sets the cursor object to point before the first user record
92
page_cur_set_before_first(
93
/*======================*/
94
const buf_block_t* block, /*!< in: index page */
95
page_cur_t* cur) /*!< in: cursor */
97
cur->block = (buf_block_t*) block;
98
cur->rec = page_get_infimum_rec(buf_block_get_frame(cur->block));
101
/*********************************************************//**
102
Sets the cursor object to point after the last user record on
106
page_cur_set_after_last(
107
/*====================*/
108
const buf_block_t* block, /*!< in: index page */
109
page_cur_t* cur) /*!< in: cursor */
111
cur->block = (buf_block_t*) block;
112
cur->rec = page_get_supremum_rec(buf_block_get_frame(cur->block));
115
/*********************************************************//**
116
Returns TRUE if the cursor is before first user record on page.
117
@return TRUE if at start */
120
page_cur_is_before_first(
121
/*=====================*/
122
const page_cur_t* cur) /*!< in: cursor */
125
ut_ad(page_align(cur->rec) == cur->block->frame);
126
return(page_rec_is_infimum(cur->rec));
129
/*********************************************************//**
130
Returns TRUE if the cursor is after last user record.
131
@return TRUE if at end */
134
page_cur_is_after_last(
135
/*===================*/
136
const page_cur_t* cur) /*!< in: cursor */
139
ut_ad(page_align(cur->rec) == cur->block->frame);
140
return(page_rec_is_supremum(cur->rec));
143
/**********************************************************//**
144
Positions the cursor on the given record. */
149
const rec_t* rec, /*!< in: record on a page */
150
const buf_block_t* block, /*!< in: buffer block containing
152
page_cur_t* cur) /*!< out: page cursor */
154
ut_ad(rec && block && cur);
155
ut_ad(page_align(rec) == block->frame);
157
cur->rec = (rec_t*) rec;
158
cur->block = (buf_block_t*) block;
161
/**********************************************************//**
162
Invalidates a page cursor by setting the record pointer NULL. */
167
page_cur_t* cur) /*!< out: page cursor */
175
/**********************************************************//**
176
Moves the cursor to the next record on page. */
179
page_cur_move_to_next(
180
/*==================*/
181
page_cur_t* cur) /*!< in/out: cursor; must not be after last */
183
ut_ad(!page_cur_is_after_last(cur));
185
cur->rec = page_rec_get_next(cur->rec);
188
/**********************************************************//**
189
Moves the cursor to the previous record on page. */
192
page_cur_move_to_prev(
193
/*==================*/
194
page_cur_t* cur) /*!< in/out: page cursor, not before first */
196
ut_ad(!page_cur_is_before_first(cur));
198
cur->rec = page_rec_get_prev(cur->rec);
201
#ifndef UNIV_HOTBACKUP
202
/****************************************************************//**
203
Searches the right position for a page cursor.
204
@return number of matched fields on the left */
209
const buf_block_t* block, /*!< in: buffer block */
210
const dict_index_t* index, /*!< in: record descriptor */
211
const dtuple_t* tuple, /*!< in: data tuple */
212
ulint mode, /*!< in: PAGE_CUR_L,
213
PAGE_CUR_LE, PAGE_CUR_G, or
215
page_cur_t* cursor) /*!< out: page cursor */
217
ulint low_matched_fields = 0;
218
ulint low_matched_bytes = 0;
219
ulint up_matched_fields = 0;
220
ulint up_matched_bytes = 0;
222
ut_ad(dtuple_check_typed(tuple));
224
page_cur_search_with_match(block, index, tuple, mode,
230
return(low_matched_fields);
233
/***********************************************************//**
234
Inserts a record next to page cursor. Returns pointer to inserted record if
235
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
236
the same logical position, but the physical position may change if it is
237
pointing to a compressed page that was reorganized.
238
@return pointer to record if succeed, NULL otherwise */
241
page_cur_tuple_insert(
242
/*==================*/
243
page_cur_t* cursor, /*!< in/out: a page cursor */
244
const dtuple_t* tuple, /*!< in: pointer to a data tuple */
245
dict_index_t* index, /*!< in: record descriptor */
246
ulint n_ext, /*!< in: number of externally stored columns */
247
mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
252
= rec_get_converted_size(index, tuple, n_ext);
255
heap = mem_heap_create(size
256
+ (4 + REC_OFFS_HEADER_SIZE
257
+ dtuple_get_n_fields(tuple))
259
rec = rec_convert_dtuple_to_rec((byte*) mem_heap_alloc(heap, size),
260
index, tuple, n_ext);
261
offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
263
if (buf_block_get_page_zip(cursor->block)) {
264
rec = page_cur_insert_rec_zip(&cursor->rec, cursor->block,
265
index, rec, offsets, mtr);
267
rec = page_cur_insert_rec_low(cursor->rec,
268
index, rec, offsets, mtr);
274
#endif /* !UNIV_HOTBACKUP */
276
/***********************************************************//**
277
Inserts a record next to page cursor. Returns pointer to inserted record if
278
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
279
the same logical position, but the physical position may change if it is
280
pointing to a compressed page that was reorganized.
281
@return pointer to record if succeed, NULL otherwise */
286
page_cur_t* cursor, /*!< in/out: a page cursor */
287
const rec_t* rec, /*!< in: record to insert */
288
dict_index_t* index, /*!< in: record descriptor */
289
ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
290
mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
292
if (buf_block_get_page_zip(cursor->block)) {
293
return(page_cur_insert_rec_zip(&cursor->rec, cursor->block,
294
index, rec, offsets, mtr));
296
return(page_cur_insert_rec_low(cursor->rec,
297
index, rec, offsets, mtr));