From: Vadim B. Mikheev Date: Mon, 23 Oct 2000 04:10:24 +0000 (+0000) Subject: New relcache hash table with RelFileNode as key to be used X-Git-Tag: REL7_1_BETA~387 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4b65a2840b124b881ce4f260f9cc35927863b2ae;p=postgresql New relcache hash table with RelFileNode as key to be used from bufmgr - it would be nice to have separate hash in smgr for node <--> fd mappings, but for the moment it's easy to add new hash to relcache. Fixed small bug in xlog.c:ReadRecord. --- diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 315d813e92..5533fa0509 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.74 2000/10/21 15:43:22 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.75 2000/10/23 04:10:05 vadim Exp $ * * NOTES * Transaction aborts can now occur two ways: @@ -676,6 +676,7 @@ RecordTransactionCommit() */ leak = BufferPoolCheckLeak(); +#ifndef XLOG /* * If no one shared buffer was changed by this transaction then we * don't flush shared buffers and don't record commit status. @@ -686,6 +687,7 @@ RecordTransactionCommit() if (leak) ResetBufferPool(true); +#endif /* * have the transaction access methods record the status of this * transaction id in the pg_log relation. @@ -717,13 +719,14 @@ RecordTransactionCommit() MyLastRecPtr.xlogid = 0; MyLastRecPtr.xrecoff = 0; } -#endif +#else /* * Now write the log info to the disk too. */ leak = BufferPoolCheckLeak(); FlushBufferPool(); } +#endif if (leak) ResetBufferPool(true); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index bae7af83c3..19d7f38c1e 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.19 2000/10/21 15:43:22 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.20 2000/10/23 04:10:05 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -991,6 +991,7 @@ got_record:; nextRecord = (XLogRecord *) ((char *) subrecord + MAXALIGN(subrecord->xl_len) + SizeOfXLogSubRecord); } + record->xl_len = len; EndRecPtr.xlogid = readId; EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ + SizeOfXLogPHD + SizeOfXLogSubRecord + @@ -1412,7 +1413,9 @@ StartupXLOG() { char buf[8192]; - sprintf(buf, "REDO @ %u/%u: ", ReadRecPtr.xlogid, ReadRecPtr.xrecoff); + sprintf(buf, "REDO @ %u/%u; LSN %u/%u: ", + ReadRecPtr.xlogid, ReadRecPtr.xrecoff, + EndRecPtr.xlogid, EndRecPtr.xrecoff); xlog_outrec(buf, record); strcat(buf, " - "); RmgrTable[record->xl_rmid].rm_desc(buf, diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c index 13aca31a3e..3c40009422 100644 --- a/src/backend/storage/buffer/buf_init.c +++ b/src/backend/storage/buffer/buf_init.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.36 2000/10/18 05:50:15 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.37 2000/10/23 04:10:06 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -68,7 +68,6 @@ bits8 *BufferLocks; /* flag bits showing locks I have set */ BufferTag *BufferTagLastDirtied; /* tag buffer had when last * dirtied by me */ BufferBlindId *BufferBlindLastDirtied; -LockRelId *BufferRelidLastDirtied; bool *BufferDirtiedByMe; /* T if buf has been dirtied in cur xact */ @@ -252,7 +251,6 @@ InitBufferPool(IPCKey key) BufferLocks = (bits8 *) calloc(NBuffers, sizeof(bits8)); BufferTagLastDirtied = (BufferTag *) calloc(NBuffers, sizeof(BufferTag)); BufferBlindLastDirtied = (BufferBlindId *) calloc(NBuffers, sizeof(BufferBlindId)); - BufferRelidLastDirtied = (LockRelId *) calloc(NBuffers, sizeof(LockRelId)); BufferDirtiedByMe = (bool *) calloc(NBuffers, sizeof(bool)); } diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 9161c48529..c0a320986c 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.90 2000/10/22 20:20:49 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.91 2000/10/23 04:10:06 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -54,6 +54,10 @@ #include "storage/smgr.h" #include "utils/relcache.h" +#ifdef XLOG +#include "catalog/pg_database.h" +#endif + extern SPINLOCK BufMgrLock; extern long int ReadBufferCount; extern long int ReadLocalBufferCount; @@ -611,7 +615,6 @@ BufferAlloc(Relation reln, /* record the database name and relation name for this buffer */ strcpy(buf->blind.dbname, (DatabaseName) ? DatabaseName : "Recovery"); strcpy(buf->blind.relname, RelationGetPhysicalRelationName(reln)); - buf->relId = reln->rd_lockInfo.lockRelId; INIT_BUFFERTAG(&(buf->tag), reln, blockNum); if (!BufTableInsert(buf)) @@ -711,7 +714,6 @@ int FlushBuffer(Buffer buffer, bool release) { BufferDesc *bufHdr; - Oid bufdb; Relation bufrel; int status; @@ -725,10 +727,7 @@ FlushBuffer(Buffer buffer, bool release) bufHdr = &BufferDescriptors[buffer - 1]; - bufdb = bufHdr->relId.dbId; - - Assert(bufdb == MyDatabaseId || bufdb == (Oid) NULL); - bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId); + bufrel = RelationNodeCacheGetRelation(bufHdr->tag.rnode); Assert(bufrel != (Relation) NULL); @@ -904,7 +903,7 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr) SpinRelease(BufMgrLock); #endif /* OPTIMIZE_SINGLE */ - reln = RelationIdCacheGetRelation(BufferRelidLastDirtied[buffer - 1].relId); + reln = RelationNodeCacheGetRelation(tagLastDirtied->rnode); if (reln == (Relation) NULL) { @@ -938,7 +937,6 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr) } *tagLastDirtied = bufHdr->tag; - BufferRelidLastDirtied[buffer - 1] = bufHdr->relId; BufferBlindLastDirtied[buffer - 1] = bufHdr->blind; BufferDirtiedByMe[buffer - 1] = true; } @@ -1010,15 +1008,14 @@ BufferSync() if (RelFileNodeEquals(bufHdr->tag.rnode, BufferTagLastDirtied[i].rnode) && bufHdr->tag.blockNum == BufferTagLastDirtied[i].blockNum) { - Oid bufrel = bufHdr->relId.relId; - /* * Try to find relation for buf. This could fail, if the * rel has been flushed from the relcache since we dirtied * the page. That should be uncommon, so paying the extra * cost of a blind write when it happens seems OK. */ - reln = RelationIdCacheGetRelation(bufrel); + if (!InRecovery) + reln = RelationNodeCacheGetRelation(bufHdr->tag.rnode); /* * We have to pin buffer to keep anyone from stealing it @@ -1083,8 +1080,6 @@ BufferSync() } else { - Assert(RelFileNodeEquals(reln->rd_node, - BufferTagLastDirtied[i].rnode)); status = smgrwrite(DEFAULT_SMGR, reln, bufHdr->tag.blockNum, (char *) MAKE_PTR(bufHdr->data)); @@ -1138,7 +1133,7 @@ BufferSync() SpinRelease(BufMgrLock); #endif /* OPTIMIZE_SINGLE */ - reln = RelationIdCacheGetRelation(BufferRelidLastDirtied[i].relId); + reln = RelationNodeCacheGetRelation(BufferTagLastDirtied[i].rnode); if (reln == (Relation) NULL) { status = smgrblindmarkdirty(DEFAULT_SMGR, @@ -1147,8 +1142,6 @@ BufferSync() } else { - Assert(RelFileNodeEquals(reln->rd_node, - BufferTagLastDirtied[i].rnode)); status = smgrmarkdirty(DEFAULT_SMGR, reln, BufferTagLastDirtied[i].blockNum); @@ -1420,21 +1413,14 @@ static int BufferReplace(BufferDesc *bufHdr) { Relation reln; - Oid bufdb, - bufrel; int status; /* * first try to find the reldesc in the cache, if no luck, don't * bother to build the reldesc from scratch, just do a blind write. */ - bufdb = bufHdr->relId.dbId; - bufrel = bufHdr->relId.relId; - if (bufdb == MyDatabaseId || bufdb == (Oid) NULL) - reln = RelationIdCacheGetRelation(bufrel); - else - reln = (Relation) NULL; + reln = RelationNodeCacheGetRelation(bufHdr->tag.rnode); /* To check if block content changed while flushing. - vadim 01/17/97 */ bufHdr->flags &= ~BM_JUST_DIRTIED; @@ -1450,7 +1436,6 @@ BufferReplace(BufferDesc *bufHdr) if (reln != (Relation) NULL) { - Assert(RelFileNodeEquals(bufHdr->tag.rnode, reln->rd_node)); status = smgrwrite(DEFAULT_SMGR, reln, bufHdr->tag.blockNum, (char *) MAKE_PTR(bufHdr->data)); } @@ -1519,7 +1504,6 @@ RelationGetNumberOfBlocks(Relation relation) void ReleaseRelationBuffers(Relation rel) { - Oid relid = RelationGetRelid(rel); int i; BufferDesc *bufHdr; @@ -1534,10 +1518,6 @@ ReleaseRelationBuffers(Relation rel) LocalRefCount[i] = 0; bufHdr->tag.rnode.relNode = InvalidOid; } - else - { - Assert(bufHdr->relId.relId != relid); - } } return; } @@ -1590,12 +1570,6 @@ recheck: */ BufTableDelete(bufHdr); } - else - { - Assert(bufHdr->relId.relId != relid || - (bufHdr->relId.dbId != MyDatabaseId && - bufHdr->relId.dbId != InvalidOid)); - } /* * Also check to see if BufferDirtiedByMe info for this buffer @@ -1608,7 +1582,7 @@ recheck: * this rel, since we hold exclusive lock on this rel. */ if (RelFileNodeEquals(rel->rd_node, - BufferTagLastDirtied[i - 1].rnode)) + BufferTagLastDirtied[i - 1].rnode)) BufferDirtiedByMe[i - 1] = false; } @@ -1673,11 +1647,6 @@ recheck: */ BufTableDelete(bufHdr); } - else - { - Assert(bufHdr->relId.dbId != dbid); - } - /* * Also check to see if BufferDirtiedByMe info for this buffer * refers to the target database, and clear it if so. This is @@ -1824,7 +1793,6 @@ BufferPoolBlowaway() int FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock) { - Oid relid = RelationGetRelid(rel); int i; BufferDesc *bufHdr; @@ -1857,10 +1825,6 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock) bufHdr->tag.rnode.relNode = InvalidOid; } } - else - { - Assert(bufHdr->relId.relId != relid); - } } return 0; } @@ -1906,12 +1870,6 @@ recheck: BufTableDelete(bufHdr); } } - else - { - Assert(bufHdr->relId.relId != relid || - (bufHdr->relId.dbId != MyDatabaseId && - bufHdr->relId.dbId != InvalidOid)); - } } SpinRelease(BufMgrLock); return 0; diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index 3cb8f572b8..1d6a416e48 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -16,7 +16,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.31 2000/10/18 05:50:15 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.32 2000/10/23 04:10:06 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -103,7 +103,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) */ if (bufHdr->flags & BM_DIRTY) { - Relation bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId); + Relation bufrel = RelationNodeCacheGetRelation(bufHdr->tag.rnode); Assert(bufrel != NULL); @@ -127,7 +127,6 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) */ bufHdr->tag.rnode = reln->rd_node; bufHdr->tag.blockNum = blockNum; - bufHdr->relId = reln->rd_lockInfo.lockRelId; bufHdr->flags &= ~BM_DIRTY; /* @@ -192,7 +191,7 @@ FlushLocalBuffer(Buffer buffer, bool release) bufid = -(buffer + 1); bufHdr = &LocalBufferDescriptors[bufid]; bufHdr->flags &= ~BM_DIRTY; - bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId); + bufrel = RelationNodeCacheGetRelation(bufHdr->tag.rnode); Assert(bufrel != NULL); smgrflush(DEFAULT_SMGR, bufrel, bufHdr->tag.blockNum, @@ -268,7 +267,7 @@ LocalBufferSync(void) #ifdef LBDEBUG fprintf(stderr, "LB SYNC %d\n", -i - 1); #endif - bufrel = RelationIdCacheGetRelation(buf->relId.relId); + bufrel = RelationNodeCacheGetRelation(buf->tag.rnode); Assert(bufrel != NULL); @@ -279,7 +278,6 @@ LocalBufferSync(void) /* drop relcache refcount from RelationIdCacheGetRelation */ RelationDecrementReferenceCount(bufrel); - buf->relId.relId = InvalidOid; buf->flags &= ~BM_DIRTY; } } diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 755359e251..de3e3c4a8d 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.112 2000/10/16 14:52:13 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.113 2000/10/23 04:10:08 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -83,6 +83,13 @@ static FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log}; static HTAB *RelationNameCache; static HTAB *RelationIdCache; +/* + * Bufmgr uses RelFileNode for lookup. Actually, I would like to do + * not pass Relation to bufmgr & beyond at all and keep some cache + * in smgr, but no time to do it right way now. -- vadim 10/22/2000 + */ +static HTAB *RelationNodeCache; + /* * newlyCreatedRelns - * relations created during this transaction. We need to keep track of @@ -114,17 +121,23 @@ typedef struct RelationBuildDescInfo } i; } RelationBuildDescInfo; +typedef struct relnamecacheent +{ + NameData relname; + Relation reldesc; +} RelNameCacheEnt; + typedef struct relidcacheent { Oid reloid; Relation reldesc; } RelIdCacheEnt; -typedef struct relnamecacheent +typedef struct relnodecacheent { - NameData relname; + RelFileNode relnode; Relation reldesc; -} RelNameCacheEnt; +} RelNodeCacheEnt; /* ----------------- * macros to manipulate name cache and id cache @@ -133,7 +146,7 @@ typedef struct relnamecacheent #define RelationCacheInsert(RELATION) \ do { \ RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \ - char *relname; Oid reloid; bool found; \ + char *relname; RelNodeCacheEnt *nodentry; bool found; \ relname = RelationGetPhysicalRelationName(RELATION); \ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ relname, \ @@ -144,9 +157,8 @@ do { \ if (found && !IsBootstrapProcessingMode()) \ /* used to give notice -- now just keep quiet */ ; \ namehentry->reldesc = RELATION; \ - reloid = RELATION->rd_id; \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ - (char *)&reloid, \ + (char *)&(RELATION->rd_id), \ HASH_ENTER, \ &found); \ if (idhentry == NULL) \ @@ -154,6 +166,15 @@ do { \ if (found && !IsBootstrapProcessingMode()) \ /* used to give notice -- now just keep quiet */ ; \ idhentry->reldesc = RELATION; \ + nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ + (char *)&(RELATION->rd_node), \ + HASH_ENTER, \ + &found); \ + if (nodentry == NULL) \ + elog(FATAL, "can't insert into relation descriptor cache"); \ + if (found && !IsBootstrapProcessingMode()) \ + /* used to give notice -- now just keep quiet */ ; \ + nodentry->reldesc = RELATION; \ } while(0) #define RelationNameCacheLookup(NAME, RELATION) \ @@ -183,10 +204,24 @@ do { \ RELATION = NULL; \ } while(0) +#define RelationNodeCacheLookup(NODE, RELATION) \ +do { \ + RelNodeCacheEnt *hentry; \ + bool found; \ + hentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ + (char *)&(NODE),HASH_FIND, &found); \ + if (hentry == NULL) \ + elog(FATAL, "error in CACHE"); \ + if (found) \ + RELATION = hentry->reldesc; \ + else \ + RELATION = NULL; \ +} while(0) + #define RelationCacheDelete(RELATION) \ do { \ RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \ - char *relname; Oid reloid; bool found; \ + char *relname; RelNodeCacheEnt *nodentry; bool found; \ relname = RelationGetPhysicalRelationName(RELATION); \ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ relname, \ @@ -196,14 +231,20 @@ do { \ elog(FATAL, "can't delete from relation descriptor cache"); \ if (!found) \ elog(NOTICE, "trying to delete a reldesc that does not exist."); \ - reloid = RELATION->rd_id; \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ - (char *)&reloid, \ + (char *)&(RELATION->rd_id), \ HASH_REMOVE, &found); \ if (idhentry == NULL) \ elog(FATAL, "can't delete from relation descriptor cache"); \ if (!found) \ elog(NOTICE, "trying to delete a reldesc that does not exist."); \ + nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ + (char *)&(RELATION->rd_node), \ + HASH_REMOVE, &found); \ + if (nodentry == NULL) \ + elog(FATAL, "can't delete from relation descriptor cache"); \ + if (!found) \ + elog(NOTICE, "trying to delete a reldesc that does not exist."); \ } while(0) /* non-export function prototypes */ @@ -1192,12 +1233,6 @@ formrdesc(char *relationName, */ RelationInitLockInfo(relation); /* see lmgr.c */ - /* ---------------- - * add new reldesc to relcache - * ---------------- - */ - RelationCacheInsert(relation); - if (IsSharedSystemRelationName(relationName)) relation->rd_node.tblNode = InvalidOid; else @@ -1205,6 +1240,12 @@ formrdesc(char *relationName, relation->rd_node.relNode = relation->rd_rel->relfilenode = RelationGetRelid(relation); + /* ---------------- + * add new reldesc to relcache + * ---------------- + */ + RelationCacheInsert(relation); + /* * Determining this requires a scan on pg_class, but to do the scan * the rdesc for pg_class must already exist. Therefore we must do @@ -1343,6 +1384,28 @@ RelationNameCacheGetRelation(const char *relationName) return rd; } +Relation +RelationNodeCacheGetRelation(RelFileNode rnode) +{ + Relation rd; + + RelationNodeCacheLookup(rnode, rd); + + if (RelationIsValid(rd)) + { + if (rd->rd_fd == -1 && rd->rd_rel->relkind != RELKIND_VIEW) + { + rd->rd_fd = smgropen(DEFAULT_SMGR, rd); + Assert(rd->rd_fd != -1 || rd->rd_unlinked); + } + + RelationIncrementReferenceCount(rd); + + } + + return rd; +} + /* -------------------------------- * RelationIdGetRelation * @@ -1942,6 +2005,11 @@ RelationCacheInitialize(void) RelationIdCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM | HASH_FUNCTION); + ctl.keysize = sizeof(RelFileNode); + ctl.hash = tag_hash; + RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl, + HASH_ELEM | HASH_FUNCTION); + /* ---------------- * initialize the cache with pre-made relation descriptors * for some of the more important system relations. These diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index 86512e50bf..65abe9b8ce 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: buf_internals.h,v 1.40 2000/10/20 11:01:21 vadim Exp $ + * $Id: buf_internals.h,v 1.41 2000/10/23 04:10:14 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -109,22 +109,6 @@ typedef struct sbufdesc bool ri_lock; /* read-intent lock */ bool w_lock; /* context exclusively locked */ - /* - * This is logical information about relation. - * IT MUST CORRESPOND TO BUFFER TAG! - * If you're going to play with relation file node (ie change relation - * file) then you have to exclusively lock relation, create new one - * (with new relID), make data transformation, flush from pool buffers - * of both files (old and new), flush old relation from cache, - * update relfilenode in pg_class, flush new relation version from - * cache, open it - now you can use relation with new file. - * - * Why we keep relId here? To re-use file descriptors. On rollback - * WAL uses dummy relId - bad (more blind writes - open/close calls), - * but allowable. Obviously we should have another cache in file manager - * - fd is not relcache deal. - */ - LockRelId relId; BufferBlindId blind; /* was used to support blind write */ /* diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index a2a2b5eb77..fc15ed5b19 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: relcache.h,v 1.21 2000/08/06 04:39:55 tgl Exp $ + * $Id: relcache.h,v 1.22 2000/10/23 04:10:24 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ */ extern Relation RelationIdGetRelation(Oid relationId); extern Relation RelationNameGetRelation(const char *relationName); +extern Relation RelationNodeCacheGetRelation(RelFileNode rnode); /* finds an existing cache entry, but won't make a new one */ extern Relation RelationIdCacheGetRelation(Oid relationId);