PostgreSQL Source Code  git master
relfilenodemap.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Oid RelidByRelfilenode (Oid reltablespace, Oid relfilenode)
 

Function Documentation

◆ RelidByRelfilenode()

Oid RelidByRelfilenode ( Oid  reltablespace,
Oid  relfilenode 
)

Definition at line 141 of file relfilenodemap.c.

References AccessShareLock, Assert, ClassTblspcRelfilenodeIndexId, elog, ERROR, GETSTRUCT, HASH_ENTER, HASH_FIND, hash_search(), HeapTupleIsValid, InitializeRelfilenodeMap(), InvalidOid, sort-test::key, MemSet, MyDatabaseTableSpace, ObjectIdGetDatum, RelationMapFilenodeToOid(), RelfilenodeMapKey::relfilenode, RelfilenodeMapEntry::relid, RelfilenodeMapKey::reltablespace, ScanKeyData::sk_argument, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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

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