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

📄 par.c

📁 firebird源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
NOD	plan, access_type, relation_node, *arg;USHORT	node_type, count;SET_TDBB (tdbb);node_type = (USHORT) BLR_BYTE;                /* a join type indicates a cross of two or more streams */if (node_type == blr_join ||    node_type == blr_merge)    {                            count = (USHORT) BLR_BYTE;    plan = PAR_make_node (tdbb, count);    plan->nod_type = (NOD_T) (USHORT) blr_table [node_type];    for (arg = plan->nod_arg; count--;)	*arg++ = par_plan (tdbb, csb);    return plan;    }/* we have hit a stream; parse the context number and access type */if (node_type == blr_retrieve)    {    TEXT	name [32], *p;    SSHORT	stream, n;    SLONG	index_id, relation_id;    REL	relation;    plan = PAR_make_node (tdbb, e_retrieve_length);    plan->nod_type = (NOD_T) (USHORT) blr_table [node_type];            /* parse the relation name and context--the relation        itself is redundant except in the case of a view,       in which case the base relation (and alias) must be specified */    n = BLR_BYTE;    if (n != blr_relation && n != blr_relation2 &&        n != blr_rid && n != blr_rid2)        syntax_error (*csb, elements [RELATION]);                                                   /* don't have par_relation() parse the context, because       this would add a new context; while this is a reference to        an existing context */    relation_node = par_relation (tdbb, csb, n, FALSE);    plan->nod_arg [e_retrieve_relation] = relation_node;    relation = (REL) relation_node->nod_arg [e_rel_relation];    n = BLR_BYTE;    if (n >= (*csb)->csb_count)        error (*csb, gds__ctxnotdef, 0);    stream = (*csb)->csb_rpt [n].csb_stream;    relation_node->nod_arg [e_rel_stream] = (NOD) (SLONG) stream;    relation_node->nod_arg [e_rel_context] = (NOD) (SLONG) n;    /* Access plan types (sequential is default) */    node_type = (USHORT) BLR_BYTE;    if (node_type == blr_navigational)	{	SSHORT idx_status;        access_type = plan->nod_arg [e_retrieve_access_type] = PAR_make_node (tdbb, 3);	access_type->nod_type = nod_navigational;	/* pick up the index name and look up the appropriate ids */	par_name (csb, name);	/* CVC: We can't do that. Index names are identifiers.	for (p = name; *p; *p++)	    *p = UPPER (*p);	*/	index_id = MET_lookup_index_name (tdbb, name, &relation_id, &idx_status);        if (idx_status == MET_object_unknown ||	    idx_status == MET_object_inactive) 	    if (tdbb->tdbb_attachment->att_flags & ATT_gbak_attachment)		warning (*csb, gds__indexname, 		    gds_arg_string, ERR_cstring (name),		    gds_arg_string, relation->rel_name,		    0);  	    else		error (*csb, gds__indexname, 		    gds_arg_string, ERR_cstring (name),		    gds_arg_string, relation->rel_name,		    0);   	/* save both the relation id and the index id, since 	   the relation could be a base relation of a view;           save the index name also, for convenience */	access_type->nod_arg [0] = (NOD) relation_id;	access_type->nod_arg [1] = (NOD) index_id;	access_type->nod_arg [2] = (NOD) ALL_cstring (name);	}    else if (node_type == blr_indices)	{	SSHORT idx_status;	count = (USHORT) BLR_BYTE;        access_type = plan->nod_arg [e_retrieve_access_type] = PAR_make_node (tdbb, count * 3);	access_type->nod_type = nod_indices;	/* pick up the index names and look up the appropriate ids */        for (arg = access_type->nod_arg; count--;)	    {  	    par_name (csb, name);	    for (p = name; *p; *p++)	        *p = UPPER (*p);  	    index_id = MET_lookup_index_name (tdbb, name, &relation_id, &idx_status);	    if (idx_status == MET_object_unknown ||	        idx_status == MET_object_inactive) 	        if (tdbb->tdbb_attachment->att_flags & ATT_gbak_attachment)		    warning (*csb, gds__indexname, 			gds_arg_string, ERR_cstring (name),			gds_arg_string, relation->rel_name,			0);		else		    error (*csb, gds__indexname, 			gds_arg_string, ERR_cstring (name),			gds_arg_string, relation->rel_name,			0); 	    /* save both the relation id and the index id, since 	       the relation could be a base relation of a view;               save the index name also, for convenience */ 	    *arg++ = (NOD) relation_id; 	    *arg++ = (NOD) index_id;	    *arg++ = (NOD) ALL_cstring (name);	    }	}    else if (node_type != blr_sequential)	syntax_error (*csb, "access type");        return plan;    }syntax_error (*csb, "plan item");return ((NOD) 0);	/* Added to remove compiler warning */}static NOD par_procedure (    TDBB	tdbb,    CSB		*csb,    SSHORT	_operator){/************************************** * *	p a r _ p r o c e d u r e * ************************************** * * Functional description *	Parse an procedural view reference. * **************************************/NOD	node;PRC	procedure;USHORT	stream;SET_TDBB (tdbb);{TEXT	name [32];SSHORT	pid;if (_operator == blr_procedure)    {    par_name (csb, name);    procedure = MET_lookup_procedure (tdbb, name);    }else    {    pid = BLR_WORD;    if (!(procedure = MET_lookup_procedure_id (tdbb, pid, FALSE, 0)))	sprintf (name, "id %d", pid);    }if (!procedure)    error (*csb,	gds__prcnotdef, 	gds_arg_string, ERR_cstring (name), 	0);}node = PAR_make_node (tdbb, e_prc_length);node->nod_type = nod_procedure;node->nod_count = count_table [blr_procedure];node->nod_arg [e_prc_procedure] = (NOD) procedure;stream = par_context (csb, NULL_PTR);node->nod_arg [e_prc_stream] = (NOD) (SLONG) stream;(*csb)->csb_rpt [stream].csb_procedure = procedure;par_procedure_parms (tdbb, csb, procedure, &node->nod_arg [e_prc_in_msg],    &node->nod_arg [e_prc_inputs], TRUE);if ((*csb)->csb_g_flags & csb_get_dependencies)    par_dependency (tdbb, csb, stream, (SSHORT) -1, NULL_PTR);return node;}static void par_procedure_parms (    TDBB	tdbb,    CSB		*csb,    PRC		procedure,    NOD		*message_ptr,    NOD		*parameter_ptr,    USHORT	input_flag){/************************************** * *	p a r _ p r o c e d u r e _ p a r m s * ************************************** * * Functional description *	Parse some procedure parameters. * **************************************/NOD	message, list, *ptr, asgn, prm, prm_f;FMT	format;USHORT	count, n, i, asgn_arg1, asgn_arg2;struct csb_repeat	*tail;BOOLEAN	mismatch = FALSE;SET_TDBB (tdbb);count = BLR_WORD ;/** Check to see if the parameter count matches **/if (count != (input_flag ? procedure->prc_inputs : procedure->prc_outputs))    {    /** They don't match...Hmmm...Its OK if we were dropping the procedure **/    if (!(tdbb->tdbb_flags & TDBB_prc_being_dropped))        error (*csb,          gds__prcmismat,          gds_arg_string, ERR_cstring (procedure->prc_name->str_data),	  0);    else	mismatch = TRUE;    }if (count)    {    /** We have a few parameters. Get on with creating the message block **/    if ((n = ++(*csb)->csb_msg_number) < 2)	(*csb)->csb_msg_number = n = 2;    tail = CMP_csb_element (csb, n);    tail->csb_message = message = PAR_make_node (tdbb, e_msg_length);    message->nod_type = nod_message;    message->nod_count = count_table [blr_message];    *message_ptr = message;    message->nod_count = 0;    message->nod_arg [e_msg_number] = (NOD) (SLONG) n;    format = input_flag ? procedure->prc_input_fmt : procedure->prc_output_fmt;    message->nod_arg [e_msg_format] = (NOD) format;    if (!mismatch)        n = format->fmt_count / 2;    else 	/*  There was a parameter mismatch hence can't depend upon the format's	    fmt_count. Use count instead.	*/	n = count;    list = *parameter_ptr = PAR_make_node (tdbb, n);    list->nod_type = nod_list;    list->nod_count = n;    ptr = list->nod_arg;    if (input_flag)	{	asgn_arg1 = e_asgn_from;	asgn_arg2 = e_asgn_to;	}    else	{	asgn_arg1 = e_asgn_to;	asgn_arg2 = e_asgn_from;	}    for (i = 0; count; count--)	{	asgn = PAR_make_node (tdbb, e_asgn_length);	*ptr++ = asgn;	asgn->nod_type = nod_assignment;	asgn->nod_count = count_table [blr_assignment];	asgn->nod_arg [asgn_arg1] = parse (tdbb, csb, VALUE);	prm = asgn->nod_arg [asgn_arg2] = PAR_make_node (tdbb, e_arg_length);	prm->nod_type = nod_argument;	prm->nod_count = 1;	prm->nod_arg [e_arg_message] = message;	prm->nod_arg [e_arg_number] = (NOD) i++;	prm_f = prm->nod_arg [e_arg_flag] = PAR_make_node (tdbb, e_arg_length);	prm_f->nod_type = nod_argument;	prm_f->nod_count = 0;	prm_f->nod_arg [e_arg_message] = message;	prm_f->nod_arg [e_arg_number] = (NOD) i++;	}    }else if ((input_flag ? procedure->prc_inputs : procedure->prc_outputs) && 	!mismatch)    error (*csb,	gds__prcmismat,	gds_arg_string, ERR_cstring (procedure->prc_name->str_data),	0);}static NOD par_relation (    TDBB	tdbb,    CSB		*csb,    SSHORT 	_operator,    BOOLEAN	parse_context){/************************************** * *	p a r _ r e l a t i o n * ************************************** * * Functional description *	Parse a relation reference. * **************************************/#ifdef GATEWAYDBB	dbb;#endifNOD	node;REL	relation;TEXT	name[32];STR	alias_string = NULL;SSHORT	id, stream, length, context;        SET_TDBB (tdbb);#ifdef GATEWAYdbb = tdbb->tdbb_database;#endif/* Make a relation reference node */node = PAR_make_node (tdbb, e_rel_length);node->nod_count = 0;/* Find relation either by id or by name */if (_operator == blr_rid || _operator == blr_rid2)    {    id = BLR_WORD;    if (_operator == blr_rid2)	{	length = BLR_PEEK;	alias_string = (STR) ALLOCDV (type_str, length + 1);	alias_string->str_length = length;	par_name (csb, alias_string->str_data);	}#ifndef GATEWAY    if (!(relation = MET_lookup_relation_id (tdbb, id, FALSE)))	{	sprintf (name, "id %d", id);	error (*csb, gds__relnotdef, gds_arg_string, ERR_cstring (name), 0);	}#else    /* To use rid, the relation slot must already have been filled in */    if (id >= dbb->dbb_relations->vec_count || !dbb->dbb_relations->vec_object [id])	error (*csb, gds__ctxnotdef, 0);    relation = MET_relation (tdbb, id);#endif    }else if (_operator == blr_relation || _operator == blr_relation2)    {    par_name (csb, name);    if (_operator == blr_relation2)	{	length = BLR_PEEK;	alias_string = (STR) ALLOCDV (type_str, length + 1);	alias_string->str_length = length;	par_name (csb, alias_string->str_data);	}    if (!(relation = MET_lookup_relation (tdbb, name)))	error (*csb, gds__relnotdef, 		gds_arg_string, ERR_cstring (name), 		0);    }/* if an alias was passed, store with the relation */if (alias_string)    node->nod_arg [e_rel_alias] = (NOD) alias_string;/* Scan the relation if it hasn't already been scanned for meta data */if ((!(relation->rel_flags & REL_scanned) || (relation->rel_flags & REL_being_scanned)) &&    ((relation->rel_flags & REL_force_scan) || !((*csb)->csb_g_flags & csb_internal)))    {    relation->rel_flags &= ~REL_force_scan;    MET_scan_relation (tdbb, relation);    }else if (relation->rel_flags & REL_sys_triggers)    MET_parse_sys_trigger (tdbb, relation);/* generate a stream for the relation reference,    assuming it is a real reference */if (parse_context)    {    stream = par_context (csb, &context);    node->nod_arg [e_rel_stream] = (NOD) (SLONG) stream;    node->nod_arg [e_rel_context] = (NOD) (SLONG) context;    (*csb)->csb_rpt [stream].csb_relation = relation;    (*csb)->csb_rpt [stream].csb_alias = alias_string;    if ((*csb)->csb_g_flags & csb_get_dependencies)        par_dependency (tdbb, csb, stream, (SSHORT) -1, NULL_PTR);    }node->nod_arg [e_rel_relation] = (NOD) relation;return node;}static NOD par_rse (    TDBB	tdbb,    CSB		*csb,    SSHORT	rse_op){/************************************** * *	p a r _ r s e * ************************************** * * Functional description *	Parse a record selection expression. * **************************************/register RSE	rse;NOD		*ptr;register SSHORT	count;USHORT		jointype;UCHAR		op;SET_TDBB (tdbb);count = (unsigned int) BLR_BYTE;rse = (RSE) PAR_make_node (tdbb, count + rse_delta + 2);rse->nod_count = 0;rse->rse_count = count;ptr = rse->rse_relation;while (--count >= 0)    *ptr++ = parse (tdbb, csb, RELATION);while (TRUE)    switch (op = BLR_BYTE)	{	case blr_boolean:	    rse->rse_boolean = parse (tdbb, csb, BOOL);	    break;	case blr_first:	    if (rse_op == blr_rs_stream)		syntax_error (*csb, "rse stream clause");	    rse->rse_first = parse (tdbb, csb, VALUE);	    break;	case blr_skip:	    if (rse_op == blr_rs_stream)		syntax_error (*csb, "rse stream clause");	    rse->rse_skip = parse (tdbb, csb, VALUE);	    break;	case blr_sort:	    if (rse_op == blr_rs_stream)		syntax_error (*csb, "rse stream clause");	    rse->rse_sorted = par_sort (tdbb, csb, TRUE);	    break;	case blr_project:	    if (rse_op == blr_rs_stream)		syntax_error (*csb, "rse stream clause");	    rse->rse_projection = par_sort (tdbb, csb, FALSE);	    break;	case blr_join_type:	    if ((rse->rse_jointype = jointype = (USHORT) BLR_BYTE) != blr_inner &&		jointype != blr_left &&		jointype != blr_right &&		jointype != blr_full)		syntax_error (*csb, "join type clause");	    break;	case blr_plan:	    rse->rse_plan = par_plan (tdbb, csb);	    break;	#ifdef SCROLLABLE_CURSORS	/* if a receive is seen here, then it is intended to be an asynchronous            receive which can happen at any time during the scope of the rse--            this is intended to be a more efficient mechanism for scrolling through            a record stream, to prevent having to send a message to the engine 	   for each record */	case blr_receive:	    BLR_PUSH;	    rse->rse_async_message = parse (tdbb, csb, STATEMENT);	    break;#endif	default:	    if (op == (UCHAR) blr_end)		{		/* An outer join is only allowed when the stream count is 2		   and a boolean expression has been supplied */		if (!rse->rse_jointype ||		    (rse->rse_count == 2 && rse->rse_boolean))		    return (NOD) rse;		}	    syntax_error (*csb, (rse_op == blr_rs_stream) ?		"rse stream clause" : "record selection expression clause");	}}static NOD par_sort (    TDBB	tdbb,    CSB		*csb,    BOOLEAN	flag){/************************************** * *	p a r _ s o r t * ************************************** * * Functional description *	Parse a sort clause (sans header byte).  This is used for *	BLR_SORT, BLR_PROJECT, and BLR_GROUP. * **************************************/NOD	clause, *ptr, *ptr2;SSHORT	count;SET_TDBB (tdbb);

⌨️ 快捷键说明

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