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

📄 pass1.c

📁 firebird源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {    return FALSE;    }invalid = FALSE;if (node->nod_type == nod_field)    {    FLD	field;    CTX	context;    NOD	reference;    if (!list)        return TRUE;    field = (FLD) node->nod_arg[e_fld_field];    context = (CTX) node->nod_arg[e_fld_context];    DEV_BLKCHK (field, type_fld);    DEV_BLKCHK (context, type_ctx);    for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++)	{	DEV_BLKCHK (*ptr, type_nod);	reference = *ptr;	if ((*ptr)->nod_type == nod_cast)	    {	    reference = (*ptr)->nod_arg[e_cast_source];	    }	DEV_BLKCHK (reference, type_nod);	if (reference->nod_type == nod_field &&	    field == (FLD) reference->nod_arg[e_fld_field] &&	    context == (CTX) reference->nod_arg[e_fld_context])	    return FALSE;	}    return TRUE;     }else if (node->nod_type == nod_dbkey)    {    CTX	context;    NOD	reference, rel_node;    if (!list)        return TRUE;    rel_node = (NOD) node->nod_arg [0];    context = (CTX) rel_node->nod_arg [0];    DEV_BLKCHK (context, type_ctx);    for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++)	{	DEV_BLKCHK (*ptr, type_nod);	reference = *ptr;	if ((*ptr)->nod_type == nod_cast)	    {	    reference = (*ptr)->nod_arg[e_cast_source];	    }	DEV_BLKCHK (reference, type_nod);	if (reference->nod_type == nod_dbkey &&	    rel_node == (NOD) reference->nod_arg [0] &&	    context == (CTX) rel_node->nod_arg [0])	    return FALSE;	}    return TRUE;     }else    {    if ((node->nod_type == nod_gen_id) || 	(node->nod_type == nod_gen_id2)    || 	(node->nod_type == nod_cast))	{	if (node->nod_count == 2)            invalid |= invalid_reference (node->nod_arg [1], list);	}	else if (node->nod_type == nod_udf) 	{		/* does this udf appear in list of group by  */		NOD reference;		STR udf_name1;		STR udf_name2;		if (!list)			return TRUE;		for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++) 		{			DEV_BLKCHK(*ptr, type_nod);			reference = *ptr;			if ((*ptr)->nod_type == nod_cast) 			{				reference = (*ptr)->nod_arg[e_cast_source];			}			DEV_BLKCHK(reference, type_nod);			if (reference->nod_type == nod_udf) 			{				udf_name1 = (STR)(node->nod_arg[0]);				udf_name2 = (STR)(reference->nod_arg[0]);				if ((udf_name1->str_length == udf_name2->str_length) &&					(strncmp(udf_name1->str_data, udf_name2->str_data,						udf_name1->str_length) == 0)) 				{					if (node->nod_count == 2) 					{						if (node_match (node, reference) == TRUE)						{							invalid = FALSE;						}						else						{							invalid = TRUE;						}						return invalid;					}					else return FALSE;				}			}		}		return TRUE;				}	#ifdef	CHECK_HAVING/******************************************************* taken out to fix a more serious bug*******************************************************/    else if (node->nod_type == nod_map)	{	MAP	map;	map = (MAP) node->nod_arg [e_map_map];	DEV_BLKCHK (map, type_map);	invalid |= invalid_reference (map->map_node, list);	}#endif    else	switch (node->nod_type)	    {	    default:		ASSERT_FAIL;		/* FALLINTO */	    case nod_add:	    case nod_concatenate:	    case nod_divide:	    case nod_multiply:	    case nod_negate:	    case nod_substr:	    case nod_subtract:	    case nod_upcase:	    case nod_extract:	    case nod_add2:	    case nod_divide2:	    case nod_multiply2:	    case nod_subtract2:	    case nod_eql:	    case nod_neq:	    case nod_gtr:	    case nod_geq:	    case nod_leq:	    case nod_lss:	    case nod_eql_any:	    case nod_neq_any:	    case nod_gtr_any:	    case nod_geq_any:	    case nod_leq_any:	    case nod_lss_any:	    case nod_eql_all:	    case nod_neq_all:	    case nod_gtr_all:	    case nod_geq_all:	    case nod_leq_all:	    case nod_lss_all:	    case nod_between:	    case nod_like:	    case nod_missing:	    case nod_and:	    case nod_or:	    case nod_any:	    case nod_ansi_any:	    case nod_ansi_all:	    case nod_not:	    case nod_unique:	    case nod_containing:	    case nod_starting:	    case nod_rse:	    case nod_list:	    case nod_via:		for (ptr = node->nod_arg, end = ptr + node->nod_count; ptr < end; ptr++)		    invalid |= invalid_reference (*ptr, list);		break;	    case nod_alias:		invalid |= invalid_reference (node->nod_arg [e_alias_value], list);		break;		/* An embedded aggregate, even of an expression, is OK */	    case nod_agg_average:	    case nod_agg_count:	    case nod_agg_max:	    case nod_agg_min:	    case nod_agg_total:	    case nod_agg_average2:	    case nod_agg_total2:		/* Fall into ... */		/* misc other stuff */	    case nod_aggregate:	    case nod_map:	    case nod_relation:	    case nod_variable:	    case nod_constant:	    case nod_null:	    case nod_current_date:	    case nod_current_time:	    case nod_current_timestamp:	    case nod_user_name:	    case nod_current_role:		return FALSE;	    }     }return invalid;}static void mark_ctx_outer_join (    NOD		node){/************************************** * *	m a r k _ c t x _ o u t e r _ j o i n  * ************************************** * * Functional description *	Mark the context blocks of relations in an RSE as *	participating in an Outer Join of some sort. *	This is important when we are deciding whether *	a particular field reference can be NULL or not. *	If the field is declared NOT NULL, it normally cannot *	be NULL - however, if the base relation reference is  *	within the "outside" part of an outer join rse, *	it CAN be null. * *	Our input RSE can be either a relation (table, view, or proc)  *	reference or a JOIN expression. *	 **************************************/CTX	context;DEV_BLKCHK (node, type_nod);switch (node->nod_type)    {    case nod_relation:	context = (CTX) node->nod_arg [e_rel_context];	DEV_BLKCHK (context, type_ctx);	assert (context);	context->ctx_flags |= CTX_outer_join;	break;    case nod_join:	mark_ctx_outer_join (node->nod_arg [e_join_left_rel]);	mark_ctx_outer_join (node->nod_arg [e_join_rght_rel]);	break;    default:	ASSERT_FAIL;		        /* only join & relation expected */	break;    }}static BOOLEAN node_match (    NOD		node1,    NOD		node2){/************************************** * *	n o d e _ m a t c h * ************************************** * * Functional description *	Compare two nodes for equality of value. * **************************************/NOD	*ptr1, *ptr2, *end;MAP	map1, map2;USHORT	l;UCHAR	*p1, *p2;DEV_BLKCHK (node1, type_nod);DEV_BLKCHK (node2, type_nod);if ((!node1) && (!node2))    return TRUE;if ((!node1) || (!node2) || (node1->nod_type != node2->nod_type)    || (node1->nod_count != node2->nod_count))    return FALSE;/* This is to get rid of assertion failures when trying   to node_match nod_aggregate's children. This was happening because not   all of the chilren are of type "struct nod". Pointer to the first child   (argument) is actually a pointer to context structure.   To compare two nodes of type nod_aggregate we need first to see if they   both refer to same context structure. If they do not they are different   nodes, if they point to the same context they are the same (because   nod_aggregate is created for an rse that have aggregate expression,    group by or having clause and each rse has its own context). But just in   case we compare two other subtrees.*/if (node1->nod_type == nod_aggregate)   if (node1->nod_arg[e_agg_context] != node2->nod_arg[e_agg_context])	return FALSE;   else	return (node_match (node1->nod_arg[e_agg_group],			    node2->nod_arg[e_agg_group]) &&		node_match (node1->nod_arg[e_agg_rse],			    node2->nod_arg[e_agg_rse]));if (node1->nod_type == nod_alias)    return node_match (node1->nod_arg [e_alias_value], node2);if (node2->nod_type == nod_alias)    return node_match (node1, node2->nod_arg [e_alias_value]);if (node1->nod_type == nod_field)    {    if (node1->nod_arg [e_fld_field] != node2->nod_arg [e_fld_field] ||	node1->nod_arg [e_fld_context] != node2->nod_arg [e_fld_context])	return FALSE;    if (node1->nod_arg [e_fld_indices] || node2->nod_arg [e_fld_indices])	return node_match (node1->nod_arg [e_fld_indices],			   node2->nod_arg [e_fld_indices]);    return TRUE;    }if (node1->nod_type == nod_constant)    {    if (node1->nod_desc.dsc_dtype != node2->nod_desc.dsc_dtype ||	node1->nod_desc.dsc_length != node2->nod_desc.dsc_length ||	node1->nod_desc.dsc_scale != node2->nod_desc.dsc_scale)	return FALSE;    p1 = node1->nod_desc.dsc_address;    p2 = node2->nod_desc.dsc_address;    for (l = node1->nod_desc.dsc_length; l > 0; l--)	if (*p1++ != *p2++)	    return FALSE;    return TRUE;    }if (node1->nod_type == nod_map)    {    map1 = (MAP) node1->nod_arg [e_map_map];    map2 = (MAP) node2->nod_arg [e_map_map];    DEV_BLKCHK (map1, type_map);    DEV_BLKCHK (map2, type_map);    return node_match (map1->map_node, map2->map_node);    }if ((node1->nod_type == nod_gen_id) ||    (node1->nod_type == nod_gen_id2)    ||     (node1->nod_type == nod_udf)    ||    (node1->nod_type == nod_cast))    {    if (node1->nod_arg [0] != node2->nod_arg [0])        return FALSE;    if (node1->nod_count == 2)        return node_match (node1->nod_arg [1], node2->nod_arg [1]);    else	return TRUE;    }if ((node1->nod_type == nod_agg_count) || (node1->nod_type == nod_agg_total)    || (node1->nod_type == nod_agg_total2)    || (node1->nod_type == nod_agg_average2)    || (node1->nod_type == nod_agg_average))    {    if ((node1->nod_flags & NOD_AGG_DISTINCT) != (node2->nod_flags & NOD_AGG_DISTINCT))        return FALSE;    }if (node1->nod_type == nod_variable)    {    VAR var1, var2;    if (node1->nod_type != node2->nod_type)	return FALSE;    var1 = node1->nod_arg [e_var_variable];    var2 = node2->nod_arg [e_var_variable];    DEV_BLKCHK (var1, type_var);    DEV_BLKCHK (var2, type_var);    if ( (strcmp (var1->var_name, var2->var_name)) ||	 (var1->var_field != var2->var_field)      ||	 (var1->var_variable_number != var2->var_variable_number) ||	 (var1->var_msg_item != var2->var_msg_item) ||	 (var1->var_msg_number != var2->var_msg_number) )	 return FALSE;    return TRUE;    }ptr1 = node1->nod_arg;ptr2 = node2->nod_arg;for (end = ptr1 + node1->nod_count; ptr1 < end; ptr1++, ptr2++)    if (!node_match (*ptr1, *ptr2))	return FALSE;return TRUE;}static NOD pass1_any (    REQ		request,    NOD		input,    NOD_TYPE	ntype){/************************************** * *	p a s s 1 _ a n y * ************************************** * * Functional description *	Compile a parsed request into something more interesting. * **************************************/NOD	node, temp, rse, select;LLS	base;DEV_BLKCHK (request, type_req);DEV_BLKCHK (input, type_nod);select = input->nod_arg [1];base = request->req_context;temp = MAKE_node (input->nod_type, 2);temp->nod_arg [0] = PASS1_node (request, input->nod_arg [0], 0);node = MAKE_node (ntype, 1);node->nod_arg [0] = rse = PASS1_rse (request, select, NULL);/* adjust the scope level back to the sub-rse, so that    the fields in the select list will be properly recognized */request->req_scope_level++;request->req_in_select_list++;temp->nod_arg [1] = PASS1_node (request, select->nod_arg [e_sel_list]->nod_arg[0], 0);request->req_in_select_list--;request->req_scope_level--;rse->nod_arg [e_rse_boolean] =	compose (rse->nod_arg [e_rse_boolean], temp, nod_and);while (request->req_context != base)    LLS_POP (&request->req_context);return node;}static void pass1_blob (    REQ		request,    NOD		input){/************************************** * *	p a s s 1 _ b l o b * ************************************** * * Functional description *	Process a blob get or put segment. * **************************************/NOD	field, list;BLB	blob;PAR	parameter;TSQL	tdsql;USHORT	fcount;

⌨️ 快捷键说明

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