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