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

📄 dsql.c

📁 firebird源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		1, &request->req_dbb->dbb_database_handle,		(int) (request->req_blr - request->req_blr_string->str_data),		request->req_blr_string->str_data);	THREAD_ENTER;	if (s)	    punt();	*trans_handle = request->req_trans;	return SUCCESS;    case REQ_COMMIT:	THREAD_EXIT;	s = isc_commit_transaction (tdsql->tsql_status,		&request->req_trans);	THREAD_ENTER;	if (s)	    punt();	*trans_handle = NULL;	return SUCCESS;    case REQ_COMMIT_RETAIN:	THREAD_EXIT;	s = isc_commit_retaining (tdsql->tsql_status,		&request->req_trans);	THREAD_ENTER;	if (s)	    punt();	return SUCCESS;    case REQ_ROLLBACK:	THREAD_EXIT;	s = isc_rollback_transaction (tdsql->tsql_status,		&request->req_trans);	THREAD_ENTER;	if (s)	    punt();	*trans_handle = NULL;	return SUCCESS;    case REQ_DDL:	DDL_execute (request);	return SUCCESS;    case REQ_GET_SEGMENT:	execute_blob (request, trans_handle,	    in_blr_length, in_blr, in_msg_length, in_msg,	    out_blr_length, out_blr, out_msg_length, out_msg);	return SUCCESS;    case REQ_PUT_SEGMENT:	execute_blob (request, trans_handle,	    in_blr_length, in_blr, in_msg_length, in_msg,	    out_blr_length, out_blr, out_msg_length, out_msg);	return SUCCESS;    case REQ_EXEC_PROCEDURE:	if (message = (MSG) request->req_send)	    {	    map_in_out (request, message, in_blr_length, in_blr,		in_msg_length, in_msg);	    in_msg_length = message->msg_length;	    in_msg = message->msg_buffer;	    }	else	    {	    in_msg_length = 0;	    in_msg = NULL;	    }	if (out_msg_length && (message = (MSG) request->req_receive))	    {	    if (out_blr_length)	        parse_blr (out_blr_length, out_blr, out_msg_length,		    message->msg_parameters);	    use_msg_length = message->msg_length;	    use_msg = message->msg_buffer;	    }	else	    {	    use_msg_length = 0;	    use_msg = NULL;	    }	THREAD_EXIT;	s = isc_transact_request (tdsql->tsql_status,		&request->req_dbb->dbb_database_handle,		&request->req_trans,		(USHORT) (request->req_blr - request->req_blr_string->str_data),		request->req_blr_string->str_data,		in_msg_length, in_msg,		use_msg_length, use_msg);	THREAD_ENTER;	if (s)	    punt();	if (out_msg_length && message)	    map_in_out (NULL, message, 0, out_blr, out_msg_length, out_msg);	return SUCCESS;    default:	/* Catch invalid request types */	assert (FALSE);	/* Fall into ... */    case REQ_SELECT:    case REQ_SELECT_UPD:    case REQ_INSERT:    case REQ_DELETE:    case REQ_UPDATE:    case REQ_UPDATE_CURSOR:    case REQ_DELETE_CURSOR:    case REQ_EMBED_SELECT:    case REQ_SET_GENERATOR:	break;    }/* If there is no data required, just start the request */if (!(message = (MSG) request->req_send))    {    THREAD_EXIT;    s = isc_start_request (tdsql->tsql_status,	    &request->req_handle,	    &request->req_trans,	    0);    THREAD_ENTER;    if (s)	punt();    }else    {    map_in_out (request, message, in_blr_length, in_blr, in_msg_length, in_msg);    THREAD_EXIT;    s = isc_start_and_send (tdsql->tsql_status,		&request->req_handle,		&request->req_trans,		message->msg_number,		message->msg_length,		message->msg_buffer,		0);    THREAD_ENTER;    if (s)	punt();    }if (out_msg_length && (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 (out_blr_length)        parse_blr (out_blr_length, out_blr, out_msg_length,		 message->msg_parameters);    THREAD_EXIT;    s = isc_receive (tdsql->tsql_status,	    &request->req_handle,	    message->msg_number,	    message->msg_length,	    message->msg_buffer,	    0);    THREAD_ENTER;    if (s)        punt();    map_in_out (NULL, message, 0, out_blr, out_msg_length, out_msg);    /* if this is a singleton select, make sure there's in fact one record */    if (singleton)	{	UCHAR	*message_buffer;	USHORT	counter;	/* Create a temp message buffer and try two more receives.	   If both succeed then the first is the next record and the	   second is either another record or the end of record message.	   In either case, there's more than one record. */	message_buffer = ALLD_malloc ((ULONG) message->msg_length);	s = 0;	THREAD_EXIT;	for (counter = 0; counter < 2 && !s; counter++)	    {	    s = isc_receive (local_status,			     &request->req_handle,			     message->msg_number,			     message->msg_length,			     message_buffer,			     0);	    }	THREAD_ENTER;	ALLD_free (message_buffer);	/* two successful receives means more than one record	   a req_sync error on the first pass above means no records	   a non-req_sync error on any of the passes above is an error */	if (!s)	    {	    tdsql->tsql_status[0] = gds_arg_gds;	    tdsql->tsql_status[1] = gds__sing_select_err;	    tdsql->tsql_status[2] = gds_arg_end;	    return_status = gds__sing_select_err;	    }	else if (s == gds__req_sync && counter == 1)	    {	    tdsql->tsql_status[0] = gds_arg_gds;	    tdsql->tsql_status[1] = gds__stream_eof;	    tdsql->tsql_status[2] = gds_arg_end;	    return_status = gds__stream_eof;	    }	else if (s != gds__req_sync)	    punt();	}    }if (!(request->req_dbb->dbb_flags & DBB_v3))    {    if (request->req_type == REQ_UPDATE_CURSOR)	{	GDS_DSQL_SQL_INFO (local_status, &request, sizeof (sql_records_info),	    sql_records_info, sizeof (buffer), buffer);	if (!request->req_updates)	    ERRD_post (isc_sqlerr, isc_arg_number, (SLONG) -913,		    isc_arg_gds, isc_deadlock,		    isc_arg_gds, isc_update_conflict,		    0);	}    else if (request->req_type == REQ_DELETE_CURSOR)	{	GDS_DSQL_SQL_INFO (local_status, &request, sizeof (sql_records_info),	    sql_records_info, sizeof (buffer), buffer);	if (!request->req_deletes)	    ERRD_post (isc_sqlerr, isc_arg_number, (SLONG) -913,		    isc_arg_gds, isc_deadlock,		    isc_arg_gds, isc_update_conflict,		    0);	}    }return return_status;}static SSHORT filter_sub_type (    REQ		request,    NOD		node){/************************************** * *	f i l t e r _ s u b _ t y p e * ************************************** * * Functional description *	Determine the sub_type to use in filtering *	a blob. * **************************************/PAR	parameter, null;if (node->nod_type == nod_constant)    return (SSHORT) node->nod_arg [0];parameter = (PAR) node->nod_arg [e_par_parameter];if (null = parameter->par_null)    if (*((SSHORT*) null->par_desc.dsc_address))	return 0;return *((SSHORT*) parameter->par_desc.dsc_address);}static BOOLEAN get_indices (    SSHORT	*explain_length_ptr,    SCHAR	**explain_ptr,    SSHORT	*plan_length_ptr,    SCHAR	**plan_ptr){/************************************** * *	g e t _ i n d i c e s * ************************************** * * Functional description *	Retrieve the indices from the index tree in *	the request info buffer, and print them out *	in the plan buffer. * **************************************/SCHAR 	*explain, *plan;SSHORT 	explain_length, plan_length;USHORT	length;explain_length = *explain_length_ptr;explain = *explain_ptr;plan_length = *plan_length_ptr;plan = *plan_ptr;/* go through the index tree information, just   extracting the indices used */explain_length--;switch (*explain++)    {    case gds__info_rsb_and:    case gds__info_rsb_or:	if (get_indices (&explain_length, &explain, &plan_length, &plan))	    return FAILURE;	if (get_indices (&explain_length, &explain, &plan_length, &plan))	    return FAILURE;        break;    case gds__info_rsb_dbkey:        break;    case gds__info_rsb_index:	explain_length--;	length = *explain++;	/* if this isn't the first index, put out a comma */	if (plan [-1] != '(' && plan [-1] != ' ')	    { 	    if (--plan_length < 0)	        return FAILURE;	    *plan++ = ',';	    }	/* now put out the index name */	if ((plan_length -= length) < 0)	    return FAILURE;	explain_length -= length;	while (length--)	    *plan++ = *explain++;        break;    default:        return FAILURE;    }*explain_length_ptr = explain_length;*explain_ptr = explain;*plan_length_ptr = plan_length;*plan_ptr = plan;return SUCCESS;}static USHORT get_plan_info (    REQ		request,    SSHORT	buffer_length,    SCHAR	**buffer){/************************************** * *	g e t _ p l a n _ i n f o * ************************************** * * Functional description *	Get the access plan for the request and turn *	it into a textual representation suitable for *	human reading. * **************************************/SCHAR 	explain_buffer [256], *explain, *plan, *explain_ptr, *buffer_ptr;SSHORT 	explain_length, i;USHORT	join_count, level;TSQL	tdsql;STATUS	s;tdsql = GET_THREAD_DATA;memset (explain_buffer, 0, sizeof (explain_buffer));explain_ptr = explain_buffer;buffer_ptr = *buffer;/* get the access path info for the underlying request from the engine */THREAD_EXIT;s = isc_request_info (	tdsql->tsql_status,	&request->req_handle,	0,	sizeof (explain_info),	explain_info,	sizeof (explain_buffer),	explain_buffer);THREAD_ENTER;if (s)    return 0;explain = explain_buffer;if (*explain == gds__info_truncated)    {    explain_ptr = (SCHAR*) gds__alloc (BUFFER_XLARGE);    THREAD_EXIT;    s = isc_request_info (	tdsql->tsql_status,	&request->req_handle,	0,	sizeof (explain_info),	explain_info,	BUFFER_XLARGE,	explain_ptr);    THREAD_ENTER;    if (s)        return 0;    }for (i = 0; i < 2; i++)    {    explain = explain_ptr;    if (*explain++ != gds__info_access_path)        return 0;    explain_length = (UCHAR) *explain++;    explain_length += (UCHAR) (*explain++) << 8;    plan = buffer_ptr;	/* CVC: What if we need to do 2nd pass? Those variables were only initialized	at the begining of the function hence they had trash the second time. */	join_count = level = 0;    /* keep going until we reach the end of the explain info */    while (explain_length > 0 && buffer_length > 0)        if (get_rsb_item (&explain_length, &explain, &buffer_length, &plan, &join_count, &level))	    {            /* assume we have run out of room in the buffer, try again with a larger one */            buffer_ptr = gds__alloc (BUFFER_XLARGE);	    buffer_length = BUFFER_XLARGE;	    break;	    }    if (buffer_ptr == *buffer)    	break;    }if (explain_ptr != explain_buffer)    gds__free (explain_ptr);*buffer = buffer_ptr;return plan - *buffer;}static USHORT get_request_info (    REQ		request,    SSHORT	buffer_length,    SCHAR	*buffer){/************************************** * *	g e t _ r e q u e s t _ i n f o * ************************************** * * Functional description *	Get the records updated/deleted for record * **************************************/SCHAR 	*data;UCHAR	p;TSQL	tdsql;STATUS	s;USHORT	data_length;tdsql = GET_THREAD_DATA;/* get the info for the request from the engine */THREAD_EXIT;s = isc_request_info (	tdsql->tsql_status,	&request->req_handle,	0,	sizeof (record_info),	record_info,	buffer_length,	buffer);THREAD_ENTER;if (s)    return 0;data = buffer;request->req_updates = request->req_deletes = 0;request->req_selects = request->req_inserts = 0;while ((p = *data++) != gds__info_end)    {    data_length =  gds__vax_integer (data, 2);    data += 2;    switch (p)	{	case gds__info_req_update_count:	    request->req_updates = gds__vax_integer (data, data_length);	    break;	case gds__info_req_delete_count:	    request->req_deletes = gds__vax_integer (data, data_length);	    break;	case gds__info_req_select_count:	    request->req_selects = gds__vax_integer (data, dat

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -