00001 /***************************************************************************** 00002 00003 Copyright (C) 1998, 2009, Innobase Oy. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it under 00006 the terms of the GNU General Public License as published by the Free Software 00007 Foundation; version 2 of the License. 00008 00009 This program is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License along with 00014 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin 00015 St, Fifth Floor, Boston, MA 02110-1301 USA 00016 00017 *****************************************************************************/ 00018 00019 /**************************************************/ 00026 #include "eval0proc.h" 00027 00028 #ifdef UNIV_NONINL 00029 #include "eval0proc.ic" 00030 #endif 00031 00032 /**********************************************************************/ 00035 UNIV_INTERN 00036 que_thr_t* 00037 if_step( 00038 /*====*/ 00039 que_thr_t* thr) 00040 { 00041 if_node_t* node; 00042 elsif_node_t* elsif_node; 00043 00044 ut_ad(thr); 00045 00046 node = static_cast<if_node_t *>(thr->run_node); 00047 ut_ad(que_node_get_type(node) == QUE_NODE_IF); 00048 00049 if (thr->prev_node == que_node_get_parent(node)) { 00050 00051 /* Evaluate the condition */ 00052 00053 eval_exp(node->cond); 00054 00055 if (eval_node_get_ibool_val(node->cond)) { 00056 00057 /* The condition evaluated to TRUE: start execution 00058 from the first statement in the statement list */ 00059 00060 thr->run_node = node->stat_list; 00061 00062 } else if (node->else_part) { 00063 thr->run_node = node->else_part; 00064 00065 } else if (node->elsif_list) { 00066 elsif_node = node->elsif_list; 00067 00068 for (;;) { 00069 eval_exp(elsif_node->cond); 00070 00071 if (eval_node_get_ibool_val( 00072 elsif_node->cond)) { 00073 00074 /* The condition evaluated to TRUE: 00075 start execution from the first 00076 statement in the statement list */ 00077 00078 thr->run_node = elsif_node->stat_list; 00079 00080 break; 00081 } 00082 00083 elsif_node = static_cast<elsif_node_t *>(que_node_get_next(elsif_node)); 00084 00085 if (elsif_node == NULL) { 00086 thr->run_node = NULL; 00087 00088 break; 00089 } 00090 } 00091 } else { 00092 thr->run_node = NULL; 00093 } 00094 } else { 00095 /* Move to the next statement */ 00096 ut_ad(que_node_get_next(thr->prev_node) == NULL); 00097 00098 thr->run_node = NULL; 00099 } 00100 00101 if (thr->run_node == NULL) { 00102 thr->run_node = que_node_get_parent(node); 00103 } 00104 00105 return(thr); 00106 } 00107 00108 /**********************************************************************/ 00111 UNIV_INTERN 00112 que_thr_t* 00113 while_step( 00114 /*=======*/ 00115 que_thr_t* thr) 00116 { 00117 while_node_t* node; 00118 00119 ut_ad(thr); 00120 00121 node = static_cast<while_node_t *>(thr->run_node); 00122 ut_ad(que_node_get_type(node) == QUE_NODE_WHILE); 00123 00124 ut_ad((thr->prev_node == que_node_get_parent(node)) 00125 || (que_node_get_next(thr->prev_node) == NULL)); 00126 00127 /* Evaluate the condition */ 00128 00129 eval_exp(node->cond); 00130 00131 if (eval_node_get_ibool_val(node->cond)) { 00132 00133 /* The condition evaluated to TRUE: start execution 00134 from the first statement in the statement list */ 00135 00136 thr->run_node = node->stat_list; 00137 } else { 00138 thr->run_node = que_node_get_parent(node); 00139 } 00140 00141 return(thr); 00142 } 00143 00144 /**********************************************************************/ 00147 UNIV_INTERN 00148 que_thr_t* 00149 assign_step( 00150 /*========*/ 00151 que_thr_t* thr) 00152 { 00153 assign_node_t* node; 00154 00155 ut_ad(thr); 00156 00157 node = static_cast<assign_node_t *>(thr->run_node); 00158 ut_ad(que_node_get_type(node) == QUE_NODE_ASSIGNMENT); 00159 00160 /* Evaluate the value to assign */ 00161 00162 eval_exp(node->val); 00163 00164 eval_node_copy_val(node->var->alias, node->val); 00165 00166 thr->run_node = que_node_get_parent(node); 00167 00168 return(thr); 00169 } 00170 00171 /**********************************************************************/ 00174 UNIV_INTERN 00175 que_thr_t* 00176 for_step( 00177 /*=====*/ 00178 que_thr_t* thr) 00179 { 00180 for_node_t* node; 00181 que_node_t* parent; 00182 lint loop_var_value; 00183 00184 ut_ad(thr); 00185 00186 node = static_cast<for_node_t *>(thr->run_node); 00187 00188 ut_ad(que_node_get_type(node) == QUE_NODE_FOR); 00189 00190 parent = que_node_get_parent(node); 00191 00192 if (thr->prev_node != parent) { 00193 00194 /* Move to the next statement */ 00195 thr->run_node = que_node_get_next(thr->prev_node); 00196 00197 if (thr->run_node != NULL) { 00198 00199 return(thr); 00200 } 00201 00202 /* Increment the value of loop_var */ 00203 00204 loop_var_value = 1 + eval_node_get_int_val(node->loop_var); 00205 } else { 00206 /* Initialize the loop */ 00207 00208 eval_exp(node->loop_start_limit); 00209 eval_exp(node->loop_end_limit); 00210 00211 loop_var_value = eval_node_get_int_val(node->loop_start_limit); 00212 00213 node->loop_end_value 00214 = (int) eval_node_get_int_val(node->loop_end_limit); 00215 } 00216 00217 /* Check if we should do another loop */ 00218 00219 if (loop_var_value > node->loop_end_value) { 00220 00221 /* Enough loops done */ 00222 00223 thr->run_node = parent; 00224 } else { 00225 eval_node_set_int_val(node->loop_var, loop_var_value); 00226 00227 thr->run_node = node->stat_list; 00228 } 00229 00230 return(thr); 00231 } 00232 00233 /**********************************************************************/ 00236 UNIV_INTERN 00237 que_thr_t* 00238 exit_step( 00239 /*======*/ 00240 que_thr_t* thr) 00241 { 00242 exit_node_t* node; 00243 que_node_t* loop_node; 00244 00245 ut_ad(thr); 00246 00247 node = static_cast<exit_node_t *>(thr->run_node); 00248 00249 ut_ad(que_node_get_type(node) == QUE_NODE_EXIT); 00250 00251 /* Loops exit by setting thr->run_node as the loop node's parent, so 00252 find our containing loop node and get its parent. */ 00253 00254 loop_node = que_node_get_containing_loop_node(node); 00255 00256 /* If someone uses an EXIT statement outside of a loop, this will 00257 trigger. */ 00258 ut_a(loop_node); 00259 00260 thr->run_node = que_node_get_parent(loop_node); 00261 00262 return(thr); 00263 } 00264 00265 /**********************************************************************/ 00268 UNIV_INTERN 00269 que_thr_t* 00270 return_step( 00271 /*========*/ 00272 que_thr_t* thr) 00273 { 00274 return_node_t* node; 00275 que_node_t* parent; 00276 00277 ut_ad(thr); 00278 00279 node = static_cast<return_node_t *>(thr->run_node); 00280 00281 ut_ad(que_node_get_type(node) == QUE_NODE_RETURN); 00282 00283 parent = node; 00284 00285 while (que_node_get_type(parent) != QUE_NODE_PROC) { 00286 00287 parent = que_node_get_parent(parent); 00288 } 00289 00290 ut_a(parent); 00291 00292 thr->run_node = que_node_get_parent(parent); 00293 00294 return(thr); 00295 }