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