Drizzled Public API Documentation

eval0proc.cc
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 }