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