📄 pass1.c
字号:
/* Insure that variable names do not duplicate parameter names */ if (variables = input->nod_arg [e_prc_dcls]) { for (ptr = variables->nod_arg, end = ptr + variables->nod_count; ptr < end; ptr++) { field = (FLD) (*ptr)->nod_arg [e_dfl_field]; DEV_BLKCHK (field, type_fld); if (parameters = input->nod_arg [e_prc_inputs]) for (ptr2 = parameters->nod_arg, end2 = ptr2 + parameters->nod_count; ptr2 < end2; ptr2++) { field2 = (FLD) (*ptr2)->nod_arg [e_dfl_field]; DEV_BLKCHK (field2, type_fld); if (!strcmp (field->fld_name, field2->fld_name)) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, gds_arg_gds, gds__dsql_var_conflict, gds_arg_string, field->fld_name, 0); } if (parameters = input->nod_arg [e_prc_outputs]) for (ptr2 = parameters->nod_arg, end2 = ptr2 + parameters->nod_count; ptr2 < end2; ptr2++) { field2 = (FLD) (*ptr2)->nod_arg [e_dfl_field]; DEV_BLKCHK (field2, type_fld); if (!strcmp (field->fld_name, field2->fld_name)) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, gds_arg_gds, gds__dsql_var_conflict, gds_arg_string, field->fld_name, 0); } } } return input; case nod_assign: node = MAKE_node (input->nod_type, input->nod_count); node->nod_arg [0] = PASS1_node (request, input->nod_arg [0], proc_flag); node->nod_arg [1] = PASS1_node (request, input->nod_arg [1], proc_flag); break; case nod_commit: if ((input->nod_arg [e_commit_retain]) && (input->nod_arg [e_commit_retain]->nod_type == nod_commit_retain)) request->req_type = REQ_COMMIT_RETAIN; else request->req_type = REQ_COMMIT; return input; case nod_delete: node = pass1_delete (request, input); if (request->req_error_handlers) { temp = MAKE_node (nod_list, 3); temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0); temp->nod_arg [1] = node; temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0); node = temp; } break; case nod_exec_procedure: if (!proc_flag) { name = (STR) input->nod_arg [e_exe_procedure]; DEV_BLKCHK (name, type_str); if (!(request->req_procedure = METD_get_procedure (request, name))) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -204, gds_arg_gds, gds__dsql_procedure_err, gds_arg_gds, gds__random, gds_arg_string, name->str_data, 0); request->req_type = REQ_EXEC_PROCEDURE; } node = MAKE_node (input->nod_type, input->nod_count); node->nod_arg [e_exe_procedure] = input->nod_arg [e_exe_procedure]; node->nod_arg [e_exe_inputs] = PASS1_node (request, input->nod_arg [e_exe_inputs], proc_flag); if (temp = input->nod_arg [e_exe_outputs]) node->nod_arg [e_exe_outputs] = (temp->nod_type == nod_all) ? explode_outputs (request, request->req_procedure) : PASS1_node (request, temp, proc_flag); if (!proc_flag) { if (node->nod_arg [e_exe_inputs]) count = node->nod_arg [e_exe_inputs]->nod_count; else count = 0; if (count != request->req_procedure->prc_in_count) ERRD_post (gds__prcmismat, gds_arg_string, name->str_data, 0); if (count) { /* Initialize this stack variable, and make it look like a node */ memset ((SCHAR *)&desc_node, 0, sizeof (desc_node)); desc_node.nod_header.blk_type = type_nod; for (ptr = node->nod_arg [e_exe_inputs]->nod_arg, field = request->req_procedure->prc_inputs; field; ptr++, field = field->fld_next) { DEV_BLKCHK (field, type_fld); DEV_BLKCHK (*ptr, type_nod); MAKE_desc_from_field (&desc_node.nod_desc, field); set_parameter_type (*ptr, &desc_node, FALSE); } } } break; case nod_for_select: node = MAKE_node (input->nod_type, input->nod_count); node->nod_flags = input->nod_flags; cursor = node->nod_arg [e_flp_cursor] = input->nod_arg [e_flp_cursor]; if (cursor && (procedure = request->req_ddl_node) && ((procedure->nod_type == nod_def_procedure) || (procedure->nod_type == nod_mod_procedure) || procedure->nod_type == nod_def_trigger || procedure->nod_type == nod_mod_trigger)) { cursor->nod_arg [e_cur_next] = procedure->nod_arg [e_prc_cursors]; procedure->nod_arg [e_prc_cursors] = cursor; cursor->nod_arg [e_cur_context] = node; } node->nod_arg [e_flp_select] = PASS1_statement (request, input->nod_arg [e_flp_select], proc_flag); into_in = input->nod_arg [e_flp_into]; node->nod_arg [e_flp_into] = into_out = MAKE_node (into_in->nod_type, into_in->nod_count); ptr2 = into_out->nod_arg; for (ptr = into_in->nod_arg, end = ptr + into_in->nod_count; ptr < end; ptr++) { DEV_BLKCHK (*ptr, type_nod); *ptr2++ = PASS1_node (request, *ptr, proc_flag); DEV_BLKCHK (*(ptr2-1), type_nod); } if (input->nod_arg [e_flp_action]) { /* CVC: Let's add the ability to BREAK the for_select same as the while. but only if the command is FOR SELECT, otherwise we have singular SELECT. */ node->nod_arg [e_flp_number] = (NOD) request->req_loop_number++; node->nod_arg [e_flp_action] = PASS1_statement (request, input->nod_arg [e_flp_action], proc_flag); } if (cursor && procedure && ((procedure->nod_type == nod_def_procedure) || (procedure->nod_type == nod_mod_procedure) || procedure->nod_type == nod_def_trigger || procedure->nod_type == nod_mod_trigger)) procedure->nod_arg [e_prc_cursors] = cursor->nod_arg [e_cur_next]; if (request->req_error_handlers && (input->nod_flags & NOD_SINGLETON_SELECT)) { temp = MAKE_node (nod_list, 3); temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0); temp->nod_arg [1] = node; temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0); node = temp; } break; case nod_get_segment: case nod_put_segment: pass1_blob (request, input); return input; case nod_if: node = MAKE_node (input->nod_type, input->nod_count); node->nod_arg [e_if_condition] = PASS1_node (request, input->nod_arg [e_if_condition], proc_flag); node->nod_arg [e_if_true] = PASS1_statement (request, input->nod_arg [e_if_true], proc_flag); if (input->nod_arg [e_if_false]) node->nod_arg [e_if_false] = PASS1_statement (request, input->nod_arg [e_if_false], proc_flag); else node->nod_arg [e_if_false] = NULL; break; case nod_exception_stmt: node = input; if (request->req_error_handlers) { temp = MAKE_node (nod_list, 3); temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0); temp->nod_arg [1] = input; temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0); node = temp; } return node; case nod_insert: node = pass1_insert (request, input); if (request->req_error_handlers) { temp = MAKE_node (nod_list, 3); temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0); temp->nod_arg [1] = node; temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0); node = temp; } break; case nod_block: if (input->nod_arg [e_blk_errs]) request->req_error_handlers++; else { input->nod_count = 1; if (!request->req_error_handlers) input->nod_type = nod_list; } case nod_list: node = MAKE_node (input->nod_type, input->nod_count); ptr2 = node->nod_arg; for (ptr = input->nod_arg, end = ptr + input->nod_count; ptr < end; ptr++) { DEV_BLKCHK (*ptr, type_nod); if ((*ptr)->nod_type == nod_assign) *ptr2++ = PASS1_node (request, *ptr, proc_flag); else *ptr2++ = PASS1_statement (request, *ptr, proc_flag); DEV_BLKCHK (*(ptr2-1), type_nod); } if (input->nod_type == nod_block && input->nod_arg [e_blk_errs]) request->req_error_handlers--; return node; case nod_on_error: node = MAKE_node (input->nod_type, input->nod_count); node->nod_arg [e_err_errs] = input->nod_arg [e_err_errs]; node->nod_arg [e_err_action] = PASS1_statement (request, input->nod_arg [e_err_action], proc_flag); return node; case nod_post: node = MAKE_node (input->nod_type, input->nod_count); node->nod_arg [e_pst_event] = PASS1_node (request, input->nod_arg [e_pst_event], proc_flag); return node; case nod_rollback: request->req_type = REQ_ROLLBACK; return input; case nod_exit: if (request->req_flags & REQ_trigger) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__token_err, /* Token unknown */ gds_arg_gds, gds__random, gds_arg_string, "EXIT", 0); return input; case nod_breakleave: input->nod_arg [e_break_number] = (NOD) (request->req_loop_number - 1); return input; case nod_exec_sql: node = MAKE_node (input->nod_type, input->nod_count); node->nod_arg [e_exec_vc] = PASS1_node (request, input->nod_arg [e_exec_vc], proc_flag); return node; case nod_return: if (request->req_flags & REQ_trigger) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__token_err, /* Token unknown */ gds_arg_gds, gds__random, gds_arg_string, "RETURN", 0); input->nod_arg [e_rtn_procedure] = request->req_ddl_node; return input; case nod_select: node = PASS1_rse (request, input->nod_arg [0], input->nod_arg [1]); if (input->nod_arg [2]) { request->req_type = REQ_SELECT_UPD; request->req_flags |= REQ_no_batch; break; } /* ** If there is a union without ALL or order by or a select distinct ** buffering is OK even if stored procedure occurs in the select ** list. In these cases all of stored procedure is executed under ** savepoint for open cursor. */ if (((temp = node->nod_arg [e_rse_streams]) && (temp->nod_type == nod_union) && temp->nod_arg [e_rse_reduced]) || node->nod_arg [e_rse_sort] || node->nod_arg [e_rse_reduced]) request->req_flags &= ~REQ_no_batch; break; case nod_trans: request->req_type = REQ_START_TRANS; return input; case nod_update: node = pass1_update (request, input); if (request->req_error_handlers) { temp = MAKE_node (nod_list, 3); temp->nod_arg [0] = MAKE_node (nod_start_savepoint, 0); temp->nod_arg [1] = node; temp->nod_arg [2] = MAKE_node (nod_end_savepoint, 0); node = temp; } break; case nod_while: node = MAKE_node (input->nod_type, input->nod_count); node->nod_arg [e_while_cond] = PASS1_node (request, input->nod_arg [e_while_cond], proc_flag); /* CVC: loop numbers should be incremented before analyzing the body to preserve nesting <==> increasing level number. */ node->nod_arg [e_while_number] = (NOD) request->req_loop_number++; node->nod_arg [e_while_action] = PASS1_statement (request, input->nod_arg [e_while_action], proc_flag); break; case nod_abort: case nod_exception: case nod_sqlcode: case nod_gdscode: return input; case nod_null: return NULL; case nod_set_generator: node = MAKE_node (input->nod_type, e_gen_id_count); node->nod_arg [e_gen_id_value] = PASS1_node (request, input->nod_arg [e_gen_id_value],proc_flag); node->nod_arg [e_gen_id_name] = input->nod_arg [e_gen_id_name]; request->req_type = REQ_SET_GENERATOR; break; case nod_set_generator2: node = MAKE_node (input->nod_type, e_gen_id_count); node->nod_arg [e_gen_id_value] = PASS1_node (request, input->nod_arg [e_gen_id_value],proc_flag); node->nod_arg [e_gen_id_name] = input->nod_arg [e_gen_id_name]; request->req_type = REQ_SET_GENERATOR; break; case nod_union: ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, gds_arg_gds, gds__dsql_command_err, gds_arg_gds, gds__union_err, /* union not supported */ 0); break; default: ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, gds_arg_gds, gds__dsql_command_err, gds_arg_gds, gds__dsql_construct_err, /* Unsupported DSQL construct */ 0); break; }/* Finish off by cleaning up contexts */while (request->req_context != base) LLS_POP (&request->req_context);#ifdef DEV_BUILDif (DSQL_debug > 1) DSQL_pretty (node, 0);#endifreturn node;} static BOOLEAN aggregate_found ( REQ request, NOD sub, NOD *proj){/************************************** * * a g g r e g a t e _ f o u n d * ************************************** * * Functional description * Check for an aggregate expression in an * rse select list. It could be buried in * an expression tree. * **************************************/BOOLEAN aggregate, field;DEV_BLKCHK (request, type_req);DEV_BLKCHK (sub, type_nod);field = FALSE;aggregate = aggregate_found2 (request, sub, proj, &field);if (field && aggregate) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__field_aggregate_err, /* field used with aggregate */ 0);return aggregate;}static BOOLEAN aggregate_found2 ( REQ request, NOD sub, NOD *proj, BOOLEAN *field){/************************************** * * a g g r e g a t e _ f o u n d 2 * ************************************** * * Functional description * Check for an aggregate expression in an * rse select list. It could be buried in * an expression tree. * * field is true if a non-aggregate field reference is seen. * **************************************/BOOLEAN aggregate;NOD *ptr, *end;DEV_BLKCHK (request, type_req);DEV_BLKCHK (sub, type_nod);switch (sub->nod_type) { /* handle the simple case of a straightforward aggregate */ case nod_agg_average: case nod_agg_average2: case nod_agg_total2: case nod_agg_max: case nod_agg_min: case nod_agg_total: case nod_agg_count: if ((sub->nod_flags & NOD_AGG_DISTINCT) && (request->req_dbb->dbb_flags & DBB_v3)) { /* NOTE: leave the v3 behaviour intact, even though it */ /* is incorrect in most cases! */ /* this aggregate requires a projection to be generated */ *proj = PASS1_node (request, sub->nod_arg [0], 0); } return TRUE; case nod_field: *field = TRUE; return FALSE; case nod_constant: return FALSE; /* for expressions in which an aggregate might be buried, recursively check for one */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -