1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. |
4 | |
5 | This program is free software; you can redistribute it and/or modify it under |
6 | the terms of the GNU General Public License as published by the Free Software |
7 | Foundation; version 2 of the License. |
8 | |
9 | This program is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License along with |
14 | this program; if not, write to the Free Software Foundation, Inc., |
15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
16 | |
17 | *****************************************************************************/ |
18 | |
19 | /**************************************************//** |
20 | @file include/que0que.ic |
21 | Query graph |
22 | |
23 | Created 5/27/1996 Heikki Tuuri |
24 | *******************************************************/ |
25 | |
26 | /***********************************************************************//** |
27 | Gets the trx of a query thread. */ |
28 | UNIV_INLINE |
29 | trx_t* |
30 | thr_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 | /*******************************************************************//** |
40 | Determines if this thread is rolling back an incomplete transaction |
41 | in crash recovery. |
42 | @return TRUE if thr is rolling back an incomplete transaction in crash |
43 | recovery */ |
44 | UNIV_INLINE |
45 | ibool |
46 | thr_is_recv( |
47 | /*========*/ |
48 | const que_thr_t* thr) /*!< in: query thread */ |
49 | { |
50 | return(trx_is_recv(thr->graph->trx)); |
51 | } |
52 | |
53 | /***********************************************************************//** |
54 | Gets the first thr in a fork. */ |
55 | UNIV_INLINE |
56 | que_thr_t* |
57 | que_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 | /***********************************************************************//** |
65 | Gets the child node of the first thr in a fork. */ |
66 | UNIV_INLINE |
67 | que_node_t* |
68 | que_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 | /***********************************************************************//** |
80 | Gets the type of a graph node. */ |
81 | UNIV_INLINE |
82 | ulint |
83 | que_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 | /***********************************************************************//** |
91 | Gets pointer to the value dfield of a graph node. */ |
92 | UNIV_INLINE |
93 | dfield_t* |
94 | que_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 | /***********************************************************************//** |
104 | Gets the value buffer size of a graph node. |
105 | @return val buffer size, not defined if val.data == NULL in node */ |
106 | UNIV_INLINE |
107 | ulint |
108 | que_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 | /***********************************************************************//** |
118 | Sets the value buffer size of a graph node. */ |
119 | UNIV_INLINE |
120 | void |
121 | que_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 | /***********************************************************************//** |
132 | Sets the parent of a graph node. */ |
133 | UNIV_INLINE |
134 | void |
135 | que_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 | /***********************************************************************//** |
146 | Gets pointer to the value data type field of a graph node. */ |
147 | UNIV_INLINE |
148 | dtype_t* |
149 | que_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 | /*********************************************************************//** |
159 | Catenates a query graph node to a list of them, possible empty list. |
160 | @return one-way list of nodes */ |
161 | UNIV_INLINE |
162 | que_node_t* |
163 | que_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 | /************************************************************************* |
192 | Removes a query graph node from the list.*/ |
193 | UNIV_INLINE |
194 | que_node_t* |
195 | que_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 | /*********************************************************************//** |
214 | Gets the next list node in a list of query graph nodes. |
215 | @return next node in a list of nodes */ |
216 | UNIV_INLINE |
217 | que_node_t* |
218 | que_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 | /*********************************************************************//** |
226 | Gets a query graph node list length. |
227 | @return length, for NULL list 0 */ |
228 | UNIV_INLINE |
229 | ulint |
230 | que_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 | /*********************************************************************//** |
249 | Gets the parent node of a query graph node. |
250 | @return parent node or NULL */ |
251 | UNIV_INLINE |
252 | que_node_t* |
253 | que_node_get_parent( |
254 | /*================*/ |
255 | que_node_t* node) /*!< in: node */ |
256 | { |
257 | return(((que_common_t*) node)->parent); |
258 | } |
259 | |
260 | /**********************************************************************//** |
261 | Checks if graph, trx, or session is in a state where the query thread should |
262 | be stopped. |
263 | @return TRUE if should be stopped; NOTE that if the peek is made |
264 | without reserving the trx mutex, then another peek with the mutex |
265 | reserved is necessary before deciding the actual stopping */ |
266 | UNIV_INLINE |
267 | ibool |
268 | que_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 | /***********************************************************************//** |
290 | Returns TRUE if the query graph is for a SELECT statement. |
291 | @return TRUE if a select */ |
292 | UNIV_INLINE |
293 | ibool |
294 | que_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 | |