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

📄 namespace.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* deconstruct the name list */	DeconstructQualifiedName(names, &schemaname, &funcname);	if (schemaname)	{		/* use exact schema given */		namespaceId = LookupExplicitNamespace(schemaname);	}	else	{		/* flag to indicate we need namespace search */		namespaceId = InvalidOid;		recomputeNamespacePath();	}	/* Search syscache by name only */	catlist = SearchSysCacheList(PROCNAMEARGSNSP, 1,								 CStringGetDatum(funcname),								 0, 0, 0);	for (i = 0; i < catlist->n_members; i++)	{		HeapTuple	proctup = &catlist->members[i]->tuple;		Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);		int			pronargs = procform->pronargs;		int			pathpos = 0;		FuncCandidateList newResult;		/* Ignore if it doesn't match requested argument count */		if (nargs >= 0 && pronargs != nargs)			continue;		if (OidIsValid(namespaceId))		{			/* Consider only procs in specified namespace */			if (procform->pronamespace != namespaceId)				continue;			/* No need to check args, they must all be different */		}		else		{			/* Consider only procs that are in the search path */			ListCell   *nsp;			foreach(nsp, namespaceSearchPath)			{				if (procform->pronamespace == lfirst_oid(nsp))					break;				pathpos++;			}			if (nsp == NULL)				continue;		/* proc is not in search path */			/*			 * Okay, it's in the search path, but does it have the same			 * arguments as something we already accepted?	If so, keep only			 * the one that appears earlier in the search path.			 *			 * If we have an ordered list from SearchSysCacheList (the normal			 * case), then any conflicting proc must immediately adjoin this			 * one in the list, so we only need to look at the newest result			 * item.  If we have an unordered list, we have to scan the whole			 * result list.			 */			if (resultList)			{				FuncCandidateList prevResult;				if (catlist->ordered)				{					if (pronargs == resultList->nargs &&						memcmp(procform->proargtypes.values,							   resultList->args,							   pronargs * sizeof(Oid)) == 0)						prevResult = resultList;					else						prevResult = NULL;				}				else				{					for (prevResult = resultList;						 prevResult;						 prevResult = prevResult->next)					{						if (pronargs == prevResult->nargs &&							memcmp(procform->proargtypes.values,								   prevResult->args,								   pronargs * sizeof(Oid)) == 0)							break;					}				}				if (prevResult)				{					/* We have a match with a previous result */					Assert(pathpos != prevResult->pathpos);					if (pathpos > prevResult->pathpos)						continue;		/* keep previous result */					/* replace previous result */					prevResult->pathpos = pathpos;					prevResult->oid = HeapTupleGetOid(proctup);					continue;	/* args are same, of course */				}			}		}		/*		 * Okay to add it to result list		 */		newResult = (FuncCandidateList)			palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)				   + pronargs * sizeof(Oid));		newResult->pathpos = pathpos;		newResult->oid = HeapTupleGetOid(proctup);		newResult->nargs = pronargs;		memcpy(newResult->args, procform->proargtypes.values,			   pronargs * sizeof(Oid));		newResult->next = resultList;		resultList = newResult;	}	ReleaseSysCacheList(catlist);	return resultList;}/* * FunctionIsVisible *		Determine whether a function (identified by OID) is visible in the *		current search path.  Visible means "would be found by searching *		for the unqualified function name with exact argument matches". */boolFunctionIsVisible(Oid funcid){	HeapTuple	proctup;	Form_pg_proc procform;	Oid			pronamespace;	bool		visible;	proctup = SearchSysCache(PROCOID,							 ObjectIdGetDatum(funcid),							 0, 0, 0);	if (!HeapTupleIsValid(proctup))		elog(ERROR, "cache lookup failed for function %u", funcid);	procform = (Form_pg_proc) GETSTRUCT(proctup);	recomputeNamespacePath();	/*	 * Quick check: if it ain't in the path at all, it ain't visible. Items in	 * the system namespace are surely in the path and so we needn't even do	 * list_member_oid() for them.	 */	pronamespace = procform->pronamespace;	if (pronamespace != PG_CATALOG_NAMESPACE &&		!list_member_oid(namespaceSearchPath, pronamespace))		visible = false;	else	{		/*		 * If it is in the path, it might still not be visible; it could be		 * hidden by another proc of the same name and arguments earlier in		 * the path.  So we must do a slow check to see if this is the same		 * proc that would be found by FuncnameGetCandidates.		 */		char	   *proname = NameStr(procform->proname);		int			nargs = procform->pronargs;		FuncCandidateList clist;		visible = false;		clist = FuncnameGetCandidates(list_make1(makeString(proname)), nargs);		for (; clist; clist = clist->next)		{			if (memcmp(clist->args, procform->proargtypes.values,					   nargs * sizeof(Oid)) == 0)			{				/* Found the expected entry; is it the right proc? */				visible = (clist->oid == funcid);				break;			}		}	}	ReleaseSysCache(proctup);	return visible;}/* * OpernameGetCandidates *		Given a possibly-qualified operator name and operator kind, *		retrieve a list of the possible matches. * * If oprkind is '\0', we return all operators matching the given name, * regardless of arguments. * * We search a single namespace if the operator name is qualified, else * all namespaces in the search path.  The return list will never contain * multiple entries with identical argument lists --- in the multiple- * namespace case, we arrange for entries in earlier namespaces to mask * identical entries in later namespaces. * * The returned items always have two args[] entries --- one or the other * will be InvalidOid for a prefix or postfix oprkind.	nargs is 2, too. */FuncCandidateListOpernameGetCandidates(List *names, char oprkind){	FuncCandidateList resultList = NULL;	char	   *resultSpace = NULL;	int			nextResult = 0;	char	   *schemaname;	char	   *opername;	Oid			namespaceId;	CatCList   *catlist;	int			i;	/* deconstruct the name list */	DeconstructQualifiedName(names, &schemaname, &opername);	if (schemaname)	{		/* use exact schema given */		namespaceId = LookupExplicitNamespace(schemaname);	}	else	{		/* flag to indicate we need namespace search */		namespaceId = InvalidOid;		recomputeNamespacePath();	}	/* Search syscache by name only */	catlist = SearchSysCacheList(OPERNAMENSP, 1,								 CStringGetDatum(opername),								 0, 0, 0);	/*	 * In typical scenarios, most if not all of the operators found by the	 * catcache search will end up getting returned; and there can be quite a	 * few, for common operator names such as '=' or '+'.  To reduce the time	 * spent in palloc, we allocate the result space as an array large enough	 * to hold all the operators.  The original coding of this routine did a	 * separate palloc for each operator, but profiling revealed that the	 * pallocs used an unreasonably large fraction of parsing time.	 */#define SPACE_PER_OP MAXALIGN(sizeof(struct _FuncCandidateList) + sizeof(Oid))	if (catlist->n_members > 0)		resultSpace = palloc(catlist->n_members * SPACE_PER_OP);	for (i = 0; i < catlist->n_members; i++)	{		HeapTuple	opertup = &catlist->members[i]->tuple;		Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);		int			pathpos = 0;		FuncCandidateList newResult;		/* Ignore operators of wrong kind, if specific kind requested */		if (oprkind && operform->oprkind != oprkind)			continue;		if (OidIsValid(namespaceId))		{			/* Consider only opers in specified namespace */			if (operform->oprnamespace != namespaceId)				continue;			/* No need to check args, they must all be different */		}		else		{			/* Consider only opers that are in the search path */			ListCell   *nsp;			foreach(nsp, namespaceSearchPath)			{				if (operform->oprnamespace == lfirst_oid(nsp))					break;				pathpos++;			}			if (nsp == NULL)				continue;		/* oper is not in search path */			/*			 * Okay, it's in the search path, but does it have the same			 * arguments as something we already accepted?	If so, keep only			 * the one that appears earlier in the search path.			 *			 * If we have an ordered list from SearchSysCacheList (the normal			 * case), then any conflicting oper must immediately adjoin this			 * one in the list, so we only need to look at the newest result			 * item.  If we have an unordered list, we have to scan the whole			 * result list.			 */			if (resultList)			{				FuncCandidateList prevResult;				if (catlist->ordered)				{					if (operform->oprleft == resultList->args[0] &&						operform->oprright == resultList->args[1])						prevResult = resultList;					else						prevResult = NULL;				}				else				{					for (prevResult = resultList;						 prevResult;						 prevResult = prevResult->next)					{						if (operform->oprleft == prevResult->args[0] &&							operform->oprright == prevResult->args[1])							break;					}				}				if (prevResult)				{					/* We have a match with a previous result */					Assert(pathpos != prevResult->pathpos);					if (pathpos > prevResult->pathpos)						continue;		/* keep previous result */					/* replace previous result */					prevResult->pathpos = pathpos;					prevResult->oid = HeapTupleGetOid(opertup);					continue;	/* args are same, of course */				}			}		}		/*		 * Okay to add it to result list		 */		newResult = (FuncCandidateList) (resultSpace + nextResult);		nextResult += SPACE_PER_OP;		newResult->pathpos = pathpos;		newResult->oid = HeapTupleGetOid(opertup);		newResult->nargs = 2;		newResult->args[0] = operform->oprleft;		newResult->args[1] = operform->oprright;		newResult->next = resultList;		resultList = newResult;	}	ReleaseSysCacheList(catlist);	return resultList;}/* * OperatorIsVisible *		Determine whether an operator (identified by OID) is visible in the *		current search path.  Visible means "would be found by searching *		for the unqualified operator name with exact argument matches". */boolOperatorIsVisible(Oid oprid){	HeapTuple	oprtup;	Form_pg_operator oprform;	Oid			oprnamespace;	bool		visible;	oprtup = SearchSysCache(OPEROID,							ObjectIdGetDatum(oprid),							0, 0, 0);	if (!HeapTupleIsValid(oprtup))		elog(ERROR, "cache lookup failed for operator %u", oprid);	oprform = (Form_pg_operator) GETSTRUCT(oprtup);	recomputeNamespacePath();	/*	 * Quick check: if it ain't in the path at all, it ain't visible. Items in	 * the system namespace are surely in the path and so we needn't even do	 * list_member_oid() for them.	 */	oprnamespace = oprform->oprnamespace;	if (oprnamespace != PG_CATALOG_NAMESPACE &&		!list_member_oid(namespaceSearchPath, oprnamespace))		visible = false;	else	{		/*		 * If it is in the path, it might still not be visible; it could be		 * hidden by another operator of the same name and arguments earlier		 * in the path.  So we must do a slow check to see if this is the same		 * operator that would be found by OpernameGetCandidates.		 */		char	   *oprname = NameStr(oprform->oprname);		FuncCandidateList clist;		visible = false;		clist = OpernameGetCandidates(list_make1(makeString(oprname)),									  oprform->oprkind);		for (; clist; clist = clist->next)		{			if (clist->args[0] == oprform->oprleft &&				clist->args[1] == oprform->oprright)			{				/* Found the expected entry; is it the right op? */				visible = (clist->oid == oprid);				break;			}		}	}	ReleaseSysCache(oprtup);	return visible;}/* * OpclassnameGetOpcid *		Try to resolve an unqualified index opclass name. *		Returns OID if opclass found in search path, else InvalidOid. * * This is essentially the same as TypenameGetTypid, but we have to have * an extra argument for the index AM OID. */OidOpclassnameGetOpcid(Oid amid, const char *opcname){	Oid			opcid;	ListCell   *l;	recomputeNamespacePath();	foreach(l, namespaceSearchPath)	{		Oid			namespaceId = lfirst_oid(l);		opcid = GetSysCacheOid(CLAAMNAMENSP,							   ObjectIdGetDatum(amid),							   PointerGetDatum(opcname),							   ObjectIdGetDatum(namespaceId),							   0);		if (OidIsValid(opcid))			return opcid;	}	/* Not found in path */	return InvalidOid;}/* * OpclassIsVisible *		Determine whether an opclass (identified by OID) is visible in the *		current search path.  Visible means "would be found by searching *		for the unqualified opclass name". */boolOpclassIsVisible(Oid opcid){	HeapTuple	opctup;	Form_pg_opclass opcform;	Oid			opcnamespace;	bool		visible;	opctup = SearchSysCache(CLAOID,							ObjectIdGetDatum(opcid),							0, 0, 0);	if (!HeapTupleIsValid(opctup))		elog(ERROR, "cache lookup failed for opclass %u", opcid);	opcform = (Form_pg_opclass) GETSTRUCT(opctup);	recomputeNamespacePath();	/*	 * Quick check: if it ain't in the path at all, it ain't visible. Items in	 * the system namespace are surely in the path and so we needn't even do	 * list_member_oid() for them.	 */	opcnamespace = opcform->opcnamespace;	if (opcnamespace != PG_CATALOG_NAMESPACE &&		!list_member_oid(namespaceSearchPath, opcnamespace))		visible = false;	else	{		/*		 * If it is in the path, it might still not be visible; it could be

⌨️ 快捷键说明

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