📄 dsql.c
字号:
* Dialect * 10 + parser_version * * and is extracted in dsql8_execute_immediate as follows: * parser_version = ((dialect *10)+parser_version)%10 * client_dialect = ((dialect *10)+parser_version)/10 * * For example, parser_version = 1 and client dialect = 1 * * combined = (1 * 10) + 1 == 11 * * parser = (combined) %10 == 1 * dialect = (combined) / 19 == 1 * * If the parser version is not part of the dialect, then assume that the * connection being made is a local classic connection. */if ((dialect / 10) == 0) parser_version = 2;else { parser_version = dialect % 10; dialect /= 10; }request->req_client_dialect = dialect;request = prepare (request, length, string, dialect, parser_version);execute_request (request, trans_handle, in_blr_length, in_blr, in_msg_length, in_msg, out_blr_length, out_blr, out_msg_length, out_msg, FALSE);release_request (request, TRUE);RETURN_SUCCESS;}STATUS DLL_EXPORT GDS_DSQL_FETCH ( STATUS *user_status, REQ *req_handle, USHORT blr_length, UCHAR *blr, USHORT msg_type, USHORT msg_length, UCHAR *msg#ifdef SCROLLABLE_CURSORS , USHORT direction, SLONG offset)#else )#endif{/************************************** * * d s q l _ f e t c h * ************************************** * * Functional description * Fetch next record from a dynamic SQL cursor * **************************************/REQ request;MSG message;PAR eof, parameter, null;STATUS s;USHORT *ret_length;UCHAR *buffer;struct tsql thd_context, *tdsql;JMP_BUF env;SET_THREAD_DATA;ERROR_INIT (env);init (NULL_PTR);request = *req_handle;tdsql->tsql_default = request->req_pool;/* if the cursor isn't open, we've got a problem */if (request->req_type == REQ_SELECT || request->req_type == REQ_SELECT_UPD || request->req_type == REQ_EMBED_SELECT || request->req_type == REQ_GET_SEGMENT) if (!(request->req_flags & REQ_cursor_open)) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -504, gds_arg_gds, gds__dsql_cursor_err, 0);#ifdef SCROLLABLE_CURSORS/* check whether we need to send an asynchronous scrolling message to the engine; the engine will automatically advance one record in the same direction as before, so optimize out messages of that type */if (request->req_type == REQ_SELECT && request->req_dbb->dbb_base_level >= 5) { switch (direction) { case isc_fetch_next: if (!(request->req_flags & REQ_backwards)) offset = 0; else { direction = blr_forward; offset = 1; request->req_flags &= ~REQ_backwards; } break; case isc_fetch_prior: if (request->req_flags & REQ_backwards) offset = 0; else { direction = blr_backward; offset = 1; request->req_flags |= REQ_backwards; } break; case isc_fetch_first: direction = blr_bof_forward; offset = 1; request->req_flags &= ~REQ_backwards; break; case isc_fetch_last: direction = blr_eof_backward; offset = 1; request->req_flags |= REQ_backwards; break; case isc_fetch_absolute: direction = blr_bof_forward; request->req_flags &= ~REQ_backwards; break; case isc_fetch_relative: if (offset < 0) { direction = blr_backward; offset = -offset; request->req_flags |= REQ_backwards; } else { direction = blr_forward; request->req_flags &= ~REQ_backwards; } break; default: ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -804, gds_arg_gds, gds__dsql_sqlda_err, 0); } if (offset) { PAR offset_parameter; DSC desc; message = (MSG) request->req_async; desc.dsc_dtype = dtype_short; desc.dsc_scale = 0; desc.dsc_length = sizeof (USHORT); desc.dsc_flags = 0; desc.dsc_address = (UCHAR*) &direction; offset_parameter = message->msg_parameters; parameter = offset_parameter->par_next; MOVD_move (&desc, ¶meter->par_desc); desc.dsc_dtype = dtype_long; desc.dsc_scale = 0; desc.dsc_length = sizeof (SLONG); desc.dsc_flags = 0; desc.dsc_address = (UCHAR*) &offset; MOVD_move (&desc, &offset_parameter->par_desc); THREAD_EXIT; s = isc_receive2 (GDS_VAL (tdsql->tsql_status), GDS_REF (request->req_handle), message->msg_number, message->msg_length, GDS_VAL (message->msg_buffer), 0, direction, offset); THREAD_ENTER; if (s) punt(); } }#endifmessage = (MSG) request->req_receive;/* Insure that the blr for the message is parsed, regardless of whether anything is found by the call to receive. */if (blr_length) parse_blr (blr_length, blr, msg_length, message->msg_parameters);if (request->req_type == REQ_GET_SEGMENT) { /* For get segment, use the user buffer and indicator directly. */ parameter = request->req_blob->blb_segment; null = parameter->par_null; ret_length = (USHORT*) (msg + (SLONG) null->par_user_desc.dsc_address); buffer = msg + (SLONG) parameter->par_user_desc.dsc_address; THREAD_EXIT; s = isc_get_segment (tdsql->tsql_status, GDS_REF (request->req_handle), GDS_VAL (ret_length), parameter->par_user_desc.dsc_length, GDS_VAL (buffer)); THREAD_ENTER; if (!s) { RESTORE_THREAD_DATA; return 0; } else if (s == gds__segment) { RESTORE_THREAD_DATA; return 101; } else if (s == gds__segstr_eof) { RESTORE_THREAD_DATA; return 100; } else punt(); }THREAD_EXIT;s = isc_receive (GDS_VAL (tdsql->tsql_status), GDS_REF (request->req_handle), message->msg_number, message->msg_length, GDS_VAL (message->msg_buffer), 0);THREAD_ENTER;if (s) punt();if (eof = request->req_eof) if (!*((USHORT*) eof->par_desc.dsc_address)) { RESTORE_THREAD_DATA; return 100; }map_in_out (NULL, message, 0, blr, msg_length, msg);RETURN_SUCCESS;}STATUS DLL_EXPORT GDS_DSQL_FREE ( STATUS *user_status, REQ *req_handle, USHORT option){/************************************** * * d s q l _ f r e e _ s t a t e m e n t * ************************************** * * Functional description * Release request for a dsql statement * **************************************/REQ request;struct tsql thd_context, *tdsql;JMP_BUF env;SET_THREAD_DATA;ERROR_INIT (env);init (NULL_PTR);request = *req_handle;tdsql->tsql_default = request->req_pool;if (option & DSQL_drop) { /* Release everything associate with the request.*/ release_request (request, TRUE); *req_handle = NULL; }else if (option & DSQL_close) { /* Just close the cursor associated with the request. */ if (!(request->req_flags & REQ_cursor_open)) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -501, gds_arg_gds, gds__dsql_cursor_close_err, 0); close_cursor (request); }RETURN_SUCCESS;}STATUS DLL_EXPORT GDS_DSQL_INSERT ( STATUS *user_status, REQ *req_handle, USHORT blr_length, UCHAR *blr, USHORT msg_type, USHORT msg_length, UCHAR *msg){/************************************** * * d s q l _ i n s e r t * ************************************** * * Functional description * Insert next record into a dynamic SQL cursor * **************************************/REQ request;MSG message;PAR parameter;SCHAR *buffer;STATUS s;struct tsql thd_context, *tdsql;JMP_BUF env;SET_THREAD_DATA;ERROR_INIT (env);init (NULL_PTR);request = *req_handle;tdsql->tsql_default = request->req_pool;/* if the cursor isn't open, we've got a problem */if (request->req_type == REQ_PUT_SEGMENT) if (!(request->req_flags & REQ_cursor_open)) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -504, gds_arg_gds, gds__dsql_cursor_err, 0);message = (MSG) request->req_receive;/* Insure that the blr for the message is parsed, regardless of whether anything is found by the call to receive. */if (blr_length) parse_blr (blr_length, blr, msg_length, message->msg_parameters);if (request->req_type == REQ_PUT_SEGMENT) { /* For put segment, use the user buffer and indicator directly. */ parameter = request->req_blob->blb_segment; buffer = msg + (SLONG) parameter->par_user_desc.dsc_address; THREAD_EXIT; s = isc_put_segment (tdsql->tsql_status, GDS_REF (request->req_handle), parameter->par_user_desc.dsc_length, GDS_VAL (buffer)); THREAD_ENTER; if (s) punt(); }RETURN_SUCCESS;}STATUS DLL_EXPORT GDS_DSQL_PREPARE ( STATUS *user_status, isc_tr_handle *trans_handle, REQ *req_handle, USHORT length, TEXT *string, USHORT dialect, USHORT item_length, UCHAR *items, USHORT buffer_length, UCHAR *buffer){/************************************** * * d s q l _ p r e p a r e * ************************************** * * Functional description * Prepare a statement for execution. * **************************************/REQ old_request, request;USHORT parser_version;DBB database;STATUS status;struct tsql thd_context, *tdsql;JMP_BUF env;SET_THREAD_DATA;ERROR_INIT (env);init (NULL_PTR);old_request = *req_handle;database = old_request->req_dbb;/* check to see if old request has an open cursor */if (old_request && (old_request->req_flags & REQ_cursor_open)) { ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -519, gds_arg_gds, gds__dsql_open_cursor_request, 0); }/* Allocate a new request block and then prepare the request. We want to keep the old request around, as is, until we know that we are able to prepare the new one. *//* It would be really *nice* to know *why* we want to keep the old request around -- 1994-October-27 David Schnepper */tdsql->tsql_default = ALLD_pool();request = (REQ) ALLOCD (type_req);request->req_dbb = database;request->req_pool = tdsql->tsql_default;request->req_trans = (int *) *trans_handle;if (SETJMP (tdsql->tsql_setjmp)) { status = error(); release_request (request, TRUE); RESTORE_THREAD_DATA; return status; }if (!length) length = strlen (string);/* Figure out which parser version to use *//* Since the API to GDS_DSQL_PREPARE is public and can not be changed, there needs to * be a way to send the parser version to DSQL so that the parser can compare the keyword * version to the parser version. To accomplish this, the parser version is combined with * the client dialect and sent across that way. In dsql8_prepare_statement, the parser version * and client dialect are separated and passed on to their final desintations. The information * is combined as follows: * Dialect * 10 + parser_version * * and is extracted in dsql8_prepare_statement as follows: * parser_version = ((dialect *10)+parser_version)%10 * client_dialect = ((dialect *10)+parser_version)/10 * * For example, parser_version = 1 and client dialect = 1 * * combined = (1 * 10) + 1 == 11 * * parser = (combined) %10 == 1 * dialect = (combined) / 19 == 1 * * If the parser version is not part of the dialect, then assume that the * connection being made is a local classic connection. */if ((dialect / 10) == 0) parser_version = 2;else { parser_version = dialect % 10; dialect /= 10; }request->req_client_dialect = dialect;request = prepare (request, length, string, dialect, parser_version);/* Can not prepare a CREATE DATABASE/SCHEMA statement */if ((request->req_type == REQ_DDL) && (request->req_ddl_node->nod_type == nod_def_database)) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -530, gds_arg_gds, gds__dsql_crdb_prepare_err, 0);request->req_flags |= REQ_prepared;/* Now that we know that the new request exists, zap the old one. */tdsql->tsql_default = old_request->req_pool;release_request (old_request, TRUE);tdsql->tsql_default = NULL;/* The request was sucessfully prepared, and the old request was * successfully zapped, so set the client's handle to the new request */*req_handle = request;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -