1/*****************************************************************************
2
3Copyright (c) 1997, 2017, Oracle and/or its affiliates.
4Copyright (c) 2017, MariaDB Corporation.
5
6This program is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free Software
8Foundation; version 2 of the License.
9
10This program is distributed in the hope that it will be useful, but WITHOUT
11ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program; if not, write to the Free Software Foundation, Inc.,
1651 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
18*****************************************************************************/
19
20/**************************************************//**
21@file include/row0sel.h
22Select
23
24Created 12/19/1997 Heikki Tuuri
25*******************************************************/
26
27#ifndef row0sel_h
28#define row0sel_h
29
30#include "univ.i"
31#include "data0data.h"
32#include "que0types.h"
33#include "dict0types.h"
34#include "trx0types.h"
35#include "read0types.h"
36#include "row0types.h"
37#include "que0types.h"
38#include "pars0sym.h"
39#include "btr0pcur.h"
40#include "row0mysql.h"
41
42/*********************************************************************//**
43Creates a select node struct.
44@return own: select node struct */
45sel_node_t*
46sel_node_create(
47/*============*/
48 mem_heap_t* heap); /*!< in: memory heap where created */
49/*********************************************************************//**
50Frees the memory private to a select node when a query graph is freed,
51does not free the heap where the node was originally created. */
52void
53sel_node_free_private(
54/*==================*/
55 sel_node_t* node); /*!< in: select node struct */
56/*********************************************************************//**
57Frees a prefetch buffer for a column, including the dynamically allocated
58memory for data stored there. */
59void
60sel_col_prefetch_buf_free(
61/*======================*/
62 sel_buf_t* prefetch_buf); /*!< in, own: prefetch buffer */
63/*********************************************************************//**
64Gets the plan node for the nth table in a join.
65@return plan node */
66UNIV_INLINE
67plan_t*
68sel_node_get_nth_plan(
69/*==================*/
70 sel_node_t* node, /*!< in: select node */
71 ulint i); /*!< in: get ith plan node */
72/**********************************************************************//**
73Performs a select step. This is a high-level function used in SQL execution
74graphs.
75@return query thread to run next or NULL */
76que_thr_t*
77row_sel_step(
78/*=========*/
79 que_thr_t* thr); /*!< in: query thread */
80/**********************************************************************//**
81Performs an execution step of an open or close cursor statement node.
82@return query thread to run next or NULL */
83UNIV_INLINE
84que_thr_t*
85open_step(
86/*======*/
87 que_thr_t* thr); /*!< in: query thread */
88/**********************************************************************//**
89Performs a fetch for a cursor.
90@return query thread to run next or NULL */
91que_thr_t*
92fetch_step(
93/*=======*/
94 que_thr_t* thr); /*!< in: query thread */
95/***********************************************************//**
96Prints a row in a select result.
97@return query thread to run next or NULL */
98que_thr_t*
99row_printf_step(
100/*============*/
101 que_thr_t* thr); /*!< in: query thread */
102
103/** Copy used fields from cached row.
104Copy cache record field by field, don't touch fields that
105are not covered by current key.
106@param[out] buf Where to copy the MySQL row.
107@param[in] cached_rec What to copy (in MySQL row format).
108@param[in] prebuilt prebuilt struct. */
109void
110row_sel_copy_cached_fields_for_mysql(
111 byte* buf,
112 const byte* cached_rec,
113 row_prebuilt_t* prebuilt);
114
115/****************************************************************//**
116Converts a key value stored in MySQL format to an Innobase dtuple. The last
117field of the key value may be just a prefix of a fixed length field: hence
118the parameter key_len. But currently we do not allow search keys where the
119last field is only a prefix of the full key field len and print a warning if
120such appears. */
121void
122row_sel_convert_mysql_key_to_innobase(
123/*==================================*/
124 dtuple_t* tuple, /*!< in/out: tuple where to build;
125 NOTE: we assume that the type info
126 in the tuple is already according
127 to index! */
128 byte* buf, /*!< in: buffer to use in field
129 conversions; NOTE that dtuple->data
130 may end up pointing inside buf so
131 do not discard that buffer while
132 the tuple is being used. See
133 row_mysql_store_col_in_innobase_format()
134 in the case of DATA_INT */
135 ulint buf_len, /*!< in: buffer length */
136 dict_index_t* index, /*!< in: index of the key value */
137 const byte* key_ptr, /*!< in: MySQL key value */
138 ulint key_len); /*!< in: MySQL key value length */
139
140
141/** Searches for rows in the database. This is used in the interface to
142MySQL. This function opens a cursor, and also implements fetch next
143and fetch prev. NOTE that if we do a search with a full key value
144from a unique index (ROW_SEL_EXACT), then we will not store the cursor
145position and fetch next or fetch prev must not be tried to the cursor!
146
147@param[out] buf buffer for the fetched row in MySQL format
148@param[in] mode search mode PAGE_CUR_L
149@param[in,out] prebuilt prebuilt struct for the table handler;
150 this contains the info to search_tuple,
151 index; if search tuple contains 0 field then
152 we position the cursor at start or the end of
153 index, depending on 'mode'
154@param[in] match_mode 0 or ROW_SEL_EXACT or ROW_SEL_EXACT_PREFIX
155@param[in] direction 0 or ROW_SEL_NEXT or ROW_SEL_PREV;
156 Note: if this is != 0, then prebuilt must has a
157 pcur with stored position! In opening of a
158 cursor 'direction' should be 0.
159@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK,
160DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */
161UNIV_INLINE
162dberr_t
163row_search_for_mysql(
164 byte* buf,
165 page_cur_mode_t mode,
166 row_prebuilt_t* prebuilt,
167 ulint match_mode,
168 ulint direction)
169 MY_ATTRIBUTE((warn_unused_result));
170
171/** Searches for rows in the database using cursor.
172Function is mainly used for tables that are shared across connections and
173so it employs technique that can help re-construct the rows that
174transaction is suppose to see.
175It also has optimization such as pre-caching the rows, using AHI, etc.
176
177@param[out] buf buffer for the fetched row in MySQL format
178@param[in] mode search mode PAGE_CUR_L
179@param[in,out] prebuilt prebuilt struct for the table handler;
180 this contains the info to search_tuple,
181 index; if search tuple contains 0 field then
182 we position the cursor at start or the end of
183 index, depending on 'mode'
184@param[in] match_mode 0 or ROW_SEL_EXACT or ROW_SEL_EXACT_PREFIX
185@param[in] direction 0 or ROW_SEL_NEXT or ROW_SEL_PREV;
186 Note: if this is != 0, then prebuilt must has a
187 pcur with stored position! In opening of a
188 cursor 'direction' should be 0.
189@return DB_SUCCESS or error code */
190dberr_t
191row_search_mvcc(
192 byte* buf,
193 page_cur_mode_t mode,
194 row_prebuilt_t* prebuilt,
195 ulint match_mode,
196 ulint direction)
197 MY_ATTRIBUTE((warn_unused_result));
198
199/********************************************************************//**
200Count rows in a R-Tree leaf level.
201@return DB_SUCCESS if successful */
202dberr_t
203row_count_rtree_recs(
204/*=================*/
205 row_prebuilt_t* prebuilt, /*!< in: prebuilt struct for the
206 table handle; this contains the info
207 of search_tuple, index; if search
208 tuple contains 0 fields then we
209 position the cursor at the start or
210 the end of the index, depending on
211 'mode' */
212 ulint* n_rows); /*!< out: number of entries
213 seen in the consistent read */
214
215/*******************************************************************//**
216Checks if MySQL at the moment is allowed for this table to retrieve a
217consistent read result, or store it to the query cache.
218@return whether storing or retrieving from the query cache is permitted */
219bool
220row_search_check_if_query_cache_permitted(
221/*======================================*/
222 trx_t* trx, /*!< in: transaction object */
223 const char* norm_name); /*!< in: concatenation of database name,
224 '/' char, table name */
225/** Read the max AUTOINC value from an index.
226@param[in] index index starting with an AUTO_INCREMENT column
227@return the largest AUTO_INCREMENT value
228@retval 0 if no records were found */
229ib_uint64_t
230row_search_max_autoinc(dict_index_t* index)
231 MY_ATTRIBUTE((nonnull, warn_unused_result));
232
233/** A structure for caching column values for prefetched rows */
234struct sel_buf_t{
235 byte* data; /*!< data, or NULL; if not NULL, this field
236 has allocated memory which must be explicitly
237 freed; can be != NULL even when len is
238 UNIV_SQL_NULL */
239 ulint len; /*!< data length or UNIV_SQL_NULL */
240 ulint val_buf_size;
241 /*!< size of memory buffer allocated for data:
242 this can be more than len; this is defined
243 when data != NULL */
244};
245
246/** Copy used fields from cached row.
247Copy cache record field by field, don't touch fields that
248are not covered by current key.
249@param[out] buf Where to copy the MySQL row.
250@param[in] cached_rec What to copy (in MySQL row format).
251@param[in] prebuilt prebuilt struct. */
252void
253row_sel_copy_cached_fields_for_mysql(
254 byte* buf,
255 const byte* cached_rec,
256 row_prebuilt_t* prebuilt);
257
258/** Query plan */
259struct plan_t{
260 dict_table_t* table; /*!< table struct in the dictionary
261 cache */
262 dict_index_t* index; /*!< table index used in the search */
263 btr_pcur_t pcur; /*!< persistent cursor used to search
264 the index */
265 ibool asc; /*!< TRUE if cursor traveling upwards */
266 ibool pcur_is_open; /*!< TRUE if pcur has been positioned
267 and we can try to fetch new rows */
268 ibool cursor_at_end; /*!< TRUE if the cursor is open but
269 we know that there are no more
270 qualifying rows left to retrieve from
271 the index tree; NOTE though, that
272 there may still be unprocessed rows in
273 the prefetch stack; always FALSE when
274 pcur_is_open is FALSE */
275 ibool stored_cursor_rec_processed;
276 /*!< TRUE if the pcur position has been
277 stored and the record it is positioned
278 on has already been processed */
279 que_node_t** tuple_exps; /*!< array of expressions
280 which are used to calculate
281 the field values in the search
282 tuple: there is one expression
283 for each field in the search
284 tuple */
285 dtuple_t* tuple; /*!< search tuple */
286 page_cur_mode_t mode; /*!< search mode: PAGE_CUR_G, ... */
287 ulint n_exact_match; /*!< number of first fields in
288 the search tuple which must be
289 exactly matched */
290 ibool unique_search; /*!< TRUE if we are searching an
291 index record with a unique key */
292 ulint n_rows_fetched; /*!< number of rows fetched using pcur
293 after it was opened */
294 ulint n_rows_prefetched;/*!< number of prefetched rows cached
295 for fetch: fetching several rows in
296 the same mtr saves CPU time */
297 ulint first_prefetched;/*!< index of the first cached row in
298 select buffer arrays for each column */
299 ibool no_prefetch; /*!< no prefetch for this table */
300 sym_node_list_t columns; /*!< symbol table nodes for the columns
301 to retrieve from the table */
302 UT_LIST_BASE_NODE_T(func_node_t)
303 end_conds; /*!< conditions which determine the
304 fetch limit of the index segment we
305 have to look at: when one of these
306 fails, the result set has been
307 exhausted for the cursor in this
308 index; these conditions are normalized
309 so that in a comparison the column
310 for this table is the first argument */
311 UT_LIST_BASE_NODE_T(func_node_t)
312 other_conds; /*!< the rest of search conditions we can
313 test at this table in a join */
314 ibool must_get_clust; /*!< TRUE if index is a non-clustered
315 index and we must also fetch the
316 clustered index record; this is the
317 case if the non-clustered record does
318 not contain all the needed columns, or
319 if this is a single-table explicit
320 cursor, or a searched update or
321 delete */
322 ulint* clust_map; /*!< map telling how clust_ref is built
323 from the fields of a non-clustered
324 record */
325 dtuple_t* clust_ref; /*!< the reference to the clustered
326 index entry is built here if index is
327 a non-clustered index */
328 btr_pcur_t clust_pcur; /*!< if index is non-clustered, we use
329 this pcur to search the clustered
330 index */
331 mem_heap_t* old_vers_heap; /*!< memory heap used in building an old
332 version of a row, or NULL */
333};
334
335/** Select node states */
336enum sel_node_state {
337 SEL_NODE_CLOSED, /*!< it is a declared cursor which is not
338 currently open */
339 SEL_NODE_OPEN, /*!< intention locks not yet set on tables */
340 SEL_NODE_FETCH, /*!< intention locks have been set */
341 SEL_NODE_NO_MORE_ROWS /*!< cursor has reached the result set end */
342};
343
344/** Select statement node */
345struct sel_node_t{
346 que_common_t common; /*!< node type: QUE_NODE_SELECT */
347 enum sel_node_state
348 state; /*!< node state */
349 que_node_t* select_list; /*!< select list */
350 sym_node_t* into_list; /*!< variables list or NULL */
351 sym_node_t* table_list; /*!< table list */
352 ibool asc; /*!< TRUE if the rows should be fetched
353 in an ascending order */
354 ibool set_x_locks; /*!< TRUE if the cursor is for update or
355 delete, which means that a row x-lock
356 should be placed on the cursor row */
357 ulint row_lock_mode; /*!< LOCK_X or LOCK_S */
358 ulint n_tables; /*!< number of tables */
359 ulint fetch_table; /*!< number of the next table to access
360 in the join */
361 plan_t* plans; /*!< array of n_tables many plan nodes
362 containing the search plan and the
363 search data structures */
364 que_node_t* search_cond; /*!< search condition */
365 ReadView* read_view; /*!< if the query is a non-locking
366 consistent read, its read view is
367 placed here, otherwise NULL */
368 ibool consistent_read;/*!< TRUE if the select is a consistent,
369 non-locking read */
370 order_node_t* order_by; /*!< order by column definition, or
371 NULL */
372 ibool is_aggregate; /*!< TRUE if the select list consists of
373 aggregate functions */
374 ibool aggregate_already_fetched;
375 /*!< TRUE if the aggregate row has
376 already been fetched for the current
377 cursor */
378 ibool can_get_updated;/*!< this is TRUE if the select
379 is in a single-table explicit
380 cursor which can get updated
381 within the stored procedure,
382 or in a searched update or
383 delete; NOTE that to determine
384 of an explicit cursor if it
385 can get updated, the parser
386 checks from a stored procedure
387 if it contains positioned
388 update or delete statements */
389 sym_node_t* explicit_cursor;/*!< not NULL if an explicit cursor */
390 UT_LIST_BASE_NODE_T(sym_node_t)
391 copy_variables; /*!< variables whose values we have to
392 copy when an explicit cursor is opened,
393 so that they do not change between
394 fetches */
395};
396
397/** Fetch statement node */
398struct fetch_node_t{
399 que_common_t common; /*!< type: QUE_NODE_FETCH */
400 sel_node_t* cursor_def; /*!< cursor definition */
401 sym_node_t* into_list; /*!< variables to set */
402
403 pars_user_func_t*
404 func; /*!< User callback function or NULL.
405 The first argument to the function
406 is a sel_node_t*, containing the
407 results of the SELECT operation for
408 one row. If the function returns
409 NULL, it is not interested in
410 further rows and the cursor is
411 modified so (cursor % NOTFOUND) is
412 true. If it returns not-NULL,
413 continue normally. */
414};
415
416/** Open or close cursor operation type */
417enum open_node_op {
418 ROW_SEL_OPEN_CURSOR, /*!< open cursor */
419 ROW_SEL_CLOSE_CURSOR /*!< close cursor */
420};
421
422/** Open or close cursor statement node */
423struct open_node_t{
424 que_common_t common; /*!< type: QUE_NODE_OPEN */
425 enum open_node_op
426 op_type; /*!< operation type: open or
427 close cursor */
428 sel_node_t* cursor_def; /*!< cursor definition */
429};
430
431/** Row printf statement node */
432struct row_printf_node_t{
433 que_common_t common; /*!< type: QUE_NODE_ROW_PRINTF */
434 sel_node_t* sel_node; /*!< select */
435};
436
437/** Search direction for the MySQL interface */
438enum row_sel_direction {
439 ROW_SEL_NEXT = 1, /*!< ascending direction */
440 ROW_SEL_PREV = 2 /*!< descending direction */
441};
442
443/** Match mode for the MySQL interface */
444enum row_sel_match_mode {
445 ROW_SEL_EXACT = 1, /*!< search using a complete key value */
446 ROW_SEL_EXACT_PREFIX /*!< search using a key prefix which
447 must match rows: the prefix may
448 contain an incomplete field (the last
449 field in prefix may be just a prefix
450 of a fixed length column) */
451};
452
453#ifdef UNIV_DEBUG
454/** Convert a non-SQL-NULL field from Innobase format to MySQL format. */
455# define row_sel_field_store_in_mysql_format(dest,templ,idx,field,src,len) \
456 row_sel_field_store_in_mysql_format_func(dest,templ,idx,field,src,len)
457#else /* UNIV_DEBUG */
458/** Convert a non-SQL-NULL field from Innobase format to MySQL format. */
459# define row_sel_field_store_in_mysql_format(dest,templ,idx,field,src,len) \
460 row_sel_field_store_in_mysql_format_func(dest,templ,src,len)
461#endif /* UNIV_DEBUG */
462
463/**************************************************************//**
464Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
465function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. */
466
467void
468row_sel_field_store_in_mysql_format_func(
469/*=====================================*/
470 byte* dest, /*!< in/out: buffer where to store; NOTE
471 that BLOBs are not in themselves
472 stored here: the caller must allocate
473 and copy the BLOB into buffer before,
474 and pass the pointer to the BLOB in
475 'data' */
476 const mysql_row_templ_t* templ,
477 /*!< in: MySQL column template.
478 Its following fields are referenced:
479 type, is_unsigned, mysql_col_len,
480 mbminlen, mbmaxlen */
481#ifdef UNIV_DEBUG
482 const dict_index_t* index,
483 /*!< in: InnoDB index */
484 ulint field_no,
485 /*!< in: templ->rec_field_no or
486 templ->clust_rec_field_no or
487 templ->icp_rec_field_no */
488#endif /* UNIV_DEBUG */
489 const byte* data, /*!< in: data to store */
490 ulint len); /*!< in: length of the data */
491
492#include "row0sel.ic"
493
494#endif
495