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

📄 parse_oper.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
	return (ncandidates == 1) ? candidates->args : NULL;}	/* oper_select_candidate() *//* oper_exact() * Given operator, and arguments, return oper struct. * Inputs: * arg1, arg2: Type IDs */Operatoroper_exact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarnings){	HeapTuple	tup;	Node	   *tree;	/* Unspecified type for one of the arguments? then use the other */	if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))		arg1 = arg2;	else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))		arg2 = arg1;	tup = SearchSysCacheTuple(OPRNAME,							  PointerGetDatum(op),							  ObjectIdGetDatum(arg1),							  ObjectIdGetDatum(arg2),							  CharGetDatum('b'));	/*	 * Did not find anything? then try flipping arguments on a commutative	 * operator...	 */	if (!HeapTupleIsValid(tup) && (arg1 != arg2))	{		tup = SearchSysCacheTuple(OPRNAME,								  PointerGetDatum(op),								  ObjectIdGetDatum(arg2),								  ObjectIdGetDatum(arg1),								  CharGetDatum('b'));		if (HeapTupleIsValid(tup))		{			Form_pg_operator opform;			opform = (Form_pg_operator) GETSTRUCT(tup);			if (opform->oprcom == tup->t_data->t_oid)			{				if ((ltree != NULL) && (rtree != NULL))				{					tree = *ltree;					*ltree = *rtree;					*rtree = tree;				}			}			/* disable for now... - thomas 1998-05-14 */			else				tup = NULL;		}		if (!HeapTupleIsValid(tup) && (!noWarnings))			op_error(op, arg1, arg2);	}	return tup;}	/* oper_exact() *//* oper_inexact() * Given operator, types of arg1, and arg2, return oper struct. * Inputs: * arg1, arg2: Type IDs */Operatoroper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarnings){	HeapTuple	tup;	CandidateList candidates;	int			ncandidates;	Oid		   *targetOids;	Oid			inputOids[2];	/* Unspecified type for one of the arguments? then use the other */	if (arg2 == InvalidOid)		arg2 = arg1;	if (arg1 == InvalidOid)		arg1 = arg2;	ncandidates = binary_oper_get_candidates(op, arg1, arg2, &candidates);	/* No operators found? Then throw error or return null... */	if (ncandidates == 0)	{		if (!noWarnings)			op_error(op, arg1, arg2);		return NULL;	}	/* Or found exactly one? Then proceed... */	else if (ncandidates == 1)	{		tup = SearchSysCacheTuple(OPRNAME,								  PointerGetDatum(op),								  ObjectIdGetDatum(candidates->args[0]),								  ObjectIdGetDatum(candidates->args[1]),								  CharGetDatum('b'));		Assert(HeapTupleIsValid(tup));	}	/* Otherwise, multiple operators of the desired types found... */	else	{		inputOids[0] = arg1;		inputOids[1] = arg2;		targetOids = oper_select_candidate(2, inputOids, candidates);		if (targetOids != NULL)		{			tup = SearchSysCacheTuple(OPRNAME,									  PointerGetDatum(op),									  ObjectIdGetDatum(targetOids[0]),									  ObjectIdGetDatum(targetOids[1]),									  CharGetDatum('b'));		}		else			tup = NULL;		/* Could not choose one, for whatever reason... */		if (!HeapTupleIsValid(tup))		{			if (!noWarnings)			{				elog(ERROR, "Unable to identify an operator '%s' for types '%s' and '%s'"					 "\n\tYou will have to retype this query using an explicit cast",					 op, typeTypeName(typeidType(arg1)), typeTypeName(typeidType(arg2)));			}			return NULL;		}	}	return (Operator) tup;}	/* oper_inexact() *//* oper() * Given operator, types of arg1, and arg2, return oper struct. * Inputs: * arg1, arg2: Type IDs */Operatoroper(char *opname, Oid ltypeId, Oid rtypeId, bool noWarnings){	HeapTuple	tup;	/* check for exact match on this operator... */	if (HeapTupleIsValid(tup = oper_exact(opname, ltypeId, rtypeId, NULL, NULL, TRUE)))	{	}	/* try to find a match on likely candidates... */	else if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId, NULL, NULL, TRUE)))	{	}	else if (!noWarnings)	{		elog(ERROR, "Unable to identify a binary operator '%s' for types %s and %s",			 opname, typeTypeName(typeidType(ltypeId)), typeTypeName(typeidType(rtypeId)));	}	return (Operator) tup;}	/* oper() *//* unary_oper_get_candidates() *	given opname and typeId, find all possible types for which *	a right/left unary operator named opname exists, *	such that typeId can be coerced to it */static intunary_oper_get_candidates(char *op,						  Oid typeId,						  CandidateList *candidates,						  char rightleft){	CandidateList current_candidate;	Relation	pg_operator_desc;	HeapScanDesc pg_operator_scan;	HeapTuple	tup;	Form_pg_operator oper;	int			ncandidates = 0;	static ScanKeyData opKey[2] = {		{0, Anum_pg_operator_oprname, F_NAMEEQ},	{0, Anum_pg_operator_oprkind, F_CHAREQ}};	*candidates = NULL;	fmgr_info(F_NAMEEQ, (FmgrInfo *) &opKey[0].sk_func);	opKey[0].sk_argument = NameGetDatum(op);	fmgr_info(F_CHAREQ, (FmgrInfo *) &opKey[1].sk_func);	opKey[1].sk_argument = CharGetDatum(rightleft);	pg_operator_desc = heap_openr(OperatorRelationName);	pg_operator_scan = heap_beginscan(pg_operator_desc,									  0,									  SnapshotSelf,		/* ??? */									  2,									  opKey);	while (HeapTupleIsValid(tup = heap_getnext(pg_operator_scan, 0)))	{		current_candidate = (CandidateList) palloc(sizeof(struct _CandidateList));		current_candidate->args = (Oid *) palloc(sizeof(Oid));		oper = (Form_pg_operator) GETSTRUCT(tup);		if (rightleft == 'r')			current_candidate->args[0] = oper->oprleft;		else			current_candidate->args[0] = oper->oprright;		current_candidate->next = *candidates;		*candidates = current_candidate;		ncandidates++;	}	heap_endscan(pg_operator_scan);	heap_close(pg_operator_desc);	return ncandidates;}	/* unary_oper_get_candidates() *//* Given unary right-side operator (operator on right), return oper struct *//* arg-- type id */Operatorright_oper(char *op, Oid arg){	HeapTuple	tup;	CandidateList candidates;	int			ncandidates;	Oid		   *targetOid;	tup = SearchSysCacheTuple(OPRNAME,							  PointerGetDatum(op),							  ObjectIdGetDatum(arg),							  ObjectIdGetDatum(InvalidOid),							  CharGetDatum('r'));	if (!HeapTupleIsValid(tup))	{		ncandidates = unary_oper_get_candidates(op, arg, &candidates, 'r');		if (ncandidates == 0)		{			elog(ERROR, "Can't find right op '%s' for type %u", op, arg);			return NULL;		}		else if (ncandidates == 1)		{			tup = SearchSysCacheTuple(OPRNAME,									  PointerGetDatum(op),								   ObjectIdGetDatum(candidates->args[0]),									  ObjectIdGetDatum(InvalidOid),									  CharGetDatum('r'));			Assert(HeapTupleIsValid(tup));		}		else		{			targetOid = oper_select_candidate(1, &arg, candidates);			if (targetOid != NULL)			{				tup = SearchSysCacheTuple(OPRNAME,										  PointerGetDatum(op),										  ObjectIdGetDatum(InvalidOid),										  ObjectIdGetDatum(*targetOid),										  CharGetDatum('r'));			}			else				tup = NULL;			if (!HeapTupleIsValid(tup))			{				elog(ERROR, "Unable to convert right operator '%s' from type '%s'",					 op, typeidTypeName(arg));				return NULL;			}		}	}	return (Operator) tup;}	/* right_oper() *//* Given unary left-side operator (operator on left), return oper struct *//* arg--type id */Operatorleft_oper(char *op, Oid arg){	HeapTuple	tup;	CandidateList candidates;	int			ncandidates;	Oid		   *targetOid;	tup = SearchSysCacheTuple(OPRNAME,							  PointerGetDatum(op),							  ObjectIdGetDatum(InvalidOid),							  ObjectIdGetDatum(arg),							  CharGetDatum('l'));	if (!HeapTupleIsValid(tup))	{		ncandidates = unary_oper_get_candidates(op, arg, &candidates, 'l');		if (ncandidates == 0)		{			elog(ERROR, "Can't find left op '%s' for type %u", op, arg);			return NULL;		}		else if (ncandidates == 1)		{			tup = SearchSysCacheTuple(OPRNAME,									  PointerGetDatum(op),									  ObjectIdGetDatum(InvalidOid),								   ObjectIdGetDatum(candidates->args[0]),									  CharGetDatum('l'));			Assert(HeapTupleIsValid(tup));		}		else		{			targetOid = oper_select_candidate(1, &arg, candidates);			if (targetOid != NULL)			{				tup = SearchSysCacheTuple(OPRNAME,										  PointerGetDatum(op),										  ObjectIdGetDatum(InvalidOid),										  ObjectIdGetDatum(*targetOid),										  CharGetDatum('l'));			}			else				tup = NULL;			if (!HeapTupleIsValid(tup))			{				elog(ERROR, "Unable to convert left operator '%s' from type '%s'",					 op, typeidTypeName(arg));				return NULL;			}		}	}	return (Operator) tup;}	/* left_oper() *//* op_error() * Give a somewhat useful error message when the operator for two types * is not found. */static voidop_error(char *op, Oid arg1, Oid arg2){	Type		tp1 = NULL,				tp2 = NULL;	if (typeidIsValid(arg1))		tp1 = typeidType(arg1);	else	{		elog(ERROR, "Left hand side of operator '%s' has an unknown type"			 "\n\tProbably a bad attribute name", op);	}	if (typeidIsValid(arg2))		tp2 = typeidType(arg2);	else	{		elog(ERROR, "Right hand side of operator %s has an unknown type"			 "\n\tProbably a bad attribute name", op);	}	elog(ERROR, "There is no operator '%s' for types '%s' and '%s'"		 "\n\tYou will either have to retype this query using an explicit cast,"	 "\n\tor you will have to define the operator using CREATE OPERATOR",		 op, typeTypeName(tp1), typeTypeName(tp2));}

⌨️ 快捷键说明

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