~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/innobase/eval/eval0proc.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

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