1 /***************************************************************************** 2 3 Copyright (c) 1996, 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/que0que.h 28 Query graph 29 30 Created 5/27/1996 Heikki Tuuri 31 *******************************************************/ 32 33 #ifndef que0que_h 34 #define que0que_h 35 36 #include "data0data.h" 37 #include "dict0types.h" 38 #include "pars0types.h" 39 #include "que0types.h" 40 #include "row0types.h" 41 #include "srv0srv.h" 42 #include "trx0roll.h" 43 #include "trx0trx.h" 44 #include "univ.i" 45 #include "usr0types.h" 46 47 /** Mutex protecting the query threads. */ 48 extern ib_mutex_t que_thr_mutex; 49 50 /** Creates a query graph fork node. 51 @return own: fork node */ 52 que_fork_t *que_fork_create( 53 que_t *graph, /*!< in: graph, if NULL then this 54 fork node is assumed to be the 55 graph root */ 56 que_node_t *parent, /*!< in: parent node */ 57 ulint fork_type, /*!< in: fork type */ 58 mem_heap_t *heap); /*!< in: memory heap where created */ 59 /** Gets the first thr in a fork. */ 60 UNIV_INLINE 61 que_thr_t *que_fork_get_first_thr(que_fork_t *fork); /*!< in: query fork */ 62 /** Gets the child node of the first thr in a fork. */ 63 UNIV_INLINE 64 que_node_t *que_fork_get_child(que_fork_t *fork); /*!< in: query fork */ 65 66 /** Sets the parent of a graph node. 67 @param[in] node graph node 68 @param[in] parent parent */ 69 UNIV_INLINE 70 void que_node_set_parent(que_node_t *node, que_node_t *parent); 71 72 /** Creates a query graph thread node. 73 @param[in] parent parent node, i.e., a fork node 74 @param[in] heap memory heap where created 75 @param[in] prebuilt row prebuilt structure 76 @return own: query thread node */ 77 que_thr_t *que_thr_create(que_fork_t *parent, mem_heap_t *heap, 78 row_prebuilt_t *prebuilt); 79 /** Frees a query graph, but not the heap where it was created. Does not free 80 explicit cursor declarations, they are freed in que_graph_free. */ 81 void que_graph_free_recursive(que_node_t *node); /*!< in: query graph node */ 82 /** Frees a query graph. */ 83 void que_graph_free(que_t *graph); /*!< in: query graph; we assume that the 84 memory heap where this graph was created is 85 private to this graph: if not, then use 86 que_graph_free_recursive and free the heap 87 afterwards! */ 88 /** Stops a query thread if graph or trx is in a state requiring it. The 89 conditions are tested in the order (1) graph, (2) trx. 90 Caller must hold the trx mutex. 91 @param[in,out] thr query thread 92 @return true if stopped */ 93 bool que_thr_stop(que_thr_t *thr); 94 95 /** Moves a thread from another state to the QUE_THR_RUNNING state. Increments 96 the n_active_thrs counters of the query graph and transaction. */ 97 void que_thr_move_to_run_state_for_mysql( 98 que_thr_t *thr, /*!< in: an query thread */ 99 trx_t *trx); /*!< in: transaction */ 100 /** A patch for MySQL used to 'stop' a dummy query thread used in MySQL 101 select, when there is no error or lock wait. */ 102 void que_thr_stop_for_mysql_no_error(que_thr_t *thr, /*!< in: query thread */ 103 trx_t *trx); /*!< in: transaction */ 104 /** A patch for MySQL used to 'stop' a dummy query thread used in MySQL. The 105 query thread is stopped and made inactive, except in the case where 106 it was put to the lock wait state in lock0lock.cc, but the lock has already 107 been granted or the transaction chosen as a victim in deadlock resolution. */ 108 void que_thr_stop_for_mysql(que_thr_t *thr); /*!< in: query thread */ 109 /** Run a query thread. Handles lock waits. */ 110 void que_run_threads(que_thr_t *thr); /*!< in: query thread */ 111 /** Moves a suspended query thread to the QUE_THR_RUNNING state and release 112 a worker thread to execute it. This function should be used to end 113 the wait state of a query thread waiting for a lock or a stored procedure 114 completion. 115 @return query thread instance of thread to wakeup or NULL */ 116 que_thr_t *que_thr_end_lock_wait(trx_t *trx); /*!< in: transaction in the 117 QUE_THR_LOCK_WAIT state */ 118 /** Starts execution of a command in a query fork. Picks a query thread which 119 is not in the QUE_THR_RUNNING state and moves it to that state. If none 120 can be chosen, a situation which may arise in parallelized fetches, NULL 121 is returned. 122 @return a query thread of the graph moved to QUE_THR_RUNNING state, or 123 NULL; the query thread should be executed by que_run_threads by the 124 caller */ 125 que_thr_t *que_fork_start_command(que_fork_t *fork); /*!< in: a query fork */ 126 /** Gets the trx of a query thread. */ 127 UNIV_INLINE 128 trx_t *thr_get_trx(que_thr_t *thr); /*!< in: query thread */ 129 /** Determines if this thread is rolling back an incomplete transaction 130 in crash recovery. 131 @return true if thr is rolling back an incomplete transaction in crash 132 recovery */ 133 UNIV_INLINE 134 ibool thr_is_recv(const que_thr_t *thr); /*!< in: query thread */ 135 /** Gets the type of a graph node. */ 136 UNIV_INLINE 137 ulint que_node_get_type(const que_node_t *node); /*!< in: graph node */ 138 /** Gets pointer to the value data type field of a graph node. */ 139 UNIV_INLINE 140 dtype_t *que_node_get_data_type(que_node_t *node); /*!< in: graph node */ 141 /** Gets pointer to the value dfield of a graph node. */ 142 UNIV_INLINE 143 dfield_t *que_node_get_val(que_node_t *node); /*!< in: graph node */ 144 /** Gets the value buffer size of a graph node. 145 @return val buffer size, not defined if val.data == NULL in node */ 146 UNIV_INLINE 147 ulint que_node_get_val_buf_size(que_node_t *node); /*!< in: graph node */ 148 149 /** Sets the value buffer size of a graph node. 150 @param[in] node graph node 151 @param[in] size size */ 152 UNIV_INLINE 153 void que_node_set_val_buf_size(que_node_t *node, ulint size); 154 155 /** Gets the next list node in a list of query graph nodes. */ 156 UNIV_INLINE 157 que_node_t *que_node_get_next(que_node_t *node); /*!< in: node in a list */ 158 /** Gets the parent node of a query graph node. 159 @return parent node or NULL */ 160 UNIV_INLINE 161 que_node_t *que_node_get_parent(que_node_t *node); /*!< in: node */ 162 /** Get the first containing loop node (e.g. while_node_t or for_node_t) for the 163 given node, or NULL if the node is not within a loop. 164 @return containing loop node, or NULL. */ 165 que_node_t *que_node_get_containing_loop_node( 166 que_node_t *node); /*!< in: node */ 167 168 /** Catenates a query graph node to a list of them, possible empty list. 169 @param[in] node_list node list, or NULL 170 @param[in] node node 171 @return one-way list of nodes */ 172 UNIV_INLINE 173 que_node_t *que_node_list_add_last(que_node_t *node_list, que_node_t *node); 174 175 /************************************************************************* 176 Get the last node from the list.*/ 177 UNIV_INLINE 178 que_node_t *que_node_list_get_last( 179 /* out: node last node from list.*/ 180 que_node_t *node_list); /* in: node list, or NULL */ 181 /** Gets a query graph node list length. 182 @return length, for NULL list 0 */ 183 UNIV_INLINE 184 ulint que_node_list_get_len( 185 que_node_t *node_list); /*!< in: node list, or NULL */ 186 /** Checks if graph, trx, or session is in a state where the query thread should 187 be stopped. 188 @return true if should be stopped; NOTE that if the peek is made 189 without reserving the trx_t::mutex, then another peek with the mutex 190 reserved is necessary before deciding the actual stopping */ 191 UNIV_INLINE 192 ibool que_thr_peek_stop(que_thr_t *thr); /*!< in: query thread */ 193 /** Returns TRUE if the query graph is for a SELECT statement. 194 @return true if a select */ 195 UNIV_INLINE 196 ibool que_graph_is_select(que_t *graph); /*!< in: graph */ 197 /** Prints info of an SQL query graph node. */ 198 void que_node_print_info(que_node_t *node); /*!< in: query graph node */ 199 /** Evaluate the given SQL 200 @return error code or DB_SUCCESS */ 201 dberr_t que_eval_sql(pars_info_t *info, /*!< in: info struct, or NULL */ 202 const char *sql, /*!< in: SQL string */ 203 ibool reserve_dict_mutex, 204 /*!< in: if TRUE, acquire/release 205 dict_sys->mutex around call to pars_sql. */ 206 trx_t *trx); /*!< in: trx */ 207 208 /** Round robin scheduler. 209 @return a query thread of the graph moved to QUE_THR_RUNNING state, or 210 NULL; the query thread should be executed by que_run_threads by the 211 caller */ 212 que_thr_t *que_fork_scheduler_round_robin( 213 que_fork_t *fork, /*!< in: a query fork */ 214 que_thr_t *thr); /*!< in: current pos */ 215 216 /** Initialise the query sub-system. */ 217 void que_init(void); 218 219 /** Close the query sub-system. */ 220 void que_close(void); 221 222 /** Query thread states */ 223 enum que_thr_state_t { 224 QUE_THR_RUNNING, 225 QUE_THR_PROCEDURE_WAIT, 226 /** in selects this means that the thread is at the end of its 227 result set (or start, in case of a scroll cursor); in other 228 statements, this means the thread has done its task */ 229 QUE_THR_COMPLETED, 230 QUE_THR_COMMAND_WAIT, 231 QUE_THR_LOCK_WAIT, 232 QUE_THR_SUSPENDED 233 }; 234 235 /** Query thread lock states */ 236 enum que_thr_lock_t { 237 QUE_THR_LOCK_NOLOCK, 238 QUE_THR_LOCK_ROW, 239 QUE_THR_LOCK_TABLE 240 }; 241 242 /** From where the cursor position is counted */ 243 enum que_cur_t { QUE_CUR_NOT_DEFINED, QUE_CUR_START, QUE_CUR_END }; 244 245 /* Query graph query thread node: the fields are protected by the 246 trx_t::mutex with the exceptions named below */ 247 248 struct que_thr_t { 249 que_common_t common; /*!< type: QUE_NODE_THR */ 250 ulint magic_n; /*!< magic number to catch memory 251 corruption */ 252 que_node_t *child; /*!< graph child node */ 253 que_t *graph; /*!< graph where this node belongs */ 254 que_thr_state_t state; /*!< state of the query thread */ 255 ibool is_active; /*!< TRUE if the thread has been set 256 to the run state in 257 que_thr_move_to_run_state, but not 258 deactivated in 259 que_thr_dec_reference_count */ 260 /*------------------------------*/ 261 /* The following fields are private to the OS thread executing the 262 query thread, and are not protected by any mutex: */ 263 264 que_node_t *run_node; /*!< pointer to the node where the 265 subgraph down from this node is 266 currently executed */ 267 que_node_t *prev_node; /*!< pointer to the node from which 268 the control came */ 269 ulint resource; /*!< resource usage of the query thread 270 thus far */ 271 ulint lock_state; /*!< lock state of thread (table or 272 row) */ 273 274 /** The thread slot in the lock_sys->waiting_threads array protected by 275 lock_sys->wait_mutex when writing to it, and also by trx->mutex when changing 276 from null to non-null. 277 While reading, one can either hold the lock_sys->wait_mutex, or hold the 278 trx->mutex and a proof that no one has woken the trx yet, 279 so the slot is either still null (if trx hadn't yet started the sleep), or 280 already non-null (if it already started sleep), but definitely not 281 changing from null to non-null (as it requires trx->mutex) nor 282 changing from non-null to null (as it happens after wake up). */ 283 struct srv_slot_t *slot; 284 /*------------------------------*/ 285 /* The following fields are links for the various lists that 286 this type can be on. */ 287 UT_LIST_NODE_T(que_thr_t) 288 thrs; /*!< list of thread nodes of the fork 289 node */ 290 UT_LIST_NODE_T(que_thr_t) 291 trx_thrs; /*!< lists of threads in wait list of 292 the trx */ 293 UT_LIST_NODE_T(que_thr_t) 294 queue; /*!< list of runnable thread nodes in 295 the server task queue */ 296 ulint fk_cascade_depth; /*!< maximum cascading call depth 297 supported for foreign key constraint 298 related delete/updates */ 299 row_prebuilt_t *prebuilt; /*!< prebuilt structure processed by 300 the query thread */ 301 }; 302 303 #define QUE_THR_MAGIC_N 8476583 304 #define QUE_THR_MAGIC_FREED 123461526 305 306 /* Query graph fork node: its fields are protected by the query thread mutex */ 307 struct que_fork_t { 308 que_common_t common; /*!< type: QUE_NODE_FORK */ 309 que_t *graph; /*!< query graph of this node */ 310 ulint fork_type; /*!< fork type */ 311 ulint n_active_thrs; /*!< if this is the root of a graph, the 312 number query threads that have been 313 started in que_thr_move_to_run_state 314 but for which que_thr_dec_refer_count 315 has not yet been called */ 316 trx_t *trx; /*!< transaction: this is set only in 317 the root node */ 318 ulint state; /*!< state of the fork node */ 319 que_thr_t *caller; /*!< pointer to a possible calling query 320 thread */ 321 UT_LIST_BASE_NODE_T(que_thr_t) 322 thrs; /*!< list of query threads */ 323 /*------------------------------*/ 324 /* The fields in this section are defined only in the root node */ 325 sym_tab_t *sym_tab; /*!< symbol table of the query, 326 generated by the parser, or NULL 327 if the graph was created 'by hand' */ 328 pars_info_t *info; /*!< info struct, or NULL */ 329 /* The following cur_... fields are relevant only in a select graph */ 330 331 ulint cur_end; /*!< QUE_CUR_NOT_DEFINED, QUE_CUR_START, 332 QUE_CUR_END */ 333 ulint cur_pos; /*!< if there are n rows in the result 334 set, values 0 and n + 1 mean before 335 first row, or after last row, depending 336 on cur_end; values 1...n mean a row 337 index */ 338 ibool cur_on_row; /*!< TRUE if cursor is on a row, i.e., 339 it is not before the first row or 340 after the last row */ 341 sel_node_t *last_sel_node; /*!< last executed select node, or NULL 342 if none */ 343 UT_LIST_NODE_T(que_fork_t) 344 graphs; /*!< list of query graphs of a session 345 or a stored procedure */ 346 /*------------------------------*/ 347 mem_heap_t *heap; /*!< memory heap where the fork was 348 created */ 349 }; 350 351 /* Query fork (or graph) types */ 352 #define QUE_FORK_SELECT_NON_SCROLL 1 /* forward-only cursor */ 353 #define QUE_FORK_SELECT_SCROLL 2 /* scrollable cursor */ 354 #define QUE_FORK_INSERT 3 355 #define QUE_FORK_UPDATE 4 356 #define QUE_FORK_ROLLBACK 5 357 /* This is really the undo graph used in rollback, 358 no signal-sending roll_node in this graph */ 359 #define QUE_FORK_PURGE 6 360 #define QUE_FORK_EXECUTE 7 361 #define QUE_FORK_PROCEDURE 8 362 #define QUE_FORK_PROCEDURE_CALL 9 363 #define QUE_FORK_MYSQL_INTERFACE 10 364 #define QUE_FORK_RECOVERY 11 365 366 /* Query fork (or graph) states */ 367 #define QUE_FORK_ACTIVE 1 368 #define QUE_FORK_COMMAND_WAIT 2 369 #define QUE_FORK_INVALID 3 370 #define QUE_FORK_BEING_FREED 4 371 372 /* Flag which is ORed to control structure statement node types */ 373 #define QUE_NODE_CONTROL_STAT 1024 374 375 /* Query graph node types */ 376 #define QUE_NODE_LOCK 1 377 #define QUE_NODE_INSERT 2 378 #define QUE_NODE_UPDATE 4 379 #define QUE_NODE_CURSOR 5 380 #define QUE_NODE_SELECT 6 381 #define QUE_NODE_AGGREGATE 7 382 #define QUE_NODE_FORK 8 383 #define QUE_NODE_THR 9 384 #define QUE_NODE_UNDO 10 385 #define QUE_NODE_COMMIT 11 386 #define QUE_NODE_ROLLBACK 12 387 #define QUE_NODE_PURGE 13 388 #define QUE_NODE_SYMBOL 14 389 #define QUE_NODE_RES_WORD 15 390 #define QUE_NODE_FUNC 16 391 #define QUE_NODE_ORDER 17 392 #define QUE_NODE_PROC (18 + QUE_NODE_CONTROL_STAT) 393 #define QUE_NODE_IF (19 + QUE_NODE_CONTROL_STAT) 394 #define QUE_NODE_WHILE (20 + QUE_NODE_CONTROL_STAT) 395 #define QUE_NODE_ASSIGNMENT 21 396 #define QUE_NODE_FETCH 22 397 #define QUE_NODE_OPEN 23 398 #define QUE_NODE_COL_ASSIGNMENT 24 399 #define QUE_NODE_FOR (25 + QUE_NODE_CONTROL_STAT) 400 #define QUE_NODE_RETURN 26 401 #define QUE_NODE_ELSIF 27 402 #define QUE_NODE_CALL 28 403 #define QUE_NODE_EXIT 29 404 405 #include "que0que.ic" 406 407 #endif 408