You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

278 lines
5.7 KiB

20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
  1. /******************************************************
  2. Executes SQL stored procedures and their control structures
  3. (c) 1998 Innobase Oy
  4. Created 1/20/1998 Heikki Tuuri
  5. *******************************************************/
  6. #include "eval0proc.h"
  7. #ifdef UNIV_NONINL
  8. #include "eval0proc.ic"
  9. #endif
  10. /**************************************************************************
  11. Performs an execution step of an if-statement node. */
  12. UNIV_INTERN
  13. que_thr_t*
  14. if_step(
  15. /*====*/
  16. /* out: query thread to run next or NULL */
  17. que_thr_t* thr) /* in: query thread */
  18. {
  19. if_node_t* node;
  20. elsif_node_t* elsif_node;
  21. ut_ad(thr);
  22. node = thr->run_node;
  23. ut_ad(que_node_get_type(node) == QUE_NODE_IF);
  24. if (thr->prev_node == que_node_get_parent(node)) {
  25. /* Evaluate the condition */
  26. eval_exp(node->cond);
  27. if (eval_node_get_ibool_val(node->cond)) {
  28. /* The condition evaluated to TRUE: start execution
  29. from the first statement in the statement list */
  30. thr->run_node = node->stat_list;
  31. } else if (node->else_part) {
  32. thr->run_node = node->else_part;
  33. } else if (node->elsif_list) {
  34. elsif_node = node->elsif_list;
  35. for (;;) {
  36. eval_exp(elsif_node->cond);
  37. if (eval_node_get_ibool_val(
  38. elsif_node->cond)) {
  39. /* The condition evaluated to TRUE:
  40. start execution from the first
  41. statement in the statement list */
  42. thr->run_node = elsif_node->stat_list;
  43. break;
  44. }
  45. elsif_node = que_node_get_next(elsif_node);
  46. if (elsif_node == NULL) {
  47. thr->run_node = NULL;
  48. break;
  49. }
  50. }
  51. } else {
  52. thr->run_node = NULL;
  53. }
  54. } else {
  55. /* Move to the next statement */
  56. ut_ad(que_node_get_next(thr->prev_node) == NULL);
  57. thr->run_node = NULL;
  58. }
  59. if (thr->run_node == NULL) {
  60. thr->run_node = que_node_get_parent(node);
  61. }
  62. return(thr);
  63. }
  64. /**************************************************************************
  65. Performs an execution step of a while-statement node. */
  66. UNIV_INTERN
  67. que_thr_t*
  68. while_step(
  69. /*=======*/
  70. /* out: query thread to run next or NULL */
  71. que_thr_t* thr) /* in: query thread */
  72. {
  73. while_node_t* node;
  74. ut_ad(thr);
  75. node = thr->run_node;
  76. ut_ad(que_node_get_type(node) == QUE_NODE_WHILE);
  77. ut_ad((thr->prev_node == que_node_get_parent(node))
  78. || (que_node_get_next(thr->prev_node) == NULL));
  79. /* Evaluate the condition */
  80. eval_exp(node->cond);
  81. if (eval_node_get_ibool_val(node->cond)) {
  82. /* The condition evaluated to TRUE: start execution
  83. from the first statement in the statement list */
  84. thr->run_node = node->stat_list;
  85. } else {
  86. thr->run_node = que_node_get_parent(node);
  87. }
  88. return(thr);
  89. }
  90. /**************************************************************************
  91. Performs an execution step of an assignment statement node. */
  92. UNIV_INTERN
  93. que_thr_t*
  94. assign_step(
  95. /*========*/
  96. /* out: query thread to run next or NULL */
  97. que_thr_t* thr) /* in: query thread */
  98. {
  99. assign_node_t* node;
  100. ut_ad(thr);
  101. node = thr->run_node;
  102. ut_ad(que_node_get_type(node) == QUE_NODE_ASSIGNMENT);
  103. /* Evaluate the value to assign */
  104. eval_exp(node->val);
  105. eval_node_copy_val(node->var->alias, node->val);
  106. thr->run_node = que_node_get_parent(node);
  107. return(thr);
  108. }
  109. /**************************************************************************
  110. Performs an execution step of a for-loop node. */
  111. UNIV_INTERN
  112. que_thr_t*
  113. for_step(
  114. /*=====*/
  115. /* out: query thread to run next or NULL */
  116. que_thr_t* thr) /* in: query thread */
  117. {
  118. for_node_t* node;
  119. que_node_t* parent;
  120. lint loop_var_value;
  121. ut_ad(thr);
  122. node = thr->run_node;
  123. ut_ad(que_node_get_type(node) == QUE_NODE_FOR);
  124. parent = que_node_get_parent(node);
  125. if (thr->prev_node != parent) {
  126. /* Move to the next statement */
  127. thr->run_node = que_node_get_next(thr->prev_node);
  128. if (thr->run_node != NULL) {
  129. return(thr);
  130. }
  131. /* Increment the value of loop_var */
  132. loop_var_value = 1 + eval_node_get_int_val(node->loop_var);
  133. } else {
  134. /* Initialize the loop */
  135. eval_exp(node->loop_start_limit);
  136. eval_exp(node->loop_end_limit);
  137. loop_var_value = eval_node_get_int_val(node->loop_start_limit);
  138. node->loop_end_value
  139. = (int) eval_node_get_int_val(node->loop_end_limit);
  140. }
  141. /* Check if we should do another loop */
  142. if (loop_var_value > node->loop_end_value) {
  143. /* Enough loops done */
  144. thr->run_node = parent;
  145. } else {
  146. eval_node_set_int_val(node->loop_var, loop_var_value);
  147. thr->run_node = node->stat_list;
  148. }
  149. return(thr);
  150. }
  151. /**************************************************************************
  152. Performs an execution step of an exit statement node. */
  153. UNIV_INTERN
  154. que_thr_t*
  155. exit_step(
  156. /*======*/
  157. /* out: query thread to run next or NULL */
  158. que_thr_t* thr) /* in: query thread */
  159. {
  160. exit_node_t* node;
  161. que_node_t* loop_node;
  162. ut_ad(thr);
  163. node = thr->run_node;
  164. ut_ad(que_node_get_type(node) == QUE_NODE_EXIT);
  165. /* Loops exit by setting thr->run_node as the loop node's parent, so
  166. find our containing loop node and get its parent. */
  167. loop_node = que_node_get_containing_loop_node(node);
  168. /* If someone uses an EXIT statement outside of a loop, this will
  169. trigger. */
  170. ut_a(loop_node);
  171. thr->run_node = que_node_get_parent(loop_node);
  172. return(thr);
  173. }
  174. /**************************************************************************
  175. Performs an execution step of a return-statement node. */
  176. UNIV_INTERN
  177. que_thr_t*
  178. return_step(
  179. /*========*/
  180. /* out: query thread to run next or NULL */
  181. que_thr_t* thr) /* in: query thread */
  182. {
  183. return_node_t* node;
  184. que_node_t* parent;
  185. ut_ad(thr);
  186. node = thr->run_node;
  187. ut_ad(que_node_get_type(node) == QUE_NODE_RETURN);
  188. parent = node;
  189. while (que_node_get_type(parent) != QUE_NODE_PROC) {
  190. parent = que_node_get_parent(parent);
  191. }
  192. ut_a(parent);
  193. thr->run_node = que_node_get_parent(parent);
  194. return(thr);
  195. }