📄 exe.c
字号:
/* correct boolean rsbs to point to the "real" rsb */if (rsb->rsb_type == rsb_boolean) rsb = rsb->rsb_next;RSE_MARK_CRACK (tdbb, rsb, flag);if (flag == irsb_eof) ERR_warning (gds__stream_eof, 0);else if (flag == irsb_bof) ERR_warning (gds__stream_bof, 0);else if (flag & irsb_crack) ERR_warning (gds__stream_crack, 0);}#endifvoid EXE_receive ( TDBB tdbb, register REQ request, USHORT msg, USHORT length, UCHAR *buffer){/************************************** * * E X E _ r e c e i v e * ************************************** * * Functional description * Move a message from JRD to the host program. This corresponds to * a JRD BLR/NOD send. * **************************************/NOD message;FMT format;TRA transaction;SAV save_sav_point;JMP_BUF env, *old_env;SET_TDBB (tdbb);DEV_BLKCHK (request, type_req);transaction = request->req_transaction;if (!(request->req_flags & req_active)) ERR_post (gds__req_sync, 0);if (request->req_flags & req_proc_fetch) { /* request->req_proc_sav_point stores all the request savepoints. When going to continue execution put request save point list into transaction->tra_save_point so that it is used in looper. When we come back to EXE_receive() restore transaction->tra_save_point and merge all work done under stored procedure savepoints into the current transaction savepoint, which is the savepoint for fetch. */ save_sav_point = transaction->tra_save_point; transaction->tra_save_point = request->req_proc_sav_point; request->req_proc_sav_point = save_sav_point; if (!transaction->tra_save_point) VIO_start_save_point (tdbb, transaction); old_env = (JMP_BUF*) tdbb->tdbb_setjmp; tdbb->tdbb_setjmp = (UCHAR*) env; if (SETJMP (env)) { tdbb->tdbb_setjmp = (UCHAR*) old_env; save_sav_point = transaction->tra_save_point; transaction->tra_save_point = request->req_proc_sav_point; request->req_proc_sav_point = save_sav_point; release_proc_save_points (request); LONGJMP (old_env, -1); } }if (request->req_message->nod_type == nod_stall#ifdef SCROLLABLE_CURSORS|| request->req_flags & req_fetch_required#endif) execute_looper (tdbb, request, transaction, req_sync);if (!(request->req_flags & req_active) || request->req_operation != req_send) ERR_post (gds__req_sync, 0);message = request->req_message;format = (FMT) message->nod_arg [e_msg_format];if (msg != (USHORT) message->nod_arg [e_msg_number]) ERR_post (gds__req_sync, 0);if (length != format->fmt_length) ERR_post (gds__port_len, gds_arg_number, (SLONG) length, gds_arg_number, (SLONG) format->fmt_length, 0);if ((U_IPTR) buffer & (ALIGNMENT - 1)) MOVE_FAST ((SCHAR*) request + message->nod_impure, buffer, length);else MOVE_FASTER ((SCHAR*) request + message->nod_impure, buffer, length);execute_looper (tdbb, request, transaction, req_proceed);if (request->req_flags & req_proc_fetch) { tdbb->tdbb_setjmp = (UCHAR*) old_env; save_sav_point = transaction->tra_save_point; transaction->tra_save_point = request->req_proc_sav_point; request->req_proc_sav_point = save_sav_point; VIO_merge_proc_sav_points (tdbb, transaction, &request->req_proc_sav_point); }}#ifdef SCROLLABLE_CURSORSvoid EXE_seek ( TDBB tdbb, REQ request, USHORT direction, ULONG offset){/************************************** * * E X E _ s e e k * ************************************** * * Functional description * Seek a given request in a particular direction * for offset records. * **************************************/VEC vector;RSB rsb;SLONG i;SET_TDBB (tdbb);DEV_BLKCHK (request, type_req);/* loop through all RSEs in the request, and describe the rsb tree for that rsb; go backwards because items were popped off the stack backwards */vector = request->req_fors;if (!vector) return FALSE;/* find the top-level rsb in the request and seek it */for (i = vector->vec_count - 1; i >= 0; i--) if (rsb = (RSB) vector->vec_object [i]) { seek_rsb (tdbb, request, rsb, direction, offset); break; }}#endifvoid EXE_send ( TDBB tdbb, REQ request, USHORT msg, USHORT length, UCHAR *buffer){/************************************** * * E X E _ s e n d * ************************************** * * Functional description * Send a message from the host program to the engine. * This corresponds to a blr_receive or blr_select statement. * **************************************/NOD node, message, *ptr, *end;FMT format;TRA transaction;#ifdef SCROLLABLE_CURSORSUSHORT save_operation;NOD save_next = NULL, save_message;#endifSET_TDBB (tdbb);DEV_BLKCHK (request, type_req);if (!(request->req_flags & req_active)) ERR_post (gds__req_sync, 0);#ifdef SCROLLABLE_CURSORS/* look for an asynchronous send message--if such a message was defined, we allow the user to send us a message at any time during request execution */if ((message = request->req_async_message) && (node = message->nod_arg [e_send_message]) && (msg == (USHORT) node->nod_arg [e_msg_number])) { /* save the current state of the request so we can go back to what was interrupted */ save_operation = request->req_operation; save_message = request->req_message; save_next = request->req_next; request->req_operation = req_receive; request->req_message = node; request->req_next = message->nod_arg [e_send_statement]; /* indicate that we are processing an asynchronous message */ request->req_flags |= req_async_processing; }else {#endif if (request->req_operation != req_receive) ERR_post (gds__req_sync, 0); node = request->req_message;#ifdef SCROLLABLE_CURSORS }#endiftransaction = request->req_transaction;if (node->nod_type == nod_message) message = node;else if (node->nod_type == nod_select) for (ptr = node->nod_arg, end = ptr + node->nod_count; ptr < end; ptr++) { message = (*ptr)->nod_arg [e_send_message]; if ((USHORT) message->nod_arg [e_msg_number] == msg) { request->req_next = *ptr; break; } }else BUGCHECK (167); /* msg 167 invalid SEND request */format = (FMT) message->nod_arg [e_msg_format];if (msg != (USHORT) message->nod_arg [e_msg_number]) ERR_post (gds__req_sync, 0);if (length != format->fmt_length) ERR_post (gds__port_len, gds_arg_number, (SLONG) length, gds_arg_number, (SLONG) format->fmt_length, 0);if ((U_IPTR) buffer & (ALIGNMENT - 1)) MOVE_FAST (buffer, (SCHAR*) request + message->nod_impure, length);else MOVE_FASTER (buffer, (SCHAR*) request + message->nod_impure, length);execute_looper (tdbb, request, transaction, req_proceed);#ifdef SCROLLABLE_CURSORSif (save_next) { /* if the message was sent asynchronously, restore all the previous values so that whatever we were trying to do when the message came in is what we do next */ request->req_operation = save_operation; request->req_message = save_message; request->req_next = save_next; } #endif}#ifdef GATEWAYvoid EXE_set_fields_null ( TDBB tdbb, REC record, FMT format){/************************************** * * E X E _ s e t _ f i e l d s _ n u l l * ************************************** * * Functional description * Initialize all fields in a record to missing. * **************************************/USHORT count;SET_TDBB (tdbb);DEV_BLKCHK (record, type_rec);DEV_BLKCHK (format, type_fmt);if ((count = format->fmt_count) <= 1) ((SSHORT*) record->rec_data) [0] = -1;else { ((SSHORT*) record->rec_data) [0] = ((SSHORT*) record->rec_data) [1] = -1; MOVE_FAST (record->rec_data, record->rec_data + (2 * sizeof (SSHORT)), (USHORT) ((count - 2) * sizeof (SSHORT))); }}#endifvoid EXE_start ( TDBB tdbb, REQ request, TRA transaction){/************************************** * * E X E _ s t a r t * ************************************** * * Functional description * Start an execution running. * **************************************/DBB dbb;SET_TDBB (tdbb);dbb = tdbb->tdbb_database;BLKCHK (request, type_req);BLKCHK (transaction, type_tra);if (request->req_flags & req_active) ERR_post (gds__req_sync, gds_arg_gds, gds__reqinuse, 0);if (transaction->tra_flags & TRA_prepared) ERR_post (gds__req_no_trans, 0);/* Post resources to transaction block. In particular, the interest locks on relations/indices are copied to the transaction, which is very important for (short-lived) dynamically compiled requests. This will provide transaction stability by preventing a relation from being dropped after it has been referenced from an active transaction. */TRA_post_resources (tdbb, transaction, request->req_resources);request->req_transaction = transaction;request->req_flags &= REQ_FLAGS_INIT_MASK;request->req_flags |= req_active;request->req_flags &= ~req_reserved;request->req_operation = req_evaluate;/* set up to count records affected by request */request->req_flags |= req_count_records;request->req_records_selected = 0;request->req_records_updated = 0;request->req_records_inserted = 0;request->req_records_deleted = 0;/* Store request start time for timestamp work */if (!request->req_timestamp) request->req_timestamp = time (NULL);if (request->req_invariants) { /* Set all invariants to not computed. */ NOD *ptr, *end; USHORT *invariant_flags; VLU impure; ptr = (NOD*) request->req_invariants->vec_object; end = ptr + request->req_invariants->vec_count; for (; ptr < end; ptr++) if (*ptr) { impure = (VLU) ((SCHAR*) request + (*ptr)->nod_impure); invariant_flags = (USHORT*) &impure->vlu_string; *invariant_flags = 0; } }/* Start a save point if not in middle of one */if (transaction && (transaction != dbb->dbb_sys_trans)) { VIO_start_save_point (tdbb, transaction); }#ifdef WIN_NTSTART_CHECK_FOR_EXCEPTIONS(NULL);#endif looper (tdbb, request, request->req_top_node);#ifdef WIN_NTEND_CHECK_FOR_EXCEPTIONS(NULL);#endif/* If any requested modify/delete/insert ops have completed, forget them */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); }}void EXE_unwind ( TDBB tdbb, REQ request){/************************************** * * E X E _ u n w i n d * ************************************** * * Functional description * Unwind a request, maybe active, maybe not. This is particlarly * simple since nothing really needs to be done. * **************************************/BLK *ptr, *end;struct plb *old_pool;REQ old_request;DEV_BLKCHK (request, type_req);SET_TDBB (tdbb);if (request->req_flags & req_active) { if (request->req_fors) { old_pool = tdbb->tdbb_default; tdbb->tdbb_default = request->req_pool; old_request = tdbb->tdbb_request; tdbb->tdbb_request = request; tdbb->tdbb_transaction = request->req_transaction; for (ptr = request->req_fors->vec_object, end = ptr + request->req_fors->vec_count; ptr < end; ptr++) if (*ptr) RSE_close (tdbb, *ptr); tdbb->tdbb_default = old_pool; tdbb->tdbb_request = old_request; } release_blobs (tdbb, request); }if (request->req_proc_sav_point && (request->req_flags & req_proc_fetch)) release_proc_save_points (request); request->req_flags &= ~(req_active | req_proc_fetch | req_reserved);request->req_flags |= req_abort | req_stall;request->req_timestamp = 0;#ifdef GATEWAY/* Unwind request from connected DBMS's point of view */FRGN_unwind (request);#endif}/* CVC: Moved to its own routine, originally in store(). */static void cleanup_rpb ( TDBB tdbb, RPB *rpb){/************************************** * * c l e a n u p _ r p b * ************************************** * * Functional description * Perform cleaning of rpb, zeroing unassigned fields and * the impure tail of varying fields that we don't want to carry * when the RLE algorithm is applied. * **************************************/ DSC *desc = 0; SSHORT n; USHORT length; REC record = rpb->rpb_record; FMT format = record->rec_format; register UCHAR *p; SET_TDBB (tdbb); /* Is it necessary? *//* Starting from the format, walk through its array of descriptors. If the descriptor has no address, its a computed field and we shouldn't try to fix it. Get a pointer to the actual data and see if that field is null by indexing into the null flags between the record header and the record data.*/ for (n = 0; n < format->fmt_count; n++) { desc = &format->fmt_desc [n]; if (!desc->dsc_address) continue; p = record->rec_data + (SLONG) desc->dsc_address; if (TEST_NULL (record, n)) { if (length = desc->dsc_length) do *p++ = 0; while (--length); } else if (desc->dsc_dtype == dtype_varying)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -