1/*****************************************************************************
2
3Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License as published by the Free Software
7Foundation; version 2 of the License.
8
9This program is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13You should have received a copy of the GNU General Public License along with
14this program; if not, write to the Free Software Foundation, Inc.,
1551 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16
17*****************************************************************************/
18
19/**************************************************//**
20@file include/que0que.ic
21Query graph
22
23Created 5/27/1996 Heikki Tuuri
24*******************************************************/
25
26/***********************************************************************//**
27Gets the trx of a query thread. */
28UNIV_INLINE
29trx_t*
30thr_get_trx(
31/*========*/
32 que_thr_t* thr) /*!< in: query thread */
33{
34 ut_ad(thr);
35
36 return(thr->graph->trx);
37}
38
39/*******************************************************************//**
40Determines if this thread is rolling back an incomplete transaction
41in crash recovery.
42@return TRUE if thr is rolling back an incomplete transaction in crash
43recovery */
44UNIV_INLINE
45ibool
46thr_is_recv(
47/*========*/
48 const que_thr_t* thr) /*!< in: query thread */
49{
50 return(trx_is_recv(thr->graph->trx));
51}
52
53/***********************************************************************//**
54Gets the first thr in a fork. */
55UNIV_INLINE
56que_thr_t*
57que_fork_get_first_thr(
58/*===================*/
59 que_fork_t* fork) /*!< in: query fork */
60{
61 return(UT_LIST_GET_FIRST(fork->thrs));
62}
63
64/***********************************************************************//**
65Gets the child node of the first thr in a fork. */
66UNIV_INLINE
67que_node_t*
68que_fork_get_child(
69/*===============*/
70 que_fork_t* fork) /*!< in: query fork */
71{
72 que_thr_t* thr;
73
74 thr = UT_LIST_GET_FIRST(fork->thrs);
75
76 return(thr->child);
77}
78
79/***********************************************************************//**
80Gets the type of a graph node. */
81UNIV_INLINE
82ulint
83que_node_get_type(
84/*==============*/
85 const que_node_t* node) /*!< in: graph node */
86{
87 return(reinterpret_cast<const que_common_t*>(node)->type);
88}
89
90/***********************************************************************//**
91Gets pointer to the value dfield of a graph node. */
92UNIV_INLINE
93dfield_t*
94que_node_get_val(
95/*=============*/
96 que_node_t* node) /*!< in: graph node */
97{
98 ut_ad(node);
99
100 return(&(((que_common_t*) node)->val));
101}
102
103/***********************************************************************//**
104Gets the value buffer size of a graph node.
105@return val buffer size, not defined if val.data == NULL in node */
106UNIV_INLINE
107ulint
108que_node_get_val_buf_size(
109/*======================*/
110 que_node_t* node) /*!< in: graph node */
111{
112 ut_ad(node);
113
114 return(((que_common_t*) node)->val_buf_size);
115}
116
117/***********************************************************************//**
118Sets the value buffer size of a graph node. */
119UNIV_INLINE
120void
121que_node_set_val_buf_size(
122/*======================*/
123 que_node_t* node, /*!< in: graph node */
124 ulint size) /*!< in: size */
125{
126 ut_ad(node);
127
128 ((que_common_t*) node)->val_buf_size = size;
129}
130
131/***********************************************************************//**
132Sets the parent of a graph node. */
133UNIV_INLINE
134void
135que_node_set_parent(
136/*================*/
137 que_node_t* node, /*!< in: graph node */
138 que_node_t* parent) /*!< in: parent */
139{
140 ut_ad(node);
141
142 ((que_common_t*) node)->parent = parent;
143}
144
145/***********************************************************************//**
146Gets pointer to the value data type field of a graph node. */
147UNIV_INLINE
148dtype_t*
149que_node_get_data_type(
150/*===================*/
151 que_node_t* node) /*!< in: graph node */
152{
153 ut_ad(node);
154
155 return(dfield_get_type(&((que_common_t*) node)->val));
156}
157
158/*********************************************************************//**
159Catenates a query graph node to a list of them, possible empty list.
160@return one-way list of nodes */
161UNIV_INLINE
162que_node_t*
163que_node_list_add_last(
164/*===================*/
165 que_node_t* node_list, /*!< in: node list, or NULL */
166 que_node_t* node) /*!< in: node */
167{
168 que_common_t* cnode;
169 que_common_t* cnode2;
170
171 cnode = (que_common_t*) node;
172
173 cnode->brother = NULL;
174
175 if (node_list == NULL) {
176
177 return(node);
178 }
179
180 cnode2 = (que_common_t*) node_list;
181
182 while (cnode2->brother != NULL) {
183 cnode2 = (que_common_t*) cnode2->brother;
184 }
185
186 cnode2->brother = node;
187
188 return(node_list);
189}
190
191/*************************************************************************
192Removes a query graph node from the list.*/
193UNIV_INLINE
194que_node_t*
195que_node_list_get_last(
196/*===================*/
197 /* out: last node in list.*/
198 que_node_t* node_list) /* in: node list */
199{
200 que_common_t* node;
201
202 ut_a(node_list != NULL);
203
204 node = (que_common_t*) node_list;
205
206 /* We need the last element */
207 while (node->brother != NULL) {
208 node = (que_common_t*) node->brother;
209 }
210
211 return(node);
212}
213/*********************************************************************//**
214Gets the next list node in a list of query graph nodes.
215@return next node in a list of nodes */
216UNIV_INLINE
217que_node_t*
218que_node_get_next(
219/*==============*/
220 que_node_t* node) /*!< in: node in a list */
221{
222 return(((que_common_t*) node)->brother);
223}
224
225/*********************************************************************//**
226Gets a query graph node list length.
227@return length, for NULL list 0 */
228UNIV_INLINE
229ulint
230que_node_list_get_len(
231/*==================*/
232 que_node_t* node_list) /*!< in: node list, or NULL */
233{
234 const que_common_t* cnode;
235 ulint len;
236
237 cnode = (const que_common_t*) node_list;
238 len = 0;
239
240 while (cnode != NULL) {
241 len++;
242 cnode = (const que_common_t*) cnode->brother;
243 }
244
245 return(len);
246}
247
248/*********************************************************************//**
249Gets the parent node of a query graph node.
250@return parent node or NULL */
251UNIV_INLINE
252que_node_t*
253que_node_get_parent(
254/*================*/
255 que_node_t* node) /*!< in: node */
256{
257 return(((que_common_t*) node)->parent);
258}
259
260/**********************************************************************//**
261Checks if graph, trx, or session is in a state where the query thread should
262be stopped.
263@return TRUE if should be stopped; NOTE that if the peek is made
264without reserving the trx mutex, then another peek with the mutex
265reserved is necessary before deciding the actual stopping */
266UNIV_INLINE
267ibool
268que_thr_peek_stop(
269/*==============*/
270 que_thr_t* thr) /*!< in: query thread */
271{
272 trx_t* trx;
273 que_t* graph;
274
275 graph = thr->graph;
276 trx = graph->trx;
277
278 if (graph->state != QUE_FORK_ACTIVE
279 || trx->lock.que_state == TRX_QUE_LOCK_WAIT
280 || (trx->lock.que_state != TRX_QUE_ROLLING_BACK
281 && trx->lock.que_state != TRX_QUE_RUNNING)) {
282
283 return(TRUE);
284 }
285
286 return(FALSE);
287}
288
289/***********************************************************************//**
290Returns TRUE if the query graph is for a SELECT statement.
291@return TRUE if a select */
292UNIV_INLINE
293ibool
294que_graph_is_select(
295/*================*/
296 que_t* graph) /*!< in: graph */
297{
298 if (graph->fork_type == QUE_FORK_SELECT_SCROLL
299 || graph->fork_type == QUE_FORK_SELECT_NON_SCROLL) {
300
301 return(TRUE);
302 }
303
304 return(FALSE);
305}
306
307