~linuxjedi/drizzle/trunk-bug-667053

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/************************************************************************
The page cursor

(c) 1994-1996 Innobase Oy

Created 10/4/1994 Heikki Tuuri
*************************************************************************/

#ifndef page0cur_h
#define page0cur_h

#include "univ.i"

#include "page0types.h"
#include "page0page.h"
#include "rem0rec.h"
#include "data0data.h"
#include "mtr0mtr.h"


#define PAGE_CUR_ADAPT

/* Page cursor search modes; the values must be in this order! */

#define	PAGE_CUR_UNSUPP	0
#define	PAGE_CUR_G	1
#define	PAGE_CUR_GE	2
#define	PAGE_CUR_L	3
#define	PAGE_CUR_LE	4
/*#define PAGE_CUR_LE_OR_EXTENDS 5*/ /* This is a search mode used in
				 "column LIKE 'abc%' ORDER BY column DESC";
				 we have to find strings which are <= 'abc' or
				 which extend it */
#ifdef UNIV_SEARCH_DEBUG
# define PAGE_CUR_DBG	6	/* As PAGE_CUR_LE, but skips search shortcut */
#endif /* UNIV_SEARCH_DEBUG */

#ifdef PAGE_CUR_ADAPT
# ifdef UNIV_SEARCH_PERF_STAT
extern ulint	page_cur_short_succ;
# endif /* UNIV_SEARCH_PERF_STAT */
#endif /* PAGE_CUR_ADAPT */

/*************************************************************
Gets pointer to the page frame where the cursor is positioned. */
UNIV_INLINE
page_t*
page_cur_get_page(
/*==============*/
				/* out: page */
	page_cur_t*	cur);	/* in: page cursor */
/*************************************************************
Gets the record where the cursor is positioned. */
UNIV_INLINE
rec_t*
page_cur_get_rec(
/*=============*/
				/* out: record */
	page_cur_t*	cur);	/* in: page cursor */
/*************************************************************
Sets the cursor object to point before the first user record
on the page. */
UNIV_INLINE
void
page_cur_set_before_first(
/*======================*/
	page_t*		page,	/* in: index page */
	page_cur_t*	cur);	/* in: cursor */
/*************************************************************
Sets the cursor object to point after the last user record on
the page. */
UNIV_INLINE
void
page_cur_set_after_last(
/*====================*/
	page_t*		page,	/* in: index page */
	page_cur_t*	cur);	/* in: cursor */
/*************************************************************
Returns TRUE if the cursor is before first user record on page. */
UNIV_INLINE
ibool
page_cur_is_before_first(
/*=====================*/
					/* out: TRUE if at start */
	const page_cur_t*	cur);	/* in: cursor */
/*************************************************************
Returns TRUE if the cursor is after last user record. */
UNIV_INLINE
ibool
page_cur_is_after_last(
/*===================*/
					/* out: TRUE if at end */
	const page_cur_t*	cur);	/* in: cursor */
/**************************************************************
Positions the cursor on the given record. */
UNIV_INLINE
void
page_cur_position(
/*==============*/
	rec_t*		rec,	/* in: record on a page */
	page_cur_t*	cur);	/* in: page cursor */
/**************************************************************
Invalidates a page cursor by setting the record pointer NULL. */
UNIV_INLINE
void
page_cur_invalidate(
/*================*/
	page_cur_t*	cur);	/* in: page cursor */
/**************************************************************
Moves the cursor to the next record on page. */
UNIV_INLINE
void
page_cur_move_to_next(
/*==================*/
	page_cur_t*	cur);	/* in: cursor; must not be after last */
/**************************************************************
Moves the cursor to the previous record on page. */
UNIV_INLINE
void
page_cur_move_to_prev(
/*==================*/
	page_cur_t*	cur);	/* in: cursor; must not before first */
/***************************************************************
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same position. */
UNIV_INLINE
rec_t*
page_cur_tuple_insert(
/*==================*/
				/* out: pointer to record if succeed, NULL
				otherwise */
	page_cur_t*	cursor,	/* in: a page cursor */
	dtuple_t*	tuple,	/* in: pointer to a data tuple */
	dict_index_t*	index,	/* in: record descriptor */
	mtr_t*		mtr);	/* in: mini-transaction handle */
/***************************************************************
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same position. */
UNIV_INLINE
rec_t*
page_cur_rec_insert(
/*================*/
				/* out: pointer to record if succeed, NULL
				otherwise */
	page_cur_t*	cursor,	/* in: a page cursor */
	rec_t*		rec,	/* in: record to insert */
	dict_index_t*	index,	/* in: record descriptor */
	ulint*		offsets,/* in: rec_get_offsets(rec, index) */
	mtr_t*		mtr);	/* in: mini-transaction handle */
/***************************************************************
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The record to be
inserted can be in a data tuple or as a physical record. The other parameter
must then be NULL. The cursor stays at the same position. */

rec_t*
page_cur_insert_rec_low(
/*====================*/
				/* out: pointer to record if succeed, NULL
				otherwise */
	page_cur_t*	cursor,	/* in: a page cursor */
	dtuple_t*	tuple,	/* in: pointer to a data tuple or NULL */
	dict_index_t*	index,	/* in: record descriptor */
	rec_t*		rec,	/* in: pointer to a physical record or NULL */
	ulint*		offsets,/* in: rec_get_offsets(rec, index) or NULL */
	mtr_t*		mtr);	/* in: mini-transaction handle */
/*****************************************************************
Copies records from page to a newly created page, from a given record onward,
including that record. Infimum and supremum records are not copied. */

void
page_copy_rec_list_end_to_created_page(
/*===================================*/
	page_t*		new_page,	/* in: index page to copy to */
	page_t*		page,		/* in: index page */
	rec_t*		rec,		/* in: first record to copy */
	dict_index_t*	index,		/* in: record descriptor */
	mtr_t*		mtr);		/* in: mtr */
/***************************************************************
Deletes a record at the page cursor. The cursor is moved to the
next record after the deleted one. */

void
page_cur_delete_rec(
/*================*/
	page_cur_t*	cursor,	/* in: a page cursor */
	dict_index_t*	index,	/* in: record descriptor */
	const ulint*	offsets,/* in: rec_get_offsets(cursor->rec, index) */
	mtr_t*		mtr);	/* in: mini-transaction handle */
/********************************************************************
Searches the right position for a page cursor. */
UNIV_INLINE
ulint
page_cur_search(
/*============*/
				/* out: number of matched fields on the left */
	page_t*		page,	/* in: index page */
	dict_index_t*	index,	/* in: record descriptor */
	dtuple_t*	tuple,	/* in: data tuple */
	ulint		mode,	/* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
				or PAGE_CUR_GE */
	page_cur_t*	cursor);/* out: page cursor */
/********************************************************************
Searches the right position for a page cursor. */

void
page_cur_search_with_match(
/*=======================*/
	page_t*		page,	/* in: index page */
	dict_index_t*	index,	/* in: record descriptor */
	dtuple_t*	tuple,	/* in: data tuple */
	ulint		mode,	/* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
				or PAGE_CUR_GE */
	ulint*		iup_matched_fields,
				/* in/out: already matched fields in upper
				limit record */
	ulint*		iup_matched_bytes,
				/* in/out: already matched bytes in a field
				not yet completely matched */
	ulint*		ilow_matched_fields,
				/* in/out: already matched fields in lower
				limit record */
	ulint*		ilow_matched_bytes,
				/* in/out: already matched bytes in a field
				not yet completely matched */
	page_cur_t*	cursor); /* out: page cursor */
/***************************************************************
Positions a page cursor on a randomly chosen user record on a page. If there
are no user records, sets the cursor on the infimum record. */

void
page_cur_open_on_rnd_user_rec(
/*==========================*/
	page_t*		page,	/* in: page */
	page_cur_t*	cursor);/* in/out: page cursor */
/***************************************************************
Parses a log record of a record insert on a page. */

byte*
page_cur_parse_insert_rec(
/*======================*/
				/* out: end of log record or NULL */
	ibool		is_short,/* in: TRUE if short inserts */
	byte*		ptr,	/* in: buffer */
	byte*		end_ptr,/* in: buffer end */
	dict_index_t*	index,	/* in: record descriptor */
	page_t*		page,	/* in: page or NULL */
	mtr_t*		mtr);	/* in: mtr or NULL */
/**************************************************************
Parses a log record of copying a record list end to a new created page. */

byte*
page_parse_copy_rec_list_to_created_page(
/*=====================================*/
				/* out: end of log record or NULL */
	byte*		ptr,	/* in: buffer */
	byte*		end_ptr,/* in: buffer end */
	dict_index_t*	index,	/* in: record descriptor */
	page_t*		page,	/* in: page or NULL */
	mtr_t*		mtr);	/* in: mtr or NULL */
/***************************************************************
Parses log record of a record delete on a page. */

byte*
page_cur_parse_delete_rec(
/*======================*/
				/* out: pointer to record end or NULL */
	byte*		ptr,	/* in: buffer */
	byte*		end_ptr,/* in: buffer end */
	dict_index_t*	index,	/* in: record descriptor */
	page_t*		page,	/* in: page or NULL */
	mtr_t*		mtr);	/* in: mtr or NULL */

/* Index page cursor */

struct page_cur_struct{
	byte*	rec;	/* pointer to a record on page */
};

#ifndef UNIV_NONINL
#include "page0cur.ic"
#endif

#endif