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