| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 1997, 2017, Oracle and/or its affiliates. |
| 4 | Copyright (c) 2017, MariaDB Corporation. |
| 5 | |
| 6 | This program is free software; you can redistribute it and/or modify it under |
| 7 | the terms of the GNU General Public License as published by the Free Software |
| 8 | Foundation; version 2 of the License. |
| 9 | |
| 10 | This program is distributed in the hope that it will be useful, but WITHOUT |
| 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU General Public License along with |
| 15 | this program; if not, write to the Free Software Foundation, Inc., |
| 16 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
| 17 | |
| 18 | *****************************************************************************/ |
| 19 | |
| 20 | /**************************************************//** |
| 21 | @file include/row0sel.h |
| 22 | Select |
| 23 | |
| 24 | Created 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 | /*********************************************************************//** |
| 43 | Creates a select node struct. |
| 44 | @return own: select node struct */ |
| 45 | sel_node_t* |
| 46 | sel_node_create( |
| 47 | /*============*/ |
| 48 | mem_heap_t* heap); /*!< in: memory heap where created */ |
| 49 | /*********************************************************************//** |
| 50 | Frees the memory private to a select node when a query graph is freed, |
| 51 | does not free the heap where the node was originally created. */ |
| 52 | void |
| 53 | sel_node_free_private( |
| 54 | /*==================*/ |
| 55 | sel_node_t* node); /*!< in: select node struct */ |
| 56 | /*********************************************************************//** |
| 57 | Frees a prefetch buffer for a column, including the dynamically allocated |
| 58 | memory for data stored there. */ |
| 59 | void |
| 60 | sel_col_prefetch_buf_free( |
| 61 | /*======================*/ |
| 62 | sel_buf_t* prefetch_buf); /*!< in, own: prefetch buffer */ |
| 63 | /*********************************************************************//** |
| 64 | Gets the plan node for the nth table in a join. |
| 65 | @return plan node */ |
| 66 | UNIV_INLINE |
| 67 | plan_t* |
| 68 | sel_node_get_nth_plan( |
| 69 | /*==================*/ |
| 70 | sel_node_t* node, /*!< in: select node */ |
| 71 | ulint i); /*!< in: get ith plan node */ |
| 72 | /**********************************************************************//** |
| 73 | Performs a select step. This is a high-level function used in SQL execution |
| 74 | graphs. |
| 75 | @return query thread to run next or NULL */ |
| 76 | que_thr_t* |
| 77 | row_sel_step( |
| 78 | /*=========*/ |
| 79 | que_thr_t* thr); /*!< in: query thread */ |
| 80 | /**********************************************************************//** |
| 81 | Performs an execution step of an open or close cursor statement node. |
| 82 | @return query thread to run next or NULL */ |
| 83 | UNIV_INLINE |
| 84 | que_thr_t* |
| 85 | open_step( |
| 86 | /*======*/ |
| 87 | que_thr_t* thr); /*!< in: query thread */ |
| 88 | /**********************************************************************//** |
| 89 | Performs a fetch for a cursor. |
| 90 | @return query thread to run next or NULL */ |
| 91 | que_thr_t* |
| 92 | fetch_step( |
| 93 | /*=======*/ |
| 94 | que_thr_t* thr); /*!< in: query thread */ |
| 95 | /***********************************************************//** |
| 96 | Prints a row in a select result. |
| 97 | @return query thread to run next or NULL */ |
| 98 | que_thr_t* |
| 99 | row_printf_step( |
| 100 | /*============*/ |
| 101 | que_thr_t* thr); /*!< in: query thread */ |
| 102 | |
| 103 | /** Copy used fields from cached row. |
| 104 | Copy cache record field by field, don't touch fields that |
| 105 | are 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. */ |
| 109 | void |
| 110 | row_sel_copy_cached_fields_for_mysql( |
| 111 | byte* buf, |
| 112 | const byte* cached_rec, |
| 113 | row_prebuilt_t* prebuilt); |
| 114 | |
| 115 | /****************************************************************//** |
| 116 | Converts a key value stored in MySQL format to an Innobase dtuple. The last |
| 117 | field of the key value may be just a prefix of a fixed length field: hence |
| 118 | the parameter key_len. But currently we do not allow search keys where the |
| 119 | last field is only a prefix of the full key field len and print a warning if |
| 120 | such appears. */ |
| 121 | void |
| 122 | row_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 |
| 142 | MySQL. This function opens a cursor, and also implements fetch next |
| 143 | and fetch prev. NOTE that if we do a search with a full key value |
| 144 | from a unique index (ROW_SEL_EXACT), then we will not store the cursor |
| 145 | position 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, |
| 160 | DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */ |
| 161 | UNIV_INLINE |
| 162 | dberr_t |
| 163 | row_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. |
| 172 | Function is mainly used for tables that are shared across connections and |
| 173 | so it employs technique that can help re-construct the rows that |
| 174 | transaction is suppose to see. |
| 175 | It 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 */ |
| 190 | dberr_t |
| 191 | row_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 | /********************************************************************//** |
| 200 | Count rows in a R-Tree leaf level. |
| 201 | @return DB_SUCCESS if successful */ |
| 202 | dberr_t |
| 203 | row_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 | /*******************************************************************//** |
| 216 | Checks if MySQL at the moment is allowed for this table to retrieve a |
| 217 | consistent read result, or store it to the query cache. |
| 218 | @return whether storing or retrieving from the query cache is permitted */ |
| 219 | bool |
| 220 | row_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 */ |
| 229 | ib_uint64_t |
| 230 | row_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 */ |
| 234 | struct 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. |
| 247 | Copy cache record field by field, don't touch fields that |
| 248 | are 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. */ |
| 252 | void |
| 253 | row_sel_copy_cached_fields_for_mysql( |
| 254 | byte* buf, |
| 255 | const byte* cached_rec, |
| 256 | row_prebuilt_t* prebuilt); |
| 257 | |
| 258 | /** Query plan */ |
| 259 | struct 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 */ |
| 336 | enum 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 */ |
| 345 | struct 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 */ |
| 398 | struct 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 */ |
| 417 | enum 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 */ |
| 423 | struct 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 */ |
| 432 | struct 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 */ |
| 438 | enum 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 */ |
| 444 | enum 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 | /**************************************************************//** |
| 464 | Stores a non-SQL-NULL field in the MySQL format. The counterpart of this |
| 465 | function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. */ |
| 466 | |
| 467 | void |
| 468 | row_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 | |