⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsql.c

📁 firebird源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *     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, &parameter->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 + -