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