syscache.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 731 行 · 第 1/2 页

C
731
字号
	{RelationRelationName,		/* RELOID */		ClassOidIndex,		ObjectIdAttributeNumber,		1,		{			ObjectIdAttributeNumber,			0,			0,			0	}},	{RewriteRelationName,		/* RULERELNAME */		RewriteRelRulenameIndex,		Anum_pg_rewrite_ev_class,		2,		{			Anum_pg_rewrite_ev_class,			Anum_pg_rewrite_rulename,			0,			0	}},	{ShadowRelationName,		/* SHADOWNAME */		ShadowNameIndex,		0,		1,		{			Anum_pg_shadow_usename,			0,			0,			0	}},	{ShadowRelationName,		/* SHADOWSYSID */		ShadowSysidIndex,		0,		1,		{			Anum_pg_shadow_usesysid,			0,			0,			0	}},	{StatisticRelationName,		/* STATRELATT */		StatisticRelidAttnumIndex,		Anum_pg_statistic_starelid,		2,		{			Anum_pg_statistic_starelid,			Anum_pg_statistic_staattnum,			0,			0	}},	{TypeRelationName,			/* TYPENAMENSP */		TypeNameNspIndex,		Anum_pg_type_typrelid,		2,		{			Anum_pg_type_typname,			Anum_pg_type_typnamespace,			0,			0	}},	{TypeRelationName,			/* TYPEOID */		TypeOidIndex,		Anum_pg_type_typrelid,		1,		{			ObjectIdAttributeNumber,			0,			0,			0	}}};static CatCache *SysCache[lengthof(cacheinfo)];static int	SysCacheSize = lengthof(cacheinfo);static bool CacheInitialized = false;/* * InitCatalogCache - initialize the caches * * Note that no database access is done here; we only allocate memory * and initialize the cache structure.	Interrogation of the database * to complete initialization of a cache happens upon first use * of that cache. */voidInitCatalogCache(void){	int			cacheId;	Assert(!CacheInitialized);	MemSet((char *) SysCache, 0, sizeof(SysCache));	for (cacheId = 0; cacheId < SysCacheSize; cacheId++)	{		SysCache[cacheId] = InitCatCache(cacheId,										 cacheinfo[cacheId].name,										 cacheinfo[cacheId].indname,										 cacheinfo[cacheId].reloidattr,										 cacheinfo[cacheId].nkeys,										 cacheinfo[cacheId].key);		if (!PointerIsValid(SysCache[cacheId]))			elog(ERROR, "could not initialize cache %s (%d)",				 cacheinfo[cacheId].name, cacheId);	}	CacheInitialized = true;}/* * InitCatalogCachePhase2 - finish initializing the caches * * Finish initializing all the caches, including necessary database * access. * * This is *not* essential; normally we allow syscaches to be initialized * on first use.  However, it is useful as a mechanism to preload the * relcache with entries for the most-commonly-used system catalogs. * Therefore, we invoke this routine when we need to write a new relcache * init file. */voidInitCatalogCachePhase2(void){	int			cacheId;	Assert(CacheInitialized);	for (cacheId = 0; cacheId < SysCacheSize; cacheId++)		InitCatCachePhase2(SysCache[cacheId]);}/* * SearchSysCache * *	A layer on top of SearchCatCache that does the initialization and *	key-setting for you. * *	Returns the cache copy of the tuple if one is found, NULL if not. *	The tuple is the 'cache' copy and must NOT be modified! * *	When the caller is done using the tuple, call ReleaseSysCache() *	to release the reference count grabbed by SearchSysCache().  If this *	is not done, the tuple will remain locked in cache until end of *	transaction, which is tolerable but not desirable. * *	CAUTION: The tuple that is returned must NOT be freed by the caller! */HeapTupleSearchSysCache(int cacheId,			   Datum key1,			   Datum key2,			   Datum key3,			   Datum key4){	if (cacheId < 0 || cacheId >= SysCacheSize ||		!PointerIsValid(SysCache[cacheId]))		elog(ERROR, "invalid cache id: %d", cacheId);	return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);}/* * ReleaseSysCache *		Release previously grabbed reference count on a tuple */voidReleaseSysCache(HeapTuple tuple){	ReleaseCatCache(tuple);}/* * SearchSysCacheCopy * * A convenience routine that does SearchSysCache and (if successful) * returns a modifiable copy of the syscache entry.  The original * syscache entry is released before returning.  The caller should * heap_freetuple() the result when done with it. */HeapTupleSearchSysCacheCopy(int cacheId,				   Datum key1,				   Datum key2,				   Datum key3,				   Datum key4){	HeapTuple	tuple,				newtuple;	tuple = SearchSysCache(cacheId, key1, key2, key3, key4);	if (!HeapTupleIsValid(tuple))		return tuple;	newtuple = heap_copytuple(tuple);	ReleaseSysCache(tuple);	return newtuple;}/* * SearchSysCacheExists * * A convenience routine that just probes to see if a tuple can be found. * No lock is retained on the syscache entry. */boolSearchSysCacheExists(int cacheId,					 Datum key1,					 Datum key2,					 Datum key3,					 Datum key4){	HeapTuple	tuple;	tuple = SearchSysCache(cacheId, key1, key2, key3, key4);	if (!HeapTupleIsValid(tuple))		return false;	ReleaseSysCache(tuple);	return true;}/* * GetSysCacheOid * * A convenience routine that does SearchSysCache and returns the OID * of the found tuple, or InvalidOid if no tuple could be found. * No lock is retained on the syscache entry. */OidGetSysCacheOid(int cacheId,			   Datum key1,			   Datum key2,			   Datum key3,			   Datum key4){	HeapTuple	tuple;	Oid			result;	tuple = SearchSysCache(cacheId, key1, key2, key3, key4);	if (!HeapTupleIsValid(tuple))		return InvalidOid;	result = HeapTupleGetOid(tuple);	ReleaseSysCache(tuple);	return result;}/* * SearchSysCacheAttName * * This routine is equivalent to SearchSysCache on the ATTNAME cache, * except that it will return NULL if the found attribute is marked * attisdropped.  This is convenient for callers that want to act as * though dropped attributes don't exist. */HeapTupleSearchSysCacheAttName(Oid relid, const char *attname){	HeapTuple	tuple;	tuple = SearchSysCache(ATTNAME,						   ObjectIdGetDatum(relid),						   CStringGetDatum(attname),						   0, 0);	if (!HeapTupleIsValid(tuple))		return NULL;	if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)	{		ReleaseSysCache(tuple);		return NULL;	}	return tuple;}/* * SearchSysCacheCopyAttName * * As above, an attisdropped-aware version of SearchSysCacheCopy. */HeapTupleSearchSysCacheCopyAttName(Oid relid, const char *attname){	HeapTuple	tuple,				newtuple;	tuple = SearchSysCacheAttName(relid, attname);	if (!HeapTupleIsValid(tuple))		return tuple;	newtuple = heap_copytuple(tuple);	ReleaseSysCache(tuple);	return newtuple;}/* * SearchSysCacheExistsAttName * * As above, an attisdropped-aware version of SearchSysCacheExists. */boolSearchSysCacheExistsAttName(Oid relid, const char *attname){	HeapTuple	tuple;	tuple = SearchSysCacheAttName(relid, attname);	if (!HeapTupleIsValid(tuple))		return false;	ReleaseSysCache(tuple);	return true;}/* * SysCacheGetAttr * *		Given a tuple previously fetched by SearchSysCache(), *		extract a specific attribute. * * This is equivalent to using heap_getattr() on a tuple fetched * from a non-cached relation.	Usually, this is only used for attributes * that could be NULL or variable length; the fixed-size attributes in * a system table are accessed just by mapping the tuple onto the C struct * declarations from include/catalog/. * * As with heap_getattr(), if the attribute is of a pass-by-reference type * then a pointer into the tuple data area is returned --- the caller must * not modify or pfree the datum! */DatumSysCacheGetAttr(int cacheId, HeapTuple tup,				AttrNumber attributeNumber,				bool *isNull){	/*	 * We just need to get the TupleDesc out of the cache entry, and then	 * we can apply heap_getattr().  We expect that the cache control data	 * is currently valid --- if the caller recently fetched the tuple,	 * then it should be.	 */	if (cacheId < 0 || cacheId >= SysCacheSize)		elog(ERROR, "invalid cache id: %d", cacheId);	if (!PointerIsValid(SysCache[cacheId]) ||		!PointerIsValid(SysCache[cacheId]->cc_tupdesc))		elog(ERROR, "missing cache data for cache id %d", cacheId);	return heap_getattr(tup, attributeNumber,						SysCache[cacheId]->cc_tupdesc,						isNull);}/* * List-search interface */struct catclist *SearchSysCacheList(int cacheId, int nkeys,				   Datum key1, Datum key2, Datum key3, Datum key4){	if (cacheId < 0 || cacheId >= SysCacheSize ||		!PointerIsValid(SysCache[cacheId]))		elog(ERROR, "invalid cache id: %d", cacheId);	return SearchCatCacheList(SysCache[cacheId], nkeys,							  key1, key2, key3, key4);}

⌨️ 快捷键说明

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