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