| 2150 | // |
| 2151 | |
| 2152 | static act* par_for() |
| 2153 | { |
| 2154 | TEXT s[ERROR_LENGTH]; |
| 2155 | gpre_sym* symbol = NULL; |
| 2156 | bool dup_symbol = false; |
| 2157 | |
| 2158 | tok& token = gpreGlob.token_global; |
| 2159 | |
| 2160 | if (token.tok_keyword != KW_FIRST && token.tok_keyword != KW_LEFT_PAREN) |
| 2161 | { |
| 2162 | if (token.tok_symbol) |
| 2163 | dup_symbol = true; |
| 2164 | |
| 2165 | symbol = MSC_symbol(SYM_cursor, token.tok_string, token.tok_length, 0); |
| 2166 | PAR_get_token(); |
| 2167 | |
| 2168 | if (!MSC_match(KW_IN)) |
| 2169 | { |
| 2170 | MSC_free(symbol); |
| 2171 | return NULL; |
| 2172 | } |
| 2173 | if (dup_symbol) |
| 2174 | { |
| 2175 | fb_utils::snprintf(s, sizeof(s), "symbol %s is already in use", token.tok_string); |
| 2176 | PAR_error(s); |
| 2177 | } |
| 2178 | |
| 2179 | const gpre_sym* temp = token.tok_symbol; |
| 2180 | if (temp && temp->sym_type == SYM_context) |
| 2181 | return par_open_blob(ACT_blob_for, symbol); |
| 2182 | } |
| 2183 | |
| 2184 | // Make up request block. Since this might not be a database statement, |
| 2185 | // stay ready to back out if necessay. |
| 2186 | |
| 2187 | gpre_req* request = MSC_request(REQ_for); |
| 2188 | |
| 2189 | gpre_rse* rec_expr; |
| 2190 | if (!par_options(request, true) || !(rec_expr = EXP_rse(request, symbol))) |
| 2191 | { |
| 2192 | MSC_free_request(request); |
| 2193 | return NULL; |
| 2194 | } |
| 2195 | |
| 2196 | act* action = MSC_action(request, ACT_for); |
| 2197 | MSC_push((gpre_nod*) action, &cur_for); |
| 2198 | |
| 2199 | request->req_rse = rec_expr; |
| 2200 | gpre_ctx* context = rec_expr->rse_context[0]; |
| 2201 | gpre_rel* relation = context->ctx_relation; |
| 2202 | request->req_database = relation->rel_database; |
| 2203 | |
| 2204 | gpre_ctx** ptr = rec_expr->rse_context; |
| 2205 | for (const gpre_ctx* const* const end = ptr + rec_expr->rse_count; ptr < end; ptr++) |
| 2206 | { |
| 2207 | context = *ptr; |
| 2208 | context->ctx_next = request->req_contexts; |
| 2209 | request->req_contexts = context; |
no test coverage detected