MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
eval0proc.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1998, 2011, 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 /**************************************************/
26 #include "eval0proc.h"
27 
28 #ifdef UNIV_NONINL
29 #include "eval0proc.ic"
30 #endif
31 
32 /**********************************************************************/
35 UNIV_INTERN
36 que_thr_t*
38 /*====*/
39  que_thr_t* thr)
40 {
41  if_node_t* node;
42  elsif_node_t* elsif_node;
43 
44  ut_ad(thr);
45 
46  node = static_cast<if_node_t*>(thr->run_node);
47  ut_ad(que_node_get_type(node) == QUE_NODE_IF);
48 
49  if (thr->prev_node == que_node_get_parent(node)) {
50 
51  /* Evaluate the condition */
52 
53  eval_exp(node->cond);
54 
55  if (eval_node_get_ibool_val(node->cond)) {
56 
57  /* The condition evaluated to TRUE: start execution
58  from the first statement in the statement list */
59 
60  thr->run_node = node->stat_list;
61 
62  } else if (node->else_part) {
63  thr->run_node = node->else_part;
64 
65  } else if (node->elsif_list) {
66  elsif_node = node->elsif_list;
67 
68  for (;;) {
69  eval_exp(elsif_node->cond);
70 
72  elsif_node->cond)) {
73 
74  /* The condition evaluated to TRUE:
75  start execution from the first
76  statement in the statement list */
77 
78  thr->run_node = elsif_node->stat_list;
79 
80  break;
81  }
82 
83  elsif_node = static_cast<elsif_node_t*>(
84  que_node_get_next(elsif_node));
85 
86  if (elsif_node == NULL) {
87  thr->run_node = NULL;
88 
89  break;
90  }
91  }
92  } else {
93  thr->run_node = NULL;
94  }
95  } else {
96  /* Move to the next statement */
97  ut_ad(que_node_get_next(thr->prev_node) == NULL);
98 
99  thr->run_node = NULL;
100  }
101 
102  if (thr->run_node == NULL) {
103  thr->run_node = que_node_get_parent(node);
104  }
105 
106  return(thr);
107 }
108 
109 /**********************************************************************/
112 UNIV_INTERN
113 que_thr_t*
115 /*=======*/
116  que_thr_t* thr)
117 {
118  while_node_t* node;
119 
120  ut_ad(thr);
121 
122  node = static_cast<while_node_t*>(thr->run_node);
123  ut_ad(que_node_get_type(node) == QUE_NODE_WHILE);
124 
125  ut_ad((thr->prev_node == que_node_get_parent(node))
126  || (que_node_get_next(thr->prev_node) == NULL));
127 
128  /* Evaluate the condition */
129 
130  eval_exp(node->cond);
131 
132  if (eval_node_get_ibool_val(node->cond)) {
133 
134  /* The condition evaluated to TRUE: start execution
135  from the first statement in the statement list */
136 
137  thr->run_node = node->stat_list;
138  } else {
139  thr->run_node = que_node_get_parent(node);
140  }
141 
142  return(thr);
143 }
144 
145 /**********************************************************************/
148 UNIV_INTERN
149 que_thr_t*
151 /*========*/
152  que_thr_t* thr)
153 {
154  assign_node_t* node;
155 
156  ut_ad(thr);
157 
158  node = static_cast<assign_node_t*>(thr->run_node);
159  ut_ad(que_node_get_type(node) == QUE_NODE_ASSIGNMENT);
160 
161  /* Evaluate the value to assign */
162 
163  eval_exp(node->val);
164 
165  eval_node_copy_val(node->var->alias, node->val);
166 
167  thr->run_node = que_node_get_parent(node);
168 
169  return(thr);
170 }
171 
172 /**********************************************************************/
175 UNIV_INTERN
176 que_thr_t*
178 /*=====*/
179  que_thr_t* thr)
180 {
181  for_node_t* node;
182  que_node_t* parent;
183  lint loop_var_value;
184 
185  ut_ad(thr);
186 
187  node = static_cast<for_node_t*>(thr->run_node);
188 
189  ut_ad(que_node_get_type(node) == QUE_NODE_FOR);
190 
191  parent = que_node_get_parent(node);
192 
193  if (thr->prev_node != parent) {
194 
195  /* Move to the next statement */
196  thr->run_node = que_node_get_next(thr->prev_node);
197 
198  if (thr->run_node != NULL) {
199 
200  return(thr);
201  }
202 
203  /* Increment the value of loop_var */
204 
205  loop_var_value = 1 + eval_node_get_int_val(node->loop_var);
206  } else {
207  /* Initialize the loop */
208 
209  eval_exp(node->loop_start_limit);
210  eval_exp(node->loop_end_limit);
211 
212  loop_var_value = eval_node_get_int_val(node->loop_start_limit);
213 
214  node->loop_end_value
215  = (int) eval_node_get_int_val(node->loop_end_limit);
216  }
217 
218  /* Check if we should do another loop */
219 
220  if (loop_var_value > node->loop_end_value) {
221 
222  /* Enough loops done */
223 
224  thr->run_node = parent;
225  } else {
226  eval_node_set_int_val(node->loop_var, loop_var_value);
227 
228  thr->run_node = node->stat_list;
229  }
230 
231  return(thr);
232 }
233 
234 /**********************************************************************/
237 UNIV_INTERN
238 que_thr_t*
240 /*======*/
241  que_thr_t* thr)
242 {
243  exit_node_t* node;
244  que_node_t* loop_node;
245 
246  ut_ad(thr);
247 
248  node = static_cast<exit_node_t*>(thr->run_node);
249 
250  ut_ad(que_node_get_type(node) == QUE_NODE_EXIT);
251 
252  /* Loops exit by setting thr->run_node as the loop node's parent, so
253  find our containing loop node and get its parent. */
254 
255  loop_node = que_node_get_containing_loop_node(node);
256 
257  /* If someone uses an EXIT statement outside of a loop, this will
258  trigger. */
259  ut_a(loop_node);
260 
261  thr->run_node = que_node_get_parent(loop_node);
262 
263  return(thr);
264 }
265 
266 /**********************************************************************/
269 UNIV_INTERN
270 que_thr_t*
272 /*========*/
273  que_thr_t* thr)
274 {
275  return_node_t* node;
276  que_node_t* parent;
277 
278  ut_ad(thr);
279 
280  node = static_cast<return_node_t*>(thr->run_node);
281 
282  ut_ad(que_node_get_type(node) == QUE_NODE_RETURN);
283 
284  parent = node;
285 
286  while (que_node_get_type(parent) != QUE_NODE_PROC) {
287 
288  parent = que_node_get_parent(parent);
289  }
290 
291  ut_a(parent);
292 
293  thr->run_node = que_node_get_parent(parent);
294 
295  return(thr);
296 }