1 /*****************************************************************************
3 Copyright (c) 1994, 2011, Oracle and/or its affiliates. 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.,
15 51 Franklin 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"
32 /*********************************************************//**
33 Gets pointer to the page frame where the cursor is positioned.
39 page_cur_t* cur) /*!< in: page cursor */
42 ut_ad(page_align(cur->rec) == cur->block->frame);
44 return(page_align(cur->rec));
47 /*********************************************************//**
48 Gets pointer to the buffer block where the cursor is positioned.
54 page_cur_t* cur) /*!< in: page cursor */
57 ut_ad(page_align(cur->rec) == cur->block->frame);
61 /*********************************************************//**
62 Gets pointer to the page frame where the cursor is positioned.
66 page_cur_get_page_zip(
67 /*==================*/
68 page_cur_t* cur) /*!< in: page cursor */
70 return(buf_block_get_page_zip(page_cur_get_block(cur)));
73 /*********************************************************//**
74 Gets the record where the cursor is positioned.
80 page_cur_t* cur) /*!< in: page cursor */
83 ut_ad(page_align(cur->rec) == cur->block->frame);
87 #endif /* UNIV_DEBUG */
89 /*********************************************************//**
90 Sets the cursor object to point before the first user record
94 page_cur_set_before_first(
95 /*======================*/
96 const buf_block_t* block, /*!< in: index page */
97 page_cur_t* cur) /*!< in: cursor */
99 cur->block = (buf_block_t*) block;
100 cur->rec = page_get_infimum_rec(buf_block_get_frame(cur->block));
103 /*********************************************************//**
104 Sets the cursor object to point after the last user record on
108 page_cur_set_after_last(
109 /*====================*/
110 const buf_block_t* block, /*!< in: index page */
111 page_cur_t* cur) /*!< in: cursor */
113 cur->block = (buf_block_t*) block;
114 cur->rec = page_get_supremum_rec(buf_block_get_frame(cur->block));
117 /*********************************************************//**
118 Returns TRUE if the cursor is before first user record on page.
119 @return TRUE if at start */
122 page_cur_is_before_first(
123 /*=====================*/
124 const page_cur_t* cur) /*!< in: cursor */
127 ut_ad(page_align(cur->rec) == cur->block->frame);
128 return(page_rec_is_infimum(cur->rec));
131 /*********************************************************//**
132 Returns TRUE if the cursor is after last user record.
133 @return TRUE if at end */
136 page_cur_is_after_last(
137 /*===================*/
138 const page_cur_t* cur) /*!< in: cursor */
141 ut_ad(page_align(cur->rec) == cur->block->frame);
142 return(page_rec_is_supremum(cur->rec));
145 /**********************************************************//**
146 Positions the cursor on the given record. */
151 const rec_t* rec, /*!< in: record on a page */
152 const buf_block_t* block, /*!< in: buffer block containing
154 page_cur_t* cur) /*!< out: page cursor */
156 ut_ad(rec && block && cur);
157 ut_ad(page_align(rec) == block->frame);
159 cur->rec = (rec_t*) rec;
160 cur->block = (buf_block_t*) block;
163 /**********************************************************//**
164 Invalidates a page cursor by setting the record pointer NULL. */
169 page_cur_t* cur) /*!< out: page cursor */
177 /**********************************************************//**
178 Moves the cursor to the next record on page. */
181 page_cur_move_to_next(
182 /*==================*/
183 page_cur_t* cur) /*!< in/out: cursor; must not be after last */
185 ut_ad(!page_cur_is_after_last(cur));
187 cur->rec = page_rec_get_next(cur->rec);
190 /**********************************************************//**
191 Moves the cursor to the previous record on page. */
194 page_cur_move_to_prev(
195 /*==================*/
196 page_cur_t* cur) /*!< in/out: page cursor, not before first */
198 ut_ad(!page_cur_is_before_first(cur));
200 cur->rec = page_rec_get_prev(cur->rec);
203 #ifndef UNIV_HOTBACKUP
204 /****************************************************************//**
205 Searches the right position for a page cursor.
206 @return number of matched fields on the left */
211 const buf_block_t* block, /*!< in: buffer block */
212 const dict_index_t* index, /*!< in: record descriptor */
213 const dtuple_t* tuple, /*!< in: data tuple */
214 ulint mode, /*!< in: PAGE_CUR_L,
215 PAGE_CUR_LE, PAGE_CUR_G, or
217 page_cur_t* cursor) /*!< out: page cursor */
219 ulint low_matched_fields = 0;
220 ulint low_matched_bytes = 0;
221 ulint up_matched_fields = 0;
222 ulint up_matched_bytes = 0;
224 ut_ad(dtuple_check_typed(tuple));
226 page_cur_search_with_match(block, index, tuple, mode,
232 return(low_matched_fields);
235 /***********************************************************//**
236 Inserts a record next to page cursor. Returns pointer to inserted record if
237 succeed, i.e., enough space available, NULL otherwise. The cursor stays at
238 the same logical position, but the physical position may change if it is
239 pointing to a compressed page that was reorganized.
240 @return pointer to record if succeed, NULL otherwise */
243 page_cur_tuple_insert(
244 /*==================*/
245 page_cur_t* cursor, /*!< in/out: a page cursor */
246 const dtuple_t* tuple, /*!< in: pointer to a data tuple */
247 dict_index_t* index, /*!< in: record descriptor */
248 ulint n_ext, /*!< in: number of externally stored columns */
249 mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
254 = rec_get_converted_size(index, tuple, n_ext);
257 heap = mem_heap_create(size
258 + (4 + REC_OFFS_HEADER_SIZE
259 + dtuple_get_n_fields(tuple))
261 rec = rec_convert_dtuple_to_rec((byte*) mem_heap_alloc(heap, size),
262 index, tuple, n_ext);
263 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
265 if (buf_block_get_page_zip(cursor->block)) {
266 rec = page_cur_insert_rec_zip(&cursor->rec, cursor->block,
267 index, rec, offsets, mtr);
269 rec = page_cur_insert_rec_low(cursor->rec,
270 index, rec, offsets, mtr);
273 ut_ad(!rec || !cmp_dtuple_rec(tuple, rec, offsets));
277 #endif /* !UNIV_HOTBACKUP */
279 /***********************************************************//**
280 Inserts a record next to page cursor. Returns pointer to inserted record if
281 succeed, i.e., enough space available, NULL otherwise. The cursor stays at
282 the same logical position, but the physical position may change if it is
283 pointing to a compressed page that was reorganized.
284 @return pointer to record if succeed, NULL otherwise */
289 page_cur_t* cursor, /*!< in/out: a page cursor */
290 const rec_t* rec, /*!< in: record to insert */
291 dict_index_t* index, /*!< in: record descriptor */
292 ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
293 mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
295 if (buf_block_get_page_zip(cursor->block)) {
296 return(page_cur_insert_rec_zip(&cursor->rec, cursor->block,
297 index, rec, offsets, mtr));
299 return(page_cur_insert_rec_low(cursor->rec,
300 index, rec, offsets, mtr));