📄 gen.c
字号:
if (request->req_flags & REQ_blr_version4) STUFF (blr_version4);else STUFF (blr_version5);STUFF (blr_begin);if (request->req_type == REQ_SELECT || request->req_type == REQ_SELECT_UPD) gen_select (request, node);else { message = request->req_send; if (!message->msg_parameter) request->req_send = NULL; else { GEN_port (request, message); if (request->req_type != REQ_EXEC_PROCEDURE) { STUFF (blr_receive); STUFF (message->msg_number); } } message = request->req_receive; if (!message->msg_parameter) request->req_receive = NULL; else GEN_port (request, message); GEN_statement (request, node); }STUFF (blr_end);STUFF (blr_eoc);}void GEN_start_transaction ( REQ request, NOD tran_node){/************************************** * * G E N _ s t a r t _ t r a n s a c t i o n * ************************************** * * Functional description * Generate tpb for set transaction. Use blr string of request. * If a value is not specified, default is not STUFF'ed, let the * engine handle it. * Do not allow an option to be specified more than once. * **************************************/NOD *temp, ptr, *end;SSHORT count;NOD reserve, node;SSHORT sw_access, sw_wait, sw_isolation, sw_reserve;USHORT lock_level;count = tran_node->nod_count;if (!count) return;sw_access = sw_wait = sw_isolation = sw_reserve = 0;node = tran_node->nod_arg [0];if (!node) return;/* find out isolation level - if specified. This is required for * specifying the correct lock level in reserving clause. */lock_level = gds__tpb_shared;if (count = node->nod_count) { while (count--) { ptr = node->nod_arg [count]; if ((!ptr) || (ptr->nod_type != nod_isolation)) continue; lock_level = (ptr->nod_flags & NOD_CONSISTENCY) ? gds__tpb_protected : gds__tpb_shared; } }/* Stuff some version info. */if (count = node->nod_count) STUFF (gds__tpb_version1);while (count--) { ptr = node->nod_arg [count]; if (!ptr) continue; switch (ptr->nod_type) { case nod_access: if (sw_access) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__dsql_dup_option, 0); sw_access = 1; if (ptr->nod_flags & NOD_READ_ONLY) STUFF (gds__tpb_read); else STUFF (gds__tpb_write); break; case nod_wait: if (sw_wait) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__dsql_dup_option, 0); sw_wait = 1; if (ptr->nod_flags & NOD_NO_WAIT) STUFF (gds__tpb_nowait); else STUFF (gds__tpb_wait); break; case nod_isolation: if (sw_isolation) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__dsql_dup_option, 0); sw_isolation = 1; if (ptr->nod_flags & NOD_CONCURRENCY) STUFF (gds__tpb_concurrency); else if (ptr->nod_flags & NOD_CONSISTENCY) STUFF (gds__tpb_consistency); else { STUFF (gds__tpb_read_committed); if ((ptr->nod_count) && (ptr->nod_arg [0]) && (ptr->nod_arg [0]->nod_type == nod_version)) { if (ptr->nod_arg [0]->nod_flags & NOD_VERSION) STUFF (gds__tpb_rec_version); else STUFF (gds__tpb_no_rec_version); } else STUFF (gds__tpb_no_rec_version); } break; case nod_reserve: if (sw_reserve) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__dsql_dup_option, 0); sw_reserve = 1; reserve = ptr->nod_arg [0]; if (reserve) for (temp = reserve->nod_arg, end = temp + reserve->nod_count; temp < end; temp++) gen_table_lock (request, *temp, lock_level); break; default: ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__dsql_tran_err, 0); } }}void GEN_statement ( REQ request, NOD node){/************************************** * * G E N _ s t a t e m e n t * ************************************** * * Functional description * Generate blr for an arbitrary expression. * **************************************/NOD temp, *ptr, *end;CTX context;MSG message;STR name;STR string;TEXT *p;ULONG id_length; switch (node->nod_type) { case nod_assign: STUFF (blr_assignment); GEN_expr (request, node->nod_arg [0]); GEN_expr (request, node->nod_arg [1]); return; case nod_block: STUFF (blr_block); GEN_statement (request, node->nod_arg [e_blk_action]); if (node->nod_count > 1) { temp = node->nod_arg [e_blk_errs]; for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++) GEN_statement (request, *ptr); } STUFF (blr_end); return; case nod_erase: if ((temp = node->nod_arg [e_era_rse]) != NULL) { STUFF (blr_for); GEN_expr (request, temp); } temp = node->nod_arg [e_era_relation]; context = (CTX) temp->nod_arg [e_rel_context]; STUFF (blr_erase); STUFF (context->ctx_context); return; case nod_erase_current: STUFF (blr_erase); context = (CTX) node->nod_arg [e_erc_context]; STUFF (context->ctx_context); return; case nod_exec_procedure: if (request->req_type == REQ_EXEC_PROCEDURE) { if (message = request->req_receive) { STUFF (blr_begin); STUFF (blr_send); STUFF (message->msg_number); } } else message = NULL; STUFF (blr_exec_proc); name = (STR) node->nod_arg [e_exe_procedure]; STUFF_CSTRING (name->str_data); if (temp = node->nod_arg [e_exe_inputs]) { STUFF_WORD (temp->nod_count); for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++) GEN_expr (request, *ptr); } else STUFF_WORD (0); if (temp = node->nod_arg [e_exe_outputs]) { STUFF_WORD (temp->nod_count); for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++) GEN_expr (request, *ptr); } else STUFF_WORD (0); if (message) STUFF (blr_end); return; case nod_for_select: gen_for_select (request, node); return; case nod_set_generator: case nod_set_generator2: STUFF (blr_set_generator); string = (STR) node->nod_arg [e_gen_id_name]; STUFF_CSTRING (string->str_data); GEN_expr (request, node->nod_arg [e_gen_id_value]); return; case nod_if: STUFF (blr_if); GEN_expr (request, node->nod_arg [e_if_condition]); GEN_statement (request, node->nod_arg [e_if_true]); if (node->nod_arg [e_if_false]) GEN_statement (request, node->nod_arg [e_if_false]); else STUFF (blr_end); return; case nod_list: STUFF (blr_begin); for (ptr = node->nod_arg, end = ptr + node->nod_count; ptr < end; ptr++) GEN_statement (request, *ptr); STUFF (blr_end); return; case nod_modify: if ((temp = node->nod_arg [e_mod_rse]) != NULL) { STUFF (blr_for); GEN_expr (request, temp); } STUFF (blr_modify); temp = node->nod_arg [e_mod_source]; context = (CTX) temp->nod_arg [e_rel_context]; STUFF (context->ctx_context); temp = node->nod_arg [e_mod_update]; context = (CTX) temp->nod_arg [e_rel_context]; STUFF (context->ctx_context); GEN_statement (request, node->nod_arg [e_mod_statement]); return; case nod_modify_current: STUFF (blr_modify); context = (CTX) node->nod_arg [e_mdc_context]; STUFF (context->ctx_context); temp = node->nod_arg [e_mdc_update]; context = (CTX) temp->nod_arg [e_rel_context]; STUFF (context->ctx_context); GEN_statement (request, node->nod_arg [e_mdc_statement]); return; case nod_on_error: STUFF (blr_error_handler); temp = node->nod_arg [e_err_errs]; STUFF_WORD (temp->nod_count); for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++) gen_error_condition (request, *ptr); GEN_statement (request, node->nod_arg [e_err_action]); return; case nod_post: STUFF (blr_post); GEN_expr (request, node->nod_arg [e_pst_event]); return; case nod_return: GEN_return (request, node->nod_arg [e_rtn_procedure], FALSE); return; case nod_exit: STUFF (blr_leave); STUFF (0); return; case nod_breakleave: STUFF (blr_leave); STUFF ((int) node->nod_arg [e_break_number]); return; case nod_exec_sql: STUFF (blr_exec_sql); GEN_expr (request, node->nod_arg [e_exec_vc]); return; case nod_store: if ((temp = node->nod_arg [e_sto_rse]) != NULL) { STUFF (blr_for); GEN_expr (request, temp); } STUFF (blr_store); GEN_expr (request, node->nod_arg [e_sto_relation]); GEN_statement (request, node->nod_arg [e_sto_statement]); return; case nod_abort: STUFF (blr_leave); STUFF ((int) node->nod_arg [e_abrt_number]); return; case nod_start_savepoint: STUFF (blr_start_savepoint); return; case nod_end_savepoint: STUFF (blr_end_savepoint); return; case nod_exception_stmt: STUFF (blr_abort); STUFF (blr_exception); string = (STR) node->nod_arg [0]; if (!(string->str_flags & STR_delimited_id)) { id_length = string->str_length; for (p = string->str_data; *p; id_length--) { *p = UPPER (*p); *p++; } } STUFF_CSTRING (string->str_data); return; case nod_while: STUFF (blr_label); STUFF ((int) node->nod_arg [e_while_number]); STUFF (blr_loop); STUFF (blr_begin); STUFF (blr_if); GEN_expr (request, node->nod_arg [e_while_cond]); GEN_statement (request, node->nod_arg [e_while_action]); STUFF (blr_leave); STUFF ((int) node->nod_arg [e_while_number]); STUFF (blr_end); return; case nod_sqlcode: case nod_gdscode: STUFF (blr_abort); gen_error_condition (request, node); return; default: ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -901, gds_arg_gds, gds__dsql_internal_err, gds_arg_gds, gds__node_err, /* gen.c: node not supported */ 0); }}static void gen_aggregate ( REQ request, NOD node){/************************************** * * g e n _ a g g r e g a t e * ************************************** * * Functional description * Generate blr for a relation reference. * **************************************/NOD list, *ptr, *end;CTX context;context = (CTX) node->nod_arg [e_agg_context];STUFF (blr_aggregate);STUFF (context->ctx_context);gen_rse (request, node->nod_arg [e_agg_rse]);/* Handle GROUP BY clause */STUFF (blr_group_by); if ((list = node->nod_arg [e_agg_group]) != NULL) { STUFF (list->nod_count); for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++) GEN_expr (request, *ptr); }else STUFF (0);/* Generate value map */gen_map (request, context->ctx_map);}static void gen_cast ( REQ request, NOD node){/************************************** * * g e n _ c a s t * ************************************** * * Functional description * Generate BLR for a data-type cast operation * **************************************/FLD field; STUFF (blr_cast);field = (FLD) node->nod_arg [e_cast_target];DDL_put_field_dtype (request, field, TRUE);GEN_expr (request, node->nod_arg [e_cast_source]);}static void gen_constant ( REQ request, DSC *desc, BOOLEAN negate_value){/************************************** * * g e n _ c o n s t a n t * ************************************** * * Functional description * Generate BLR for a constant. * **************************************/UCHAR *p;USHORT l;SLONG value;SINT64 i64value;DSC tmp_desc;STUFF (blr_literal);if ((desc->dsc_dtype == dtype_double) && (request->req_dbb->dbb_flags & DBB_v3)) /* v3 doesn't understand blr_double literal, generate blr_text instead */ { tmp_desc = *desc; tmp_desc.dsc_dtype = dtype_text; tmp_desc.dsc_length = desc->dsc_scale; /* length of string literal */ tmp_desc.dsc_scale = 0; desc = &tmp_desc; }l = desc->dsc_length;p = desc->dsc_address;switch (desc->dsc_dtype) { case dtype_short: gen_descriptor (request, desc, TRUE); value = *(SSHORT*) p; if (negate_value) value = -value; STUFF_WORD (value); break; case dtype_long: gen_descriptor (request, desc, TRUE); value = *(SLONG*) p; if (negate_value) value = -value; STUFF_WORD (value); STUFF_WORD (value >> 16); break; case dtype_sql_time: case dtype_sql_date: gen_descriptor (request, desc, TRUE); value = *(SLONG*) p; STUFF_WORD (value); STUFF_WORD (value >> 16); break; case dtype_double: /* this is used for approximate/large numeric literal which is transmitted to the engine as a string. */ gen_descriptor (request, desc, TRUE); l = (USHORT) desc->dsc_scale; /* length of string literal */ if (negate_value) { STUFF_WORD(l+1); STUFF('-'); } else { STUFF_WORD (l); } if (l) do STUFF (*p++); while (--l); break; case dtype_int64: i64value = *(SINT64 *)p; if (negate_value) i64value = -i64value; else if (i64value == MIN_SINT64) { /* UH OH! * yylex correctly recognized the digits as the most-negative * possible INT64 value, but unfortunately, there was no * preceding '-' (a fact which the lexer could not know). * The value is too big for a positive INT64 value, and it * didn't contain an exponent so it's not a valid DOUBLE * PRECISION literal either, so we have to bounce it. */ ERRD_post(isc_sqlerr, gds_arg_number, (SLONG) -104 , gds_arg_gds , isc_arith_except, 0); } /* We and the lexer both agree that this is an SINT64 constant, * and if the value needed to be negated, it already has been. * If the value will fit into a 32-bit signed integer, generate * it that way, else as an INT64. */ if ( (i64value >= (SINT64) MIN_SLONG) && (i64value <= (SINT64) MAX_SLONG) ) { STUFF (blr_long); STUFF (desc->dsc_scale); STUFF_WORD (i64value); STUFF_WORD (i64value >> 16); break; } else { STUFF (blr_int64); STUFF (desc->dsc_scale); STUFF_WORD (i64value); STUFF_WORD (i64value >> 16); STUFF_WORD (i64value >> 32); STUFF_WORD (i64value >> 48); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -