PostgreSQL Source Code  git master
relfilenumbermap.h File Reference
#include "common/relpath.h"
Include dependency graph for relfilenumbermap.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Oid RelidByRelfilenumber (Oid reltablespace, RelFileNumber relfilenumber)
 

Function Documentation

◆ RelidByRelfilenumber()

Oid RelidByRelfilenumber ( Oid  reltablespace,
RelFileNumber  relfilenumber 
)

Definition at line 136 of file relfilenumbermap.c.

137 {
139  RelfilenumberMapEntry *entry;
140  bool found;
141  SysScanDesc scandesc;
142  Relation relation;
143  HeapTuple ntp;
144  Oid relid;
145 
146  if (RelfilenumberMapHash == NULL)
148 
149  /* pg_class will show 0 when the value is actually MyDatabaseTableSpace */
150  if (reltablespace == MyDatabaseTableSpace)
151  reltablespace = 0;
152 
153  MemSet(&key, 0, sizeof(key));
154  key.reltablespace = reltablespace;
155  key.relfilenumber = relfilenumber;
156 
157  /*
158  * Check cache and return entry if one is found. Even if no target
159  * relation can be found later on we store the negative match and return a
160  * InvalidOid from cache. That's not really necessary for performance
161  * since querying invalid values isn't supposed to be a frequent thing,
162  * but it's basically free.
163  */
164  entry = hash_search(RelfilenumberMapHash, &key, HASH_FIND, &found);
165 
166  if (found)
167  return entry->relid;
168 
169  /* ok, no previous cache entry, do it the hard way */
170 
171  /* initialize empty/negative cache entry before doing the actual lookups */
172  relid = InvalidOid;
173 
174  if (reltablespace == GLOBALTABLESPACE_OID)
175  {
176  /*
177  * Ok, shared table, check relmapper.
178  */
179  relid = RelationMapFilenumberToOid(relfilenumber, true);
180  }
181  else
182  {
183  ScanKeyData skey[2];
184 
185  /*
186  * Not a shared table, could either be a plain relation or a
187  * non-shared, nailed one, like e.g. pg_class.
188  */
189 
190  /* check for plain relations by looking in pg_class */
191  relation = table_open(RelationRelationId, AccessShareLock);
192 
193  /* copy scankey to local copy and set scan arguments */
194  memcpy(skey, relfilenumber_skey, sizeof(skey));
195  skey[0].sk_argument = ObjectIdGetDatum(reltablespace);
196  skey[1].sk_argument = ObjectIdGetDatum(relfilenumber);
197 
198  scandesc = systable_beginscan(relation,
199  ClassTblspcRelfilenodeIndexId,
200  true,
201  NULL,
202  2,
203  skey);
204 
205  found = false;
206 
207  while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
208  {
209  Form_pg_class classform = (Form_pg_class) GETSTRUCT(ntp);
210 
211  if (found)
212  elog(ERROR,
213  "unexpected duplicate for tablespace %u, relfilenumber %u",
214  reltablespace, relfilenumber);
215  found = true;
216 
217  Assert(classform->reltablespace == reltablespace);
218  Assert(classform->relfilenode == relfilenumber);
219  relid = classform->oid;
220  }
221 
222  systable_endscan(scandesc);
223  table_close(relation, AccessShareLock);
224 
225  /* check for tables that are mapped but not shared */
226  if (!found)
227  relid = RelationMapFilenumberToOid(relfilenumber, false);
228  }
229 
230  /*
231  * Only enter entry into cache now, our opening of pg_class could have
232  * caused cache invalidations to be executed which would have deleted a
233  * new entry if we had entered it above.
234  */
235  entry = hash_search(RelfilenumberMapHash, &key, HASH_ENTER, &found);
236  if (found)
237  elog(ERROR, "corrupted hashtable");
238  entry->relid = relid;
239 
240  return relid;
241 }
#define Assert(condition)
Definition: c.h:837
#define MemSet(start, val, len)
Definition: c.h:999
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:511
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
Oid MyDatabaseTableSpace
Definition: globals.c:95
@ HASH_FIND
Definition: hsearch.h:113
@ HASH_ENTER
Definition: hsearch.h:114
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#define AccessShareLock
Definition: lockdefs.h:36
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
static ScanKeyData relfilenumber_skey[2]
static void InitializeRelfilenumberMap(void)
static HTAB * RelfilenumberMapHash
Oid RelationMapFilenumberToOid(RelFileNumber filenumber, bool shared)
Definition: relmapper.c:218
Datum sk_argument
Definition: skey.h:72
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, Assert, elog, ERROR, GETSTRUCT, HASH_ENTER, HASH_FIND, hash_search(), HeapTupleIsValid, InitializeRelfilenumberMap(), InvalidOid, sort-test::key, MemSet, MyDatabaseTableSpace, ObjectIdGetDatum(), RelationMapFilenumberToOid(), relfilenumber_skey, RelfilenumberMapHash, RelfilenumberMapEntry::relid, ScanKeyData::sk_argument, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by autoprewarm_database_main(), pg_filenode_relation(), and ReorderBufferProcessTXN().