📄 exe.c
字号:
{ VARY *vary; vary = (VARY*) p; if ((length = desc->dsc_length - sizeof (USHORT)) > vary->vary_length) { p = vary->vary_string + vary->vary_length; length -= vary->vary_length; do *p++ = 0; while (--length); } } }}static NOD erase ( TDBB tdbb, NOD node, SSHORT which_trig){/************************************** * * e r a s e * ************************************** * * Functional description * Perform erase operation. * **************************************/DBB dbb;REQ request, trigger;RPB *rpb;REL relation;REC record;FMT format;TRA transaction;#ifdef PC_ENGINELCK implicit_lock = NULL, record_locking;RSB rsb = NULL;JMP_BUF env, *old_env;IRSB impure;#endifSET_TDBB (tdbb);dbb = tdbb->tdbb_database;BLKCHK (node, type_nod);request = tdbb->tdbb_request;transaction = request->req_transaction;rpb = &request->req_rpb [(int) node->nod_arg [e_erase_stream]];relation = rpb->rpb_relation;#ifdef PC_ENGINE/* for navigational streams, retrieve the rsb */if (node->nod_arg [e_erase_rsb]) { rsb = *(RSB*) node->nod_arg [e_erase_rsb]; impure = (IRSB) ((UCHAR*) request + rsb->rsb_impure); }#endifswitch (request->req_operation) { case req_evaluate: if (!node->nod_arg [e_erase_statement]) break; format = MET_current (tdbb, rpb->rpb_relation); record = VIO_record (tdbb, rpb, format, tdbb->tdbb_default); rpb->rpb_address = record->rec_data; rpb->rpb_length = format->fmt_length; rpb->rpb_format_number = format->fmt_version; return node->nod_arg [e_erase_statement]; case req_return: break; default: return node->nod_parent; } #ifdef PC_ENGINE/* if we are on a crack in a navigational stream, erase is not a valid operation */if (rsb && EXE_crack (tdbb, rsb, irsb_bof | irsb_eof | irsb_crack)) { EXE_mark_crack (tdbb, rsb, impure->irsb_flags); request->req_operation = req_return; return node->nod_parent; }#endif request->req_operation = req_return;RLCK_reserve_relation (tdbb, transaction, relation, TRUE, TRUE);/* If the stream was sorted, the various fields in the rpb are probably junk. Just to make sure that everything is cool, refetch and release the record. */if (rpb->rpb_stream_flags & RPB_s_refetch) { SLONG tid_fetch; tid_fetch = rpb->rpb_transaction; if ((!DPM_get (tdbb, rpb, LCK_read)) || (!VIO_chase_record_version (tdbb, rpb, NULL, transaction, tdbb->tdbb_default))) ERR_post (gds__deadlock, gds_arg_gds, gds__update_conflict, 0); VIO_data (tdbb, rpb, tdbb->tdbb_request->req_pool); /* If record is present, and the transaction is read committed, * make sure the record has not been updated. Also, punt after * VIO_data () call which will release the page. */ if ((transaction->tra_flags & TRA_read_committed) && (tid_fetch != rpb->rpb_transaction)) ERR_post (gds__deadlock, gds_arg_gds, gds__update_conflict, 0); rpb->rpb_stream_flags &= ~RPB_s_refetch; }#ifndef GATEWAY #ifdef PC_ENGINE/* set up to do record locking; in case of a consistency mode transaction, we already have an exclusive lock on the table, so don't bother */if (!(transaction->tra_flags & TRA_degree3)) { /* check whether record locking is turned on */ record_locking = RLCK_record_locking (relation); if (record_locking->lck_physical != LCK_PR) { /* get an implicit lock on the record */ implicit_lock = implicit_record_lock (transaction, rpb); /* set up to catch any errors so that we can release the implicit lock */ old_env = (JMP_BUF*) tdbb->tdbb_setjmp; tdbb->tdbb_setjmp = (UCHAR*) env; if (SETJMP (env)) { tdbb->tdbb_setjmp = (UCHAR*) old_env; RLCK_unlock_record_implicit (implicit_lock, NULL_PTR); LONGJMP (old_env, -1); } } }#endifif (transaction != dbb->dbb_sys_trans) ++transaction->tra_save_point->sav_verb_count;/* Handle pre-operation trigger */if (relation->rel_pre_erase && which_trig != POST_TRIG && (trigger = execute_triggers (tdbb, &relation->rel_pre_erase, rpb->rpb_record, NULL_PTR))) trigger_failure (tdbb, trigger);if (relation->rel_file) EXT_erase (rpb, transaction);else if (!relation->rel_view_rse) VIO_erase (tdbb, rpb, transaction);/* Handle post operation trigger */if (relation->rel_post_erase && which_trig != PRE_TRIG && (trigger = execute_triggers (tdbb, &relation->rel_post_erase, rpb->rpb_record, NULL_PTR))) trigger_failure (tdbb, trigger);/* call IDX_erase (which checks constraints) after all post erase triggers have fired. This is required for cascading referential integrity, which can be implemented as post_erase triggers */if (!relation->rel_file & !relation->rel_view_rse) { REL bad_relation; USHORT bad_index; IDX_E error_code; if (error_code = IDX_erase (tdbb, rpb, transaction, &bad_relation, &bad_index)) ERR_duplicate_error (error_code, bad_relation, bad_index); } /* CVC: Increment the counter only if we called VIO/EXT_erase() and we were successful. */ if (relation->rel_file || !relation->rel_view_rse) request->req_records_deleted++;if (transaction != dbb->dbb_sys_trans) --transaction->tra_save_point->sav_verb_count;#ifdef PC_ENGINEif (implicit_lock) { tdbb->tdbb_setjmp = (UCHAR*) old_env; RLCK_unlock_record_implicit (implicit_lock, NULL_PTR); }/* if the stream is navigational, it is now positioned on a crack */if (rsb) RSE_MARK_CRACK (tdbb, rsb, irsb_crack);#endif#elseVIO_erase (rpb, transaction, node->nod_arg [e_erase_sql]);#endifreturn node->nod_parent;}static void exec_sql ( REQ request, TDBB tdbb, DSC *dsc){/************************************** * * e x e c _ s q l * ************************************** * * Functional description * Execute a string like SQL operator. * **************************************/#ifndef STACK_REDUCTIONUCHAR *p, buffer[BUFFER_LARGE + 1];#elseSTR temp_str;UCHAR *p, *buffer;#endifSSHORT l;STATUS *status, local[ISC_STATUS_LENGTH];static char *cba = "Callback Argument";#ifdef STACK_REDUCTION/* do a block allocation of local variable */temp_str = (STR) ALLOCDV (type_str, (SLONG)(sizeof (UCHAR) * (BUFFER_LARGE + 1)));buffer = temp_str->str_data;#endifmemset(local, 0, sizeof local);status = local;SET_TDBB (tdbb);p = 0;l = MOV_get_string (dsc, &p, buffer, BUFFER_LARGE);if (p) { if (tdbb->tdbb_transaction->tra_callback_count >= MAX_CALLBACKS) { status[0] = gds_arg_gds; status[1] = gds__req_max_clones_exceeded; status[2] = gds_arg_end; } else { tdbb->tdbb_transaction->tra_callback_count++; callback_execute_immediate ( status, (int *)(tdbb->tdbb_attachment), (int *)(tdbb->tdbb_transaction), p, l); tdbb->tdbb_transaction->tra_callback_count--; } }else { status[0] = gds_arg_gds; status[1] = gds__convert_error; status[2] = gds_arg_string; status[3] = cba; status[4] = gds_arg_end; }#ifdef STACK_REDUCTION/* block de-alloc */ALL_release (temp_str);#endifif (status[1]) { /* SET_TDBB (tdbb); */ memcpy(tdbb->tdbb_status_vector, status, sizeof(local)); ERR_punt(); }}static void execute_looper ( TDBB tdbb, REQ request, TRA transaction, ENUM req_s next_state){/************************************** * * e x e c u t e _ l o o p e r * ************************************** * * Functional description * Wrapper around looper. This will execute * looper with the save point mechanism. * **************************************/DBB dbb;DEV_BLKCHK (request, type_req);SET_TDBB (tdbb);dbb = tdbb->tdbb_database;/* Start a save point */if (!(request->req_flags & req_proc_fetch) && request->req_transaction) if (transaction && (transaction != dbb->dbb_sys_trans)) VIO_start_save_point (tdbb, transaction);request->req_flags &= ~req_stall;request->req_operation = next_state;looper (tdbb, request, request->req_next);/* If any requested modify/delete/insert ops have completed, forget them */if (!(request->req_flags & req_proc_fetch) && request->req_transaction) if (transaction && (transaction != dbb->dbb_sys_trans) && transaction->tra_save_point && !transaction->tra_save_point->sav_verb_count) { /* Forget about any undo for this verb */ VIO_verb_cleanup (tdbb, transaction); }}static void execute_procedure ( TDBB tdbb, NOD node){/************************************** * * e x e c u t e _ p r o c e d u r e * ************************************** * * Functional description * Execute a stored procedure. Begin by * assigning the input parameters. End * by assigning the output parameters. * **************************************/REQ request, proc_request;NOD in_message, out_message, temp;FMT format;USHORT in_msg_length, out_msg_length;SCHAR *in_msg, *out_msg;PRC procedure;STR temp_buffer = NULL;SLONG save_point_number;TRA transaction;JMP_BUF env, *old_env;struct plb *old_pool;SET_TDBB (tdbb);BLKCHK (node, type_nod);request = tdbb->tdbb_request;if (temp = node->nod_arg [e_esp_inputs]) { NOD *ptr, *end; for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++) EXE_assignment (tdbb, *ptr); }if (in_message = node->nod_arg [e_esp_in_msg]) { format = (FMT) in_message->nod_arg [e_msg_format]; in_msg_length = format->fmt_length; in_msg = (SCHAR*) request + in_message->nod_impure; }if (out_message = node->nod_arg [e_esp_out_msg]) { format = (FMT) out_message->nod_arg [e_msg_format]; out_msg_length = format->fmt_length; out_msg = (SCHAR*) request + out_message->nod_impure; }procedure = (PRC) node->nod_arg [e_esp_procedure];proc_request = EXE_find_request (tdbb, procedure->prc_request, FALSE);if (!out_message) { format = (FMT) procedure->prc_output_msg->nod_arg [e_msg_format]; out_msg_length = format->fmt_length; temp_buffer = (STR) ALLOCDV (type_str, out_msg_length + DOUBLE_ALIGN - 1); out_msg = (SCHAR*) FB_ALIGN((U_IPTR) temp_buffer->str_data, DOUBLE_ALIGN); }/* Save the old pool */old_pool = tdbb->tdbb_default;tdbb->tdbb_default = proc_request->req_pool;/* Catch errors so we can unwind cleanly */old_env = (JMP_BUF*) tdbb->tdbb_setjmp;tdbb->tdbb_setjmp = (UCHAR*) env;if (SETJMP (env)) { tdbb->tdbb_setjmp = (UCHAR*) old_env; tdbb->tdbb_default = old_pool; tdbb->tdbb_request = request; EXE_unwind (tdbb, proc_request); proc_request->req_flags &= ~(req_in_use | req_proc_fetch); proc_request->req_timestamp = 0; if (temp_buffer) ALL_release (temp_buffer); LONGJMP (old_env, -1); }transaction = request->req_transaction;save_point_number = transaction->tra_save_point->sav_number;proc_request->req_timestamp = request->req_timestamp;EXE_start (tdbb, proc_request, transaction);if (in_message) EXE_send (tdbb, proc_request, 0, in_msg_length, in_msg);EXE_receive (tdbb, proc_request, 1, out_msg_length, out_msg);/* Clean up all savepoints started during execution of the procedure */if (transaction != tdbb->tdbb_database->dbb_sys_trans) { SAV save_point; for (save_point = transaction->tra_save_point; save_point && save_point_number < save_point->sav_number; save_point = transaction->tra_save_point) VIO_verb_cleanup (tdbb, transaction); }tdbb->tdbb_setjmp = (UCHAR*) old_env;tdbb->tdbb_default = old_pool;EXE_unwind (tdbb, proc_request);tdbb->tdbb_request = request;if (temp = node->nod_arg [e_esp_outputs]) { NOD *ptr, *end; for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++) EXE_assignment (tdbb, *ptr); }if (temp_buffer) ALL_release (temp_buffer);proc_request->req_attachment = NULL;proc_request->req_flags &= ~(req_in_use | req_proc_fetch);proc_request->req_timestamp = 0;}#ifndef GATEWAYstatic REQ execute_triggers ( TDBB tdbb, VEC *triggers, REC old_rec, REC new_rec){/************************************** * * e x e c u t e _ t r i g g e r s * ************************************** * * Functional description * Execute group of triggers. Return pointer to failing trigger * if any blow up. * **************************************/REQ *ptr, *end, result;VOLATILE REQ trigger = NULL;TRA transaction;VOLATILE VEC vector;JMP_BUF env, *old_env;DEV_BLKCHK (*triggers, type_vec);DEV_BLKCHK (old_rec, type_rec);DEV_BLKCHK (new_rec, type_rec);if (!*triggers) return NULL;SET_TDBB (tdbb);transaction = tdbb->tdbb_request->req_transaction;vector = *triggers;result = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -