1
by brian
clean slate |
1 |
/******************************************************
|
2 |
Select
|
|
3 |
||
4 |
(c) 1997 Innobase Oy
|
|
5 |
||
6 |
Created 12/19/1997 Heikki Tuuri
|
|
7 |
*******************************************************/
|
|
8 |
||
9 |
#ifndef row0sel_h
|
|
10 |
#define row0sel_h
|
|
11 |
||
12 |
#include "univ.i" |
|
13 |
#include "data0data.h" |
|
14 |
#include "que0types.h" |
|
15 |
#include "dict0types.h" |
|
16 |
#include "trx0types.h" |
|
17 |
#include "row0types.h" |
|
18 |
#include "que0types.h" |
|
19 |
#include "pars0sym.h" |
|
20 |
#include "btr0pcur.h" |
|
21 |
#include "read0read.h" |
|
22 |
#include "row0mysql.h" |
|
23 |
||
24 |
/*************************************************************************
|
|
25 |
Creates a select node struct. */
|
|
26 |
||
27 |
sel_node_t* |
|
28 |
sel_node_create( |
|
29 |
/*============*/
|
|
30 |
/* out, own: select node struct */
|
|
31 |
mem_heap_t* heap); /* in: memory heap where created */ |
|
32 |
/*************************************************************************
|
|
33 |
Frees the memory private to a select node when a query graph is freed,
|
|
34 |
does not free the heap where the node was originally created. */
|
|
35 |
||
36 |
void
|
|
37 |
sel_node_free_private( |
|
38 |
/*==================*/
|
|
39 |
sel_node_t* node); /* in: select node struct */ |
|
40 |
/*************************************************************************
|
|
41 |
Frees a prefetch buffer for a column, including the dynamically allocated
|
|
42 |
memory for data stored there. */
|
|
43 |
||
44 |
void
|
|
45 |
sel_col_prefetch_buf_free( |
|
46 |
/*======================*/
|
|
47 |
sel_buf_t* prefetch_buf); /* in, own: prefetch buffer */ |
|
48 |
/*************************************************************************
|
|
49 |
Gets the plan node for the nth table in a join. */
|
|
50 |
UNIV_INLINE
|
|
51 |
plan_t* |
|
52 |
sel_node_get_nth_plan( |
|
53 |
/*==================*/
|
|
54 |
sel_node_t* node, |
|
55 |
ulint i); |
|
56 |
/**************************************************************************
|
|
57 |
Performs a select step. This is a high-level function used in SQL execution
|
|
58 |
graphs. */
|
|
59 |
||
60 |
que_thr_t* |
|
61 |
row_sel_step( |
|
62 |
/*=========*/
|
|
63 |
/* out: query thread to run next or NULL */
|
|
64 |
que_thr_t* thr); /* in: query thread */ |
|
65 |
/**************************************************************************
|
|
66 |
Performs an execution step of an open or close cursor statement node. */
|
|
67 |
UNIV_INLINE
|
|
68 |
que_thr_t* |
|
69 |
open_step( |
|
70 |
/*======*/
|
|
71 |
/* out: query thread to run next or NULL */
|
|
72 |
que_thr_t* thr); /* in: query thread */ |
|
73 |
/**************************************************************************
|
|
74 |
Performs a fetch for a cursor. */
|
|
75 |
||
76 |
que_thr_t* |
|
77 |
fetch_step( |
|
78 |
/*=======*/
|
|
79 |
/* out: query thread to run next or NULL */
|
|
80 |
que_thr_t* thr); /* in: query thread */ |
|
81 |
/********************************************************************
|
|
82 |
Sample callback function for fetch that prints each row.*/
|
|
83 |
||
84 |
void* |
|
85 |
row_fetch_print( |
|
86 |
/*============*/
|
|
87 |
/* out: always returns non-NULL */
|
|
88 |
void* row, /* in: sel_node_t* */ |
|
89 |
void* user_arg); /* in: not used */ |
|
90 |
/********************************************************************
|
|
91 |
Callback function for fetch that stores an unsigned 4 byte integer to the
|
|
92 |
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
|
|
93 |
= 4. */
|
|
94 |
||
95 |
void* |
|
96 |
row_fetch_store_uint4( |
|
97 |
/*==================*/
|
|
98 |
/* out: always returns NULL */
|
|
99 |
void* row, /* in: sel_node_t* */ |
|
100 |
void* user_arg); /* in: data pointer */ |
|
101 |
/***************************************************************
|
|
102 |
Prints a row in a select result. */
|
|
103 |
||
104 |
que_thr_t* |
|
105 |
row_printf_step( |
|
106 |
/*============*/
|
|
107 |
/* out: query thread to run next or NULL */
|
|
108 |
que_thr_t* thr); /* in: query thread */ |
|
109 |
/********************************************************************
|
|
110 |
Converts a key value stored in MySQL format to an Innobase dtuple. The last
|
|
111 |
field of the key value may be just a prefix of a fixed length field: hence
|
|
112 |
the parameter key_len. But currently we do not allow search keys where the
|
|
113 |
last field is only a prefix of the full key field len and print a warning if
|
|
114 |
such appears. */
|
|
115 |
||
116 |
void
|
|
117 |
row_sel_convert_mysql_key_to_innobase( |
|
118 |
/*==================================*/
|
|
119 |
dtuple_t* tuple, /* in: tuple where to build; |
|
120 |
NOTE: we assume that the type info
|
|
121 |
in the tuple is already according
|
|
122 |
to index! */
|
|
123 |
byte* buf, /* in: buffer to use in field |
|
124 |
conversions */
|
|
125 |
ulint buf_len, /* in: buffer length */ |
|
126 |
dict_index_t* index, /* in: index of the key value */ |
|
127 |
byte* key_ptr, /* in: MySQL key value */ |
|
128 |
ulint key_len, /* in: MySQL key value length */ |
|
129 |
trx_t* trx); /* in: transaction */ |
|
130 |
/************************************************************************
|
|
131 |
Searches for rows in the database. This is used in the interface to
|
|
132 |
MySQL. This function opens a cursor, and also implements fetch next
|
|
133 |
and fetch prev. NOTE that if we do a search with a full key value
|
|
134 |
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
|
|
135 |
position and fetch next or fetch prev must not be tried to the cursor! */
|
|
136 |
||
137 |
ulint
|
|
138 |
row_search_for_mysql( |
|
139 |
/*=================*/
|
|
140 |
/* out: DB_SUCCESS,
|
|
141 |
DB_RECORD_NOT_FOUND,
|
|
142 |
DB_END_OF_INDEX, DB_DEADLOCK,
|
|
143 |
DB_LOCK_TABLE_FULL,
|
|
144 |
or DB_TOO_BIG_RECORD */
|
|
145 |
byte* buf, /* in/out: buffer for the fetched |
|
146 |
row in the MySQL format */
|
|
147 |
ulint mode, /* in: search mode PAGE_CUR_L, ... */ |
|
148 |
row_prebuilt_t* prebuilt, /* in: prebuilt struct for the |
|
149 |
table handle; this contains the info
|
|
150 |
of search_tuple, index; if search
|
|
151 |
tuple contains 0 fields then we
|
|
152 |
position the cursor at the start or
|
|
153 |
the end of the index, depending on
|
|
154 |
'mode' */
|
|
155 |
ulint match_mode, /* in: 0 or ROW_SEL_EXACT or |
|
156 |
ROW_SEL_EXACT_PREFIX */
|
|
157 |
ulint direction); /* in: 0 or ROW_SEL_NEXT or |
|
158 |
ROW_SEL_PREV; NOTE: if this is != 0,
|
|
159 |
then prebuilt must have a pcur
|
|
160 |
with stored position! In opening of a
|
|
161 |
cursor 'direction' should be 0. */
|
|
162 |
/***********************************************************************
|
|
163 |
Checks if MySQL at the moment is allowed for this table to retrieve a
|
|
164 |
consistent read result, or store it to the query cache. */
|
|
165 |
||
166 |
ibool
|
|
167 |
row_search_check_if_query_cache_permitted( |
|
168 |
/*======================================*/
|
|
169 |
/* out: TRUE if storing or retrieving
|
|
170 |
from the query cache is permitted */
|
|
171 |
trx_t* trx, /* in: transaction object */ |
|
172 |
const char* norm_name); /* in: concatenation of database name, |
|
173 |
'/' char, table name */
|
|
174 |
/***********************************************************************
|
|
175 |
Read the max AUTOINC value from an index. */
|
|
176 |
||
177 |
ulint
|
|
178 |
row_search_max_autoinc( |
|
179 |
/*===================*/
|
|
180 |
/* out: DB_SUCCESS if all OK else
|
|
181 |
error code */
|
|
182 |
dict_index_t* index, /* in: index to search */ |
|
183 |
const char* col_name, /* in: autoinc column name */ |
|
184 |
ib_longlong* value); /* out: AUTOINC value read */ |
|
185 |
||
186 |
/* A structure for caching column values for prefetched rows */
|
|
187 |
struct sel_buf_struct{ |
|
188 |
byte* data; /* data, or NULL; if not NULL, this field |
|
189 |
has allocated memory which must be explicitly
|
|
190 |
freed; can be != NULL even when len is
|
|
191 |
UNIV_SQL_NULL */
|
|
192 |
ulint len; /* data length or UNIV_SQL_NULL */ |
|
193 |
ulint val_buf_size; |
|
194 |
/* size of memory buffer allocated for data:
|
|
195 |
this can be more than len; this is defined
|
|
196 |
when data != NULL */
|
|
197 |
};
|
|
198 |
||
199 |
struct plan_struct{ |
|
200 |
dict_table_t* table; /* table struct in the dictionary |
|
201 |
cache */
|
|
202 |
dict_index_t* index; /* table index used in the search */ |
|
203 |
btr_pcur_t pcur; /* persistent cursor used to search |
|
204 |
the index */
|
|
205 |
ibool asc; /* TRUE if cursor traveling upwards */ |
|
206 |
ibool pcur_is_open; /* TRUE if pcur has been positioned |
|
207 |
and we can try to fetch new rows */
|
|
208 |
ibool cursor_at_end; /* TRUE if the cursor is open but |
|
209 |
we know that there are no more
|
|
210 |
qualifying rows left to retrieve from
|
|
211 |
the index tree; NOTE though, that
|
|
212 |
there may still be unprocessed rows in
|
|
213 |
the prefetch stack; always FALSE when
|
|
214 |
pcur_is_open is FALSE */
|
|
215 |
ibool stored_cursor_rec_processed; |
|
216 |
/* TRUE if the pcur position has been
|
|
217 |
stored and the record it is positioned
|
|
218 |
on has already been processed */
|
|
219 |
que_node_t** tuple_exps; /* array of expressions which are used |
|
220 |
to calculate the field values in the
|
|
221 |
search tuple: there is one expression
|
|
222 |
for each field in the search tuple */
|
|
223 |
dtuple_t* tuple; /* search tuple */ |
|
224 |
ulint mode; /* search mode: PAGE_CUR_G, ... */ |
|
225 |
ulint n_exact_match; /* number of first fields in the search |
|
226 |
tuple which must be exactly matched */
|
|
227 |
ibool unique_search; /* TRUE if we are searching an |
|
228 |
index record with a unique key */
|
|
229 |
ulint n_rows_fetched; /* number of rows fetched using pcur |
|
230 |
after it was opened */
|
|
231 |
ulint n_rows_prefetched;/* number of prefetched rows cached |
|
232 |
for fetch: fetching several rows in
|
|
233 |
the same mtr saves CPU time */
|
|
234 |
ulint first_prefetched;/* index of the first cached row in |
|
235 |
select buffer arrays for each column */
|
|
236 |
ibool no_prefetch; /* no prefetch for this table */ |
|
237 |
sym_node_list_t columns; /* symbol table nodes for the columns |
|
238 |
to retrieve from the table */
|
|
239 |
UT_LIST_BASE_NODE_T(func_node_t) |
|
240 |
end_conds; /* conditions which determine the |
|
241 |
fetch limit of the index segment we
|
|
242 |
have to look at: when one of these
|
|
243 |
fails, the result set has been
|
|
244 |
exhausted for the cursor in this
|
|
245 |
index; these conditions are normalized
|
|
246 |
so that in a comparison the column
|
|
247 |
for this table is the first argument */
|
|
248 |
UT_LIST_BASE_NODE_T(func_node_t) |
|
249 |
other_conds; /* the rest of search conditions we can |
|
250 |
test at this table in a join */
|
|
251 |
ibool must_get_clust; /* TRUE if index is a non-clustered |
|
252 |
index and we must also fetch the
|
|
253 |
clustered index record; this is the
|
|
254 |
case if the non-clustered record does
|
|
255 |
not contain all the needed columns, or
|
|
256 |
if this is a single-table explicit
|
|
257 |
cursor, or a searched update or
|
|
258 |
delete */
|
|
259 |
ulint* clust_map; /* map telling how clust_ref is built |
|
260 |
from the fields of a non-clustered
|
|
261 |
record */
|
|
262 |
dtuple_t* clust_ref; /* the reference to the clustered |
|
263 |
index entry is built here if index is
|
|
264 |
a non-clustered index */
|
|
265 |
btr_pcur_t clust_pcur; /* if index is non-clustered, we use |
|
266 |
this pcur to search the clustered
|
|
267 |
index */
|
|
268 |
mem_heap_t* old_vers_heap; /* memory heap used in building an old |
|
269 |
version of a row, or NULL */
|
|
270 |
};
|
|
271 |
||
272 |
struct sel_node_struct{ |
|
273 |
que_common_t common; /* node type: QUE_NODE_SELECT */ |
|
274 |
ulint state; /* node state */ |
|
275 |
que_node_t* select_list; /* select list */ |
|
276 |
sym_node_t* into_list; /* variables list or NULL */ |
|
277 |
sym_node_t* table_list; /* table list */ |
|
278 |
ibool asc; /* TRUE if the rows should be fetched |
|
279 |
in an ascending order */
|
|
280 |
ibool set_x_locks; /* TRUE if the cursor is for update or |
|
281 |
delete, which means that a row x-lock
|
|
282 |
should be placed on the cursor row */
|
|
283 |
ibool select_will_do_update; |
|
284 |
/* TRUE if the select is for a searched
|
|
285 |
update which can be performed in-place:
|
|
286 |
in this case the select will take care
|
|
287 |
of the update */
|
|
288 |
ulint latch_mode; /* BTR_SEARCH_LEAF, or BTR_MODIFY_LEAF |
|
289 |
if select_will_do_update is TRUE */
|
|
290 |
ulint row_lock_mode; /* LOCK_X or LOCK_S */ |
|
291 |
ulint n_tables; /* number of tables */ |
|
292 |
ulint fetch_table; /* number of the next table to access |
|
293 |
in the join */
|
|
294 |
plan_t* plans; /* array of n_tables many plan nodes |
|
295 |
containing the search plan and the
|
|
296 |
search data structures */
|
|
297 |
que_node_t* search_cond; /* search condition */ |
|
298 |
read_view_t* read_view; /* if the query is a non-locking |
|
299 |
consistent read, its read view is
|
|
300 |
placed here, otherwise NULL */
|
|
301 |
ibool consistent_read;/* TRUE if the select is a consistent, |
|
302 |
non-locking read */
|
|
303 |
order_node_t* order_by; /* order by column definition, or |
|
304 |
NULL */
|
|
305 |
ibool is_aggregate; /* TRUE if the select list consists of |
|
306 |
aggregate functions */
|
|
307 |
ibool aggregate_already_fetched; |
|
308 |
/* TRUE if the aggregate row has
|
|
309 |
already been fetched for the current
|
|
310 |
cursor */
|
|
311 |
ibool can_get_updated;/* this is TRUE if the select |
|
312 |
is in a single-table explicit
|
|
313 |
cursor which can get updated
|
|
314 |
within the stored procedure,
|
|
315 |
or in a searched update or
|
|
316 |
delete; NOTE that to determine
|
|
317 |
of an explicit cursor if it
|
|
318 |
can get updated, the parser
|
|
319 |
checks from a stored procedure
|
|
320 |
if it contains positioned
|
|
321 |
update or delete statements */
|
|
322 |
sym_node_t* explicit_cursor;/* not NULL if an explicit cursor */ |
|
323 |
UT_LIST_BASE_NODE_T(sym_node_t) |
|
324 |
copy_variables; /* variables whose values we have to |
|
325 |
copy when an explicit cursor is opened,
|
|
326 |
so that they do not change between
|
|
327 |
fetches */
|
|
328 |
};
|
|
329 |
||
330 |
/* Select node states */
|
|
331 |
#define SEL_NODE_CLOSED 0 /* it is a declared cursor which is not |
|
332 |
currently open */
|
|
333 |
#define SEL_NODE_OPEN 1 /* intention locks not yet set on |
|
334 |
tables */
|
|
335 |
#define SEL_NODE_FETCH 2 /* intention locks have been set */ |
|
336 |
#define SEL_NODE_NO_MORE_ROWS 3 /* cursor has reached the result set |
|
337 |
end */
|
|
338 |
||
339 |
/* Fetch statement node */
|
|
340 |
struct fetch_node_struct{ |
|
341 |
que_common_t common; /* type: QUE_NODE_FETCH */ |
|
342 |
sel_node_t* cursor_def; /* cursor definition */ |
|
343 |
sym_node_t* into_list; /* variables to set */ |
|
344 |
||
345 |
pars_user_func_t* |
|
346 |
func; /* User callback function or NULL. |
|
347 |
The first argument to the function
|
|
348 |
is a sel_node_t*, containing the
|
|
349 |
results of the SELECT operation for
|
|
350 |
one row. If the function returns
|
|
351 |
NULL, it is not interested in
|
|
352 |
further rows and the cursor is
|
|
353 |
modified so (cursor % NOTFOUND) is
|
|
354 |
true. If it returns not-NULL,
|
|
355 |
continue normally. See
|
|
356 |
row_fetch_print() for an example
|
|
357 |
(and a useful debugging tool). */
|
|
358 |
};
|
|
359 |
||
360 |
/* Open or close cursor statement node */
|
|
361 |
struct open_node_struct{ |
|
362 |
que_common_t common; /* type: QUE_NODE_OPEN */ |
|
363 |
ulint op_type; /* ROW_SEL_OPEN_CURSOR or |
|
364 |
ROW_SEL_CLOSE_CURSOR */
|
|
365 |
sel_node_t* cursor_def; /* cursor definition */ |
|
366 |
};
|
|
367 |
||
368 |
/* Row printf statement node */
|
|
369 |
struct row_printf_node_struct{ |
|
370 |
que_common_t common; /* type: QUE_NODE_ROW_PRINTF */ |
|
371 |
sel_node_t* sel_node; /* select */ |
|
372 |
};
|
|
373 |
||
374 |
#define ROW_SEL_OPEN_CURSOR 0
|
|
375 |
#define ROW_SEL_CLOSE_CURSOR 1
|
|
376 |
||
377 |
/* Flags for the MySQL interface */
|
|
378 |
#define ROW_SEL_NEXT 1
|
|
379 |
#define ROW_SEL_PREV 2
|
|
380 |
||
381 |
#define ROW_SEL_EXACT 1 /* search using a complete key value */ |
|
382 |
#define ROW_SEL_EXACT_PREFIX 2 /* search using a key prefix which |
|
383 |
must match to rows: the prefix may
|
|
384 |
contain an incomplete field (the
|
|
385 |
last field in prefix may be just
|
|
386 |
a prefix of a fixed length column) */
|
|
387 |
||
388 |
#ifndef UNIV_NONINL
|
|
389 |
#include "row0sel.ic" |
|
390 |
#endif
|
|
391 |
||
392 |
#endif
|