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