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

📄 namespace.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 4 页
字号:
			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 */			List	   *nsp;			foreach(nsp, namespaceSearchPath)			{				if (procform->pronamespace == lfirsto(nsp))					break;				pathpos++;			}			if (nsp == NIL)				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 (nargs == resultList->nargs &&						memcmp(procform->proargtypes, resultList->args,							   nargs * sizeof(Oid)) == 0)						prevResult = resultList;					else						prevResult = NULL;				}				else				{					for (prevResult = resultList;						 prevResult;						 prevResult = prevResult->next)					{						if (nargs == prevResult->nargs &&						  memcmp(procform->proargtypes, prevResult->args,								 nargs * 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)				   + nargs * sizeof(Oid));		newResult->pathpos = pathpos;		newResult->oid = HeapTupleGetOid(proctup);		newResult->nargs = nargs;		memcpy(newResult->args, procform->proargtypes, nargs * 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 oidMember() for them.	 */	pronamespace = procform->pronamespace;	if (pronamespace != PG_CATALOG_NAMESPACE &&		!oidMember(pronamespace, namespaceSearchPath))		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(makeList1(makeString(proname)), nargs);		for (; clist; clist = clist->next)		{			if (memcmp(clist->args, procform->proargtypes,					   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	   *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);	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 */			List	   *nsp;			foreach(nsp, namespaceSearchPath)			{				if (operform->oprnamespace == lfirsto(nsp))					break;				pathpos++;			}			if (nsp == NIL)				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)			palloc(sizeof(struct _FuncCandidateList) + sizeof(Oid));		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 oidMember() for them.	 */	oprnamespace = oprform->oprnamespace;	if (oprnamespace != PG_CATALOG_NAMESPACE &&		!oidMember(oprnamespace, namespaceSearchPath))		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(makeList1(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;}/* * OpclassGetCandidates *		Given an index access method OID, retrieve a list of all the *		opclasses for that AM that are visible in the search path. * * NOTE: the opcname_tmp field in the returned structs should not be used * by callers, because it points at syscache entries that we release at * the end of this routine.  If any callers needed the name information, * we could pstrdup() the names ... but at present it'd be wasteful. */OpclassCandidateListOpclassGetCandidates(Oid amid){	OpclassCandidateList resultList = NULL;	CatCList   *catlist;	int			i;	/* Search syscache by AM OID only */	catlist = SearchSysCacheList(CLAAMNAMENSP, 1,								 ObjectIdGetDatum(amid),								 0, 0, 0);	recomputeNamespacePath();	for (i = 0; i < catlist->n_members; i++)	{		HeapTuple	opctup = &catlist->members[i]->tuple;		Form_pg_opclass opcform = (Form_pg_opclass) GETSTRUCT(opctup);		int			pathpos = 0;		OpclassCandidateList newResult;		List	   *nsp;		/* Consider only opclasses that are in the search path */		foreach(nsp, namespaceSearchPath)		{			if (opcform->opcnamespace == lfirsto(nsp))				break;			pathpos++;		}		if (nsp == NIL)			continue;			/* opclass is not in search path */		/*		 * Okay, it's in the search path, but does it have the same name		 * 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 opclass 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)		{			OpclassCandidateList prevResult;			if (catlist->ordered)			{				if (strcmp(NameStr(opcform->opcname),						   resultList->opcname_tmp) == 0)					prevResult = resultList;				else					prevResult = NULL;			}			else			{				for (prevResult = resultList;					 prevResult;					 prevResult = prevResult->next)				{					if (strcmp(NameStr(opcform->opcname),							   prevResult->opcname_tmp) == 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->opcname_tmp = NameStr(opcform->opcname);				prevResult->pathpos = pathpos;				prevResult->oid = HeapTupleGetOid(opctup);				prevResult->opcintype = opcform->opcintype;				prevResult->opcdefault = opcform->opcdefault;				prevResult->opckeytype = opcform->opckeytype;				continue;			}		}		/*		 * Okay to add it to result list		 */		newResult = (OpclassCandidateList)			palloc(sizeof(struct _OpclassCandidateList));		newResult->opcname_tmp = NameStr(opcform->opcname);		newResult->pathpos = pathpos;		newResult->oid = HeapTupleGetOid(opctup);		newResult->opcintype = opcform->opcintype;		newResult->opcdefault = opcform->opcdefault;		newResult->opckeytype = opcform->opckeytype;		newResult->next = resultList;		resultList = newResult;	}	ReleaseSysCacheList(catlist);	return resultList;}/* * 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

⌨️ 快捷键说明

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