PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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

Oid RelidByRelfilenode ( Oid  reltablespace,
Oid  relfilenode 
)

Definition at line 141 of file relfilenodemap.c.

References AccessShareLock, Anum_pg_class_relfilenode, Anum_pg_class_reltablespace, Assert, ClassTblspcRelfilenodeIndexId, elog, ERROR, fastgetattr, GLOBALTABLESPACE_OID, HASH_ENTER, HASH_FIND, hash_search(), heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, InitializeRelfilenodeMap(), InvalidOid, MemSet, MyDatabaseTableSpace, NULL, ObjectIdGetDatum, RelationGetDescr, RelationMapFilenodeToOid(), RelationRelationId, RelfilenodeMapKey::relfilenode, RelfilenodeMapEntry::relid, RelfilenodeMapKey::reltablespace, ScanKeyData::sk_argument, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by pg_filenode_relation(), and ReorderBufferCommit().

142 {
143  RelfilenodeMapKey key;
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 */
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  if (found)
216  elog(ERROR,
217  "unexpected duplicate for tablespace %u, relfilenode %u",
218  reltablespace, relfilenode);
219  found = true;
220 
221 #ifdef USE_ASSERT_CHECKING
222  {
223  bool isnull;
224  Oid check;
225 
227  RelationGetDescr(relation),
228  &isnull);
229  Assert(!isnull && check == reltablespace);
230 
232  RelationGetDescr(relation),
233  &isnull);
234  Assert(!isnull && check == relfilenode);
235  }
236 #endif
237  relid = HeapTupleGetOid(ntp);
238  }
239 
240  systable_endscan(scandesc);
241  heap_close(relation, AccessShareLock);
242 
243  /* check for tables that are mapped but not shared */
244  if (!found)
245  relid = RelationMapFilenodeToOid(relfilenode, false);
246  }
247 
248  /*
249  * Only enter entry into cache now, our opening of pg_class could have
250  * caused cache invalidations to be executed which would have deleted a
251  * new entry if we had entered it above.
252  */
253  entry = hash_search(RelfilenodeMapHash, (void *) &key, HASH_ENTER, &found);
254  if (found)
255  elog(ERROR, "corrupted hashtable");
256  entry->relid = relid;
257 
258  return relid;
259 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define fastgetattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:719
#define RelationGetDescr(relation)
Definition: rel.h:425
#define RelationRelationId
Definition: pg_class.h:29
#define Anum_pg_class_reltablespace
Definition: pg_class.h:110
#define AccessShareLock
Definition: lockdefs.h:36
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
#define MemSet(start, val, len)
Definition: c.h:857
#define heap_close(r, l)
Definition: heapam.h:97
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
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:328
#define Anum_pg_class_relfilenode
Definition: pg_class.h:109
Oid MyDatabaseTableSpace
Definition: globals.c:78
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
static HTAB * RelfilenodeMapHash
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
static ScanKeyData relfilenode_skey[2]
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
Oid RelationMapFilenodeToOid(Oid filenode, bool shared)
Definition: relmapper.c:199
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
static void InitializeRelfilenodeMap(void)
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
Datum sk_argument
Definition: skey.h:72
#define ClassTblspcRelfilenodeIndexId
Definition: indexing.h:116