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

📄 gen.c

📁 firebird源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	}    }STUFF (blr_assignment);STUFF (blr_literal);STUFF (blr_short);STUFF (0);if (eos_flag)    STUFF_WORD (0);else     STUFF_WORD (1);STUFF (blr_parameter);STUFF (1);STUFF_WORD (2 * outputs);STUFF (blr_end);if (!eos_flag)    {    STUFF (blr_stall);    STUFF (blr_end);    }}static void gen_rse (    REQ		request,    NOD		rse){/************************************** * *	g e n _ r s e * ************************************** * * Functional description *	Generate a record selection expression. * **************************************/NOD	node, list, *ptr, *end;PAR	parameter;if (rse->nod_arg [e_rse_singleton] && !(request->req_dbb->dbb_flags & DBB_v3))    STUFF (blr_singular);STUFF (blr_rse);list = rse->nod_arg [e_rse_streams];/* Handle source streams */if (list->nod_type == nod_union)    {    STUFF (1);    gen_union (request, rse);    }else if (list->nod_type == nod_list)    {    STUFF (list->nod_count);    for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++)	{	node = *ptr;	if (node->nod_type == nod_relation ||	    node->nod_type == nod_aggregate ||	    node->nod_type == nod_join)	    GEN_expr (request, node);	}    }else    {    STUFF (1);    GEN_expr (request, list);    }if ((node = rse->nod_arg [e_rse_first]) != NULL)    {    STUFF (blr_first);    GEN_expr (request, node);    }if ((node = rse->nod_arg [e_rse_skip]) != NULL)    {    STUFF (blr_skip);    GEN_expr (request, node);    }if ((node = rse->nod_arg [e_rse_boolean]) != NULL)    {    STUFF (blr_boolean);    GEN_expr (request, node);    }if ((list = rse->nod_arg [e_rse_sort]) != NULL)    gen_sort (request, list);if ((list = rse->nod_arg [e_rse_reduced]) != NULL)    {    STUFF (blr_project);    STUFF (list->nod_count);    for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++)	GEN_expr (request, *ptr);    }/* if the user specified an access plan to use, add it here */if ((node = rse->nod_arg [e_rse_plan]) != NULL)    {    STUFF (blr_plan);    gen_plan (request, node);    }#ifdef SCROLLABLE_CURSORS/* generate a statement to be executed if the user scrolls    in a direction other than forward; a message is sent outside    the normal send/receive protocol to specify the direction    and offset to scroll; note that we do this only on a SELECT    type statement and only when talking to a 4.1 engine or greater */if (request->req_type == REQ_SELECT &&    request->req_dbb->dbb_base_level >= 5)    {    STUFF (blr_receive); STUFF (request->req_async->msg_number);        STUFF (blr_seek);            parameter = request->req_async->msg_parameters;	    gen_parameter (request, parameter->par_next);	    gen_parameter (request, parameter);    }#endifSTUFF (blr_end);}static void gen_select (    REQ		request,    NOD		rse){/************************************** * *	g e n _ s e l e c t * ************************************** * * Functional description *	Generate BLR for a SELECT statement. * **************************************/NOD	list, *ptr, *end, item, alias, map_node;PAR	parameter;MSG	message;FLD	field;DSC	constant_desc;DSQL_REL	relation;UDF	udf;CTX	context;STR	string;SSHORT	constant;MAP	map;constant_desc.dsc_dtype = dtype_short;constant_desc.dsc_scale = 0;constant_desc.dsc_sub_type = 0;constant_desc.dsc_flags = 0;constant_desc.dsc_length = sizeof (SSHORT);constant_desc.dsc_address = (UCHAR*) &constant;/* Set up parameter for things in the select list */list = rse->nod_arg [e_rse_items];for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++){    item = *ptr;    parameter = MAKE_parameter (request->req_receive, TRUE, TRUE);    parameter->par_node = item;    MAKE_desc (&parameter->par_desc, item);    if (item->nod_type == nod_field)	{		field = (FLD) item->nod_arg [e_fld_field];		parameter->par_name = parameter->par_alias = field->fld_name;		context = (CTX) item->nod_arg [e_fld_context];		if (context->ctx_relation)		{			parameter->par_rel_name = context->ctx_relation->rel_name;			parameter->par_owner_name = context->ctx_relation->rel_owner;		}		else if (context->ctx_procedure)		{			parameter->par_rel_name = context->ctx_procedure->prc_name;			parameter->par_owner_name = context->ctx_procedure->prc_owner;		}	}    else if (item->nod_type == nod_dbkey)	{		parameter->par_name = parameter->par_alias = db_key_name;		context = (CTX) item->nod_arg [0]->nod_arg [0];		parameter->par_rel_name = context->ctx_relation->rel_name;		parameter->par_owner_name = context->ctx_relation->rel_owner;	}    else if (item->nod_type == nod_alias)	{		string = (STR) item->nod_arg [e_alias_alias];		parameter->par_alias = (TEXT*) string->str_data;		alias = item->nod_arg [e_alias_value];		if (alias->nod_type == nod_field)		{			field = (FLD) alias->nod_arg [e_fld_field];			parameter->par_name = field->fld_name;			context = (CTX) alias->nod_arg [e_fld_context];			if (context->ctx_relation)			{				parameter->par_rel_name = context->ctx_relation->rel_name;				parameter->par_owner_name = context->ctx_relation->rel_owner;			}			else if (context->ctx_procedure)			{				parameter->par_rel_name = context->ctx_procedure->prc_name;				parameter->par_owner_name = context->ctx_procedure->prc_owner;			}		}		else if (alias->nod_type == nod_dbkey)		{			parameter->par_name = db_key_name;			context = (CTX) alias->nod_arg [0]->nod_arg[0];			parameter->par_rel_name = context->ctx_relation->rel_name;			parameter->par_owner_name = context->ctx_relation->rel_owner;		}	}    else if (item->nod_type == nod_map)	{	map = (MAP) item->nod_arg [e_map_map];	map_node = map->map_node;	while (map_node->nod_type == nod_map)	{		/* skip all the nod_map nodes */		map = (MAP) map_node->nod_arg [e_map_map];		map_node = map->map_node;	}	if (map_node->nod_type == nod_field)	{		field = (FLD) map_node->nod_arg [e_fld_field];		parameter->par_name = parameter->par_alias = field->fld_name;	}	else if (map_node->nod_type == nod_alias)	{		string = (STR) map_node->nod_arg [e_alias_alias];		parameter->par_alias = (TEXT*) string->str_data;		alias = map_node->nod_arg [e_alias_value];		if (alias->nod_type == nod_field)		{			field = (FLD) alias->nod_arg [e_fld_field];			parameter->par_name = field->fld_name;		}	}	else if (map_node->nod_type == nod_agg_count) 	    parameter->par_name = parameter->par_alias  = "COUNT";	else if (map_node->nod_type == nod_agg_total)	    parameter->par_name = parameter->par_alias  = "SUM";	else if (map_node->nod_type == nod_agg_average)	    parameter->par_name = parameter->par_alias  = "AVG";	else if (map_node->nod_type == nod_agg_total2)	    parameter->par_name = parameter->par_alias  = "SUM";	else if (map_node->nod_type == nod_agg_average2)	    parameter->par_name = parameter->par_alias  = "AVG";	else if (map_node->nod_type == nod_agg_min)	    parameter->par_name = parameter->par_alias  = "MIN";	else if (map_node->nod_type == nod_agg_max)	    parameter->par_name = parameter->par_alias  = "MAX";	}    else if (item->nod_type == nod_udf)	{		udf = (UDF) item->nod_arg [0];		parameter->par_name = parameter->par_alias = udf->udf_name;	}    else if (item->nod_type == nod_gen_id)		parameter->par_name = parameter->par_alias  = "GEN_ID";    else if (item->nod_type == nod_gen_id2)		parameter->par_name = parameter->par_alias  = "GEN_ID";    else if (item->nod_type == nod_user_name)		parameter->par_name = parameter->par_alias  = "USER";    else if (item->nod_type == nod_current_role)		parameter->par_name = parameter->par_alias  = "ROLE";    else if (item->nod_type == nod_substr)	{		/* CVC: SQL starts at 1 but C starts at zero. */		/*NOD node = item->nod_arg [e_substr_start];		--(*(SLONG *) (node->nod_desc.dsc_address));		FIXED IN PARSE.Y; here it doesn't catch expressions: Bug 450301. */		parameter->par_name = parameter->par_alias  = "SUBSTRING";	}	else if (item->nod_type == nod_cast)		parameter->par_name = parameter->par_alias	= "CAST";} /* for *//* Set up parameter to handle EOF */request->req_eof = parameter = MAKE_parameter (request->req_receive, FALSE, FALSE);parameter->par_desc.dsc_dtype = dtype_short;parameter->par_desc.dsc_scale = 0;parameter->par_desc.dsc_length = sizeof (SSHORT);/* Save DBKEYs for possible update later */list = rse->nod_arg [e_rse_streams];if (!rse->nod_arg [e_rse_reduced])    {    for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++)	if ((item = *ptr) && (item->nod_type == nod_relation))	    {	    context = (CTX) item->nod_arg [e_rel_context];	    if (relation = context->ctx_relation)		{		/* Set up dbkey */		parameter = MAKE_parameter (request->req_receive, FALSE, FALSE);		parameter->par_dbkey_ctx = context;		parameter->par_desc.dsc_dtype = dtype_text;		parameter->par_desc.dsc_ttype = ttype_binary;		parameter->par_desc.dsc_length = relation->rel_dbkey_length;		/* Set up record version - for post v33 databases */		if (!(request->req_dbb->dbb_flags & DBB_v3))		    {		    parameter = MAKE_parameter (request->req_receive, FALSE, FALSE);		    parameter->par_rec_version_ctx = context;		    parameter->par_desc.dsc_dtype = dtype_text;		    parameter->par_desc.dsc_ttype = ttype_binary;		    parameter->par_desc.dsc_length = relation->rel_dbkey_length/2;		    }		}	    }    }#ifdef SCROLLABLE_CURSORS/* define the parameters for the scrolling message--offset and direction,    in that order to make it easier to generate the request */if (request->req_type == REQ_SELECT &&    request->req_dbb->dbb_base_level >= 5)    {    parameter = MAKE_parameter (request->req_async, FALSE, FALSE);    parameter->par_desc.dsc_dtype = dtype_short;    parameter->par_desc.dsc_length = sizeof (USHORT);    parameter->par_desc.dsc_scale = 0;    parameter->par_desc.dsc_flags = 0;    parameter->par_desc.dsc_sub_type = 0;    parameter = MAKE_parameter (request->req_async, FALSE, FALSE);    parameter->par_desc.dsc_dtype = dtype_long;    parameter->par_desc.dsc_length = sizeof (ULONG);    parameter->par_desc.dsc_scale = 0;    parameter->par_desc.dsc_flags = 0;    parameter->par_desc.dsc_sub_type = 0;    }#endif/* Generate definitions for the messages */GEN_port (request, request->req_receive);message = request->req_send;if (message->msg_parameter)    GEN_port (request, message);else    request->req_send = NULL;#ifdef SCROLLABLE_CURSORSif (request->req_type == REQ_SELECT &&    request->req_dbb->dbb_base_level >= 5)    GEN_port (request, request->req_async);#endif/* If there is a send message, build a RECEIVE */if ((message = request->req_send) != NULL)    {    STUFF (blr_receive);    STUFF (message->msg_number);    }/* Generate FOR loop */message = request->req_receive;STUFF (blr_for);if (!(request->req_dbb->dbb_flags & DBB_v3))    STUFF (blr_stall);gen_rse (request, rse);STUFF (blr_send);STUFF (message->msg_number);STUFF (blr_begin);/* Build body of FOR loop */STUFF (blr_assignment);constant = 1;gen_constant (request, &constant_desc, USE_VALUE);gen_parameter (request, request->req_eof);for (parameter = message->msg_parameters; parameter; parameter = parameter->par_next)    {    if (parameter->par_node)	{	STUFF (blr_assignment);	GEN_expr (request, parameter->par_node);	gen_parameter (request, parameter);	}    if (context = parameter->par_dbkey_ctx)	{	STUFF (blr_assignment);	STUFF (blr_dbkey);	STUFF (context->ctx_context);	gen_parameter (request, parameter);	}    if (context = parameter->par_rec_version_ctx)	{	STUFF (blr_assignment);	STUFF (blr_record_version);	STUFF (context->ctx_context);	gen_parameter (request, parameter);	}    }STUFF (blr_end);STUFF (blr_send);STUFF (message->msg_number);STUFF (blr_assignment);constant = 0;gen_constant (request, &constant_desc, USE_VALUE);gen_parameter (request, request->req_eof);}static void gen_sort (    REQ		request,    NOD		list){/************************************** * *	g e n _ s o r t * ************************************** * * Functional description *	Generate a sort clause. * **************************************/NOD	*ptr, *end;STUFF (blr_sort);STUFF (list->nod_count);for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++)    {    if ((*ptr)->nod_arg [1])	STUFF (blr_descending);    else	STUFF (blr_ascending);    GEN_expr (request, (*ptr)->nod_arg [0]);    }}static void gen_table_lock (    REQ		request,    NOD		tbl_lock,    USHORT	lock_level){/************************************** * *	g e n _ t a b l e _ l o c k * ************************************** * * Functional description *	Generate tpb for table lock. *	If lock level is specified, it overrrides the transaction lock level. * **************************************/NOD     tbl_names, *ptr, *end;STR	temp;SSHORT	flags;USHORT	lock_mode;if ((!tbl_lock) || (tbl_lock->nod_type != nod_table_lock))    return;tbl_names = tbl_lock->nod_arg [e_lock_tables];flags = 0;if (tbl_lock->nod_arg [e_lock_mode])    flags = tbl_lock->nod_arg [e_lock_mode]->nod_flags;if (flags & NOD_PROTECTED)    lock_level = gds__tpb_protected;else if (flags & NOD_SHARED)    lock_level = gds__tpb_shared;lock_mode = (flags & NOD_WRITE) ? gds__tpb_lock_write : gds__tpb_lock_read;for (ptr = tbl_names->nod_arg, end = ptr + tbl_names->nod_count; 				ptr < end; ptr++)    {    if ((*ptr)->nod_type != nod_relation_name)	continue;    STUFF (lock_mode);    /* stuff table name */    temp = (STR) ((*ptr)->nod_arg [e_rln_name]);    stuff_cstring (request, temp->str_data);    STUFF (lock_level);    }}static void gen_udf (    REQ		request,    NOD		node){/************************************** * *	g e n _ u d f * ************************************** * * Functional description *	Generate a user defined function. * **************************************/UDF	udf;NOD	list, *ptr, *end;udf = (UDF) node->nod_arg [0];STUFF (blr_function);STUFF_CSTRING (udf->udf_name);if ((node->nod_count == 2) && (list = node->nod_arg [1]))    {    STUFF (list->nod_count);    for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++)	GEN_expr (request, *ptr);    }else    STUFF (0);}static void gen_union (    REQ		request,    NOD		union_node){/************************************** * *	g e n _ u n i o n * ************************************** * * Functional description *	Generate a union of substreams. * **************************************/NOD	sub_rse, *ptr, *end, streams;NOD	items, *iptr, *iend;USHORT	count;CTX     union_context;STUFF (blr_union);/* Obtain the context for UNION from the first MAP node   */items = union_node->nod_arg[e_rse_items];union_context = (CTX) items->nod_arg[0]->nod_arg[e_map_context];STUFF (union_context->ctx_context);streams = union_node->nod_arg [e_rse_streams];STUFF (streams->nod_count);     /* number of substreams */for (ptr = streams->nod_arg, end = ptr + streams->nod_count; ptr < end; ptr++)    {    sub_rse = *ptr;    gen_rse (request, sub_rse);    items = sub_rse->nod_arg [e_rse_items];    STUFF (blr_map);    STUFF_WORD (items->nod_count);    count = 0;    for (iptr = items->nod_arg, iend = iptr + items->nod_count; iptr < iend; iptr++)	{	STUFF_WORD (count);	GEN_expr (request, *iptr);	count++;	}    }}static void stuff_cstring (    REQ		request,    UCHAR	*string){/************************************** * *	s t u f f _ c s t r i n g * ************************************** * * Functional description *	Write out a string with one byte of length. * **************************************/UCHAR	c;STUFF (strlen (string));while ((c = *string++) != NULL)    STUFF (c);}static void stuff_word (    REQ		request,    USHORT	word){/************************************** * *	s t u f f _ w o r d * ************************************** * * Functional description *	Cram a word into the blr buffer.  If the buffer is getting *	ready to overflow, expand it. * **************************************/STUFF (word);STUFF (word >> 8);}

⌨️ 快捷键说明

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